diff -r f9c4371d59d4 -r 7721042bdb67 src/Array.h --- a/src/Array.h Thu Dec 27 21:07:03 2012 -0800 +++ b/src/Array.h Fri Dec 28 17:13:51 2012 -0800 @@ -32,6 +32,7 @@ { friend class ArrayMap; + protected: // Note: we do not write barrier |elements_|, since it can be set to // arbitrary pointers. uint32 length_; @@ -40,7 +41,7 @@ Object *objelements_; }; - private: + protected: void updateLengthAndElements(Zone *zone, unsigned length, Object *array) { length_ = length; write(zone, &objelements_, array); @@ -134,19 +135,50 @@ // End GC Descriptor. static Array *cast(Object *obj) { - assert(!obj || obj->is(MapKind_Array)); + assert(!obj || + obj->is(MapKind_Array) || + obj->is(MapKind_DependentArray)); return reinterpret_cast(obj); } }; +class DependentArray : public Array +{ + Barriered root_; + + public: + static Array *New(Zone *zone, Handle source, Handle map, unsigned index); + + // GC Descriptor. + static inline size_t offsetOfRoot() { + return offsetof(DependentArray, root_); + } + // End GC Descriptor. + + static DependentArray *cast(Object *obj) { + assert(!obj || obj->is(MapKind_DependentArray)); + return reinterpret_cast(obj); + } +}; + class ArrayMap : public Map { Barriered type_; public: + // The way array maps work is kind of clownshoes. In the future, these + // should be created immediately (or lazily) on the Type directly, and not + // manually created via ::Attach. :TODO: do this when we begin caching + // array types. static ArrayMap *New(Zone *zone, Handle type); static ArrayMap *Attach(Zone *zone, Handle type); + // DependentArray maps are never attached, and are just free-floating, + // rooted ultimately by the bytecode. A :TODO: that we might need to + // cache these, or attach them somewhere saner like ArrayType, which + // itself will eventually be cached. + static ArrayMap *NewDependent(Zone *zone, Handle type); + ArrayType *type() { return type_; } @@ -169,6 +201,7 @@ assert(!type()->contained()->isTraceable()); assert(type()->hasInlineElements() || type()->isExternalArray() || + is(MapKind_DependentArray) || !length() || ByteArray::cast((Object *)elements_));