Add weak hashtable to manage qual types.
authorDavid Anderson <dvander@alliedmods.net>
Tue Dec 25 18:13:02 2012 -0800 (2012-12-25)
changeset 240e3c851a14f16
parent 239 572668ef742b
child 241 18f3010a358c
Add weak hashtable to manage qual types.
src/Handles.h
src/Heap.cpp
src/TypeManager.cpp
src/TypeManager.h
src/Types.cpp
src/Types.h
src/Zone.cpp
src/Zone.h
     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);