Add weak hashtable to manage qual types.
Add weak hashtable to manage qual types.
1.1 --- a/src/Handles.h Tue Dec 25 17:02:07 2012 -0800
1.2 +++ b/src/Handles.h Tue Dec 25 18:13:02 2012 -0800
1.3 @@ -73,7 +73,7 @@
1.4 T *operator *() {
1.5 return *thingp_;
1.6 }
1.7 - operator T *() { return *thingp_; }
1.8 + operator T *() const { return *thingp_; }
1.9 operator bool() const {
1.10 return thingp_ && *thingp_;
1.11 }
2.1 --- a/src/Heap.cpp Tue Dec 25 17:02:07 2012 -0800
2.2 +++ b/src/Heap.cpp Tue Dec 25 18:13:02 2012 -0800
2.3 @@ -350,7 +350,7 @@
2.4 Heap::sweep()
2.5 {
2.6 // Before destroying mark bits, sweep weak roots.
2.7 - zone_->symbols()->sweep();
2.8 + zone_->sweepWeakRoots();
2.9
2.10 // Note: we don't bother sweeping the LIFO space.
2.11 SweepOldSpace(&mapSpace_);
3.1 --- a/src/TypeManager.cpp Tue Dec 25 17:02:07 2012 -0800
3.2 +++ b/src/TypeManager.cpp Tue Dec 25 18:13:02 2012 -0800
3.3 @@ -28,7 +28,8 @@
3.4
3.5
3.6 TypeManager::TypeManager(Zone *zone)
3.7 - : zone_(zone)
3.8 + : zone_(zone),
3.9 + qualTable_(ZoneAllocatorPolicy())
3.10 {
3.11 }
3.12
3.13 @@ -65,6 +66,9 @@
3.14 return false;
3.15 }
3.16
3.17 + if (!qualTable_.init(32))
3.18 + return false;
3.19 +
3.20 return true;
3.21 }
3.22
3.23 @@ -97,6 +101,32 @@
3.24 return EnumType::New(zone_, name);
3.25 }
3.26
3.27 +Type *
3.28 +TypeManager::qualify(Handle<Type> type, TypeQualifiers quals)
3.29 +{
3.30 + assert(!type->hasTypeQualifiers());
3.31 +
3.32 + LookupKey key(type, quals);
3.33 +
3.34 + // We can't use findForAdd because a GC could rehash the table.
3.35 + TypeHashTable::Result r = qualTable_.find(key);
3.36 + if (r.found())
3.37 + return *r;
3.38 +
3.39 + Type *quald = Type::NewQualified(zone_, quals, type);
3.40 + if (!quald)
3.41 + return NULL;
3.42 +
3.43 + // :TODO: assert-no-gc
3.44 + TypeHashTable::Insert i = qualTable_.findForAdd(key);
3.45 + assert(!i.found());
3.46 +
3.47 + if (!qualTable_.add(i, quald))
3.48 + return NULL;
3.49 +
3.50 + return quald;
3.51 +}
3.52 +
3.53 void
3.54 TypeManager::accept(VirtualObjectVisitor *visitor)
3.55 {
3.56 @@ -108,3 +138,17 @@
3.57 visitor->visit(referenceTypes_[i].address());
3.58 }
3.59 }
3.60 +
3.61 +void
3.62 +TypeManager::sweep()
3.63 +{
3.64 + for (TypeHashTable::iterator i(&qualTable_); !i.empty(); i.next()) {
3.65 + Type *obj = *i;
3.66 + MarkBit bits = HeapChunk::GetMarkBit(obj);
3.67 + if (HeapChunk::IsWhite(bits))
3.68 + i.erase();
3.69 + else
3.70 + assert(HeapChunk::IsBlack(bits));
3.71 + }
3.72 + qualTable_.checkDensity();
3.73 +}
4.1 --- a/src/TypeManager.h Tue Dec 25 17:02:07 2012 -0800
4.2 +++ b/src/TypeManager.h Tue Dec 25 18:13:02 2012 -0800
4.3 @@ -21,6 +21,8 @@
4.4
4.5 #include "Barriers.h"
4.6 #include "Types.h"
4.7 +#include "HashTable.h"
4.8 +#include "AllocatorPolicies.h"
4.9 #include "VirtualObjectVisitor.h"
4.10
4.11 namespace ke {
4.12 @@ -29,14 +31,35 @@
4.13
4.14 class TypeManager
4.15 {
4.16 - Zone *zone_;
4.17 + struct LookupKey
4.18 + {
4.19 + Handle<Type> type;
4.20 + TypeQualifiers quals;
4.21 +
4.22 + LookupKey(Handle<Type> type, TypeQualifiers quals)
4.23 + : type(type),
4.24 + quals(quals)
4.25 + {
4.26 + }
4.27 + };
4.28
4.29 - // Primitive type cache.
4.30 - Unbarriered<Type> voidType_;
4.31 - Unbarriered<Type> stringType_;
4.32 - Unbarriered<Type> uncheckedType_;
4.33 - Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
4.34 - Unbarriered<ReferenceType> referenceTypes_[PrimitiveTypes_Total];
4.35 + struct Policy
4.36 + {
4.37 + typedef Type * Payload;
4.38 +
4.39 + static uint32 hash(const LookupKey &key) {
4.40 + // We'll need to rehash with moving GC.
4.41 + return HashPointer(key.type);
4.42 + }
4.43 +
4.44 + static bool matches(const LookupKey &key, Type *type) {
4.45 + assert(type->hasTypeQualifiers());
4.46 + return key.type == type->unqualified() &&
4.47 + key.quals == type->quals();
4.48 + }
4.49 + };
4.50 +
4.51 + typedef HashTable<Policy, ZoneAllocatorPolicy> TypeHashTable;
4.52
4.53 public:
4.54 TypeManager(Zone *zone);
4.55 @@ -62,6 +85,21 @@
4.56 EnumType *newEnum(Handle<String> name);
4.57
4.58 void accept(VirtualObjectVisitor *visitor);
4.59 + void sweep();
4.60 +
4.61 + Type *qualify(Handle<Type> type, TypeQualifiers quals);
4.62 +
4.63 + private:
4.64 + Zone *zone_;
4.65 +
4.66 + // Primitive type cache.
4.67 + Unbarriered<Type> voidType_;
4.68 + Unbarriered<Type> stringType_;
4.69 + Unbarriered<Type> uncheckedType_;
4.70 + Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
4.71 + Unbarriered<ReferenceType> referenceTypes_[PrimitiveTypes_Total];
4.72 +
4.73 + TypeHashTable qualTable_;
4.74 };
4.75
4.76 }
5.1 --- a/src/Types.cpp Tue Dec 25 17:02:07 2012 -0800
5.2 +++ b/src/Types.cpp Tue Dec 25 18:13:02 2012 -0800
5.3 @@ -26,10 +26,10 @@
5.4 using namespace ke;
5.5
5.6 void
5.7 -Type::init(Kind kind)
5.8 +Type::init(Kind kind, Type *root)
5.9 {
5.10 this->kind_ = kind;
5.11 - this->root_ = this;
5.12 + this->root_ = root ? root : this;
5.13 }
5.14
5.15 Type *
5.16 @@ -77,6 +77,18 @@
5.17 return type;
5.18 }
5.19
5.20 +Type *
5.21 +Type::NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> root)
5.22 +{
5.23 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
5.24 + if (!type)
5.25 + return NULL;
5.26 +
5.27 + type->init(QUALTYPE, root);
5.28 + type->quals_ = qual;
5.29 + return type;
5.30 +}
5.31 +
5.32 ArrayType *
5.33 ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
5.34 {
5.35 @@ -235,4 +247,3 @@
5.36 return "<unknown>";
5.37 }
5.38 }
5.39 -
6.1 --- a/src/Types.h Tue Dec 25 17:02:07 2012 -0800
6.2 +++ b/src/Types.h Tue Dec 25 18:13:02 2012 -0800
6.3 @@ -140,7 +140,7 @@
6.4 STRUCT
6.5 };
6.6
6.7 - void init(Kind kind);
6.8 + void init(Kind kind, Type *root = NULL);
6.9
6.10 private:
6.11 Kind kind() {
6.12 @@ -152,6 +152,7 @@
6.13 static Type *NewUnchecked(Zone *zone);
6.14 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
6.15 static Type *NewString(Zone *zone);
6.16 + static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
6.17
6.18 static Type *cast(Object *obj) {
6.19 assert(!obj ||
7.1 --- a/src/Zone.cpp Tue Dec 25 17:02:07 2012 -0800
7.2 +++ b/src/Zone.cpp Tue Dec 25 18:13:02 2012 -0800
7.3 @@ -180,6 +180,13 @@
7.4 stack_.accept(visitor);
7.5 }
7.6
7.7 +void
7.8 +Zone::sweepWeakRoots()
7.9 +{
7.10 + symbols_->sweep();
7.11 + types()->sweep();
7.12 +}
7.13 +
7.14 String *
7.15 Zone::makeSymbol(const char *str, size_t length)
7.16 {
8.1 --- a/src/Zone.h Tue Dec 25 17:02:07 2012 -0800
8.2 +++ b/src/Zone.h Tue Dec 25 18:13:02 2012 -0800
8.3 @@ -145,6 +145,7 @@
8.4 void endCompilationErrors();
8.5
8.6 void accept(VirtualObjectVisitor *visitor);
8.7 + void sweepWeakRoots();
8.8
8.9 void setPublicFunctionListener(Ke::IPublicFunctionListener *listener);
8.10 void registerPublic(Handle<Function> fun);