| Index: src/heap/objects-visiting.h
|
| diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h
|
| index abbb27a3267d7fba7618ccddf8930a93da667e50..f10f370314766cebfb8520aa118b899e4440cde0 100644
|
| --- a/src/heap/objects-visiting.h
|
| +++ b/src/heap/objects-visiting.h
|
| @@ -41,11 +41,42 @@
|
| V(FixedFloat64Array) \
|
| V(NativeContext) \
|
| V(AllocationSite) \
|
| - V(DataObject) \
|
| - V(JSObjectFast) \
|
| - V(JSObject) \
|
| - V(JSApiObject) \
|
| - V(Struct) \
|
| + V(DataObject2) \
|
| + V(DataObject3) \
|
| + V(DataObject4) \
|
| + V(DataObject5) \
|
| + V(DataObject6) \
|
| + V(DataObject7) \
|
| + V(DataObject8) \
|
| + V(DataObject9) \
|
| + V(DataObjectGeneric) \
|
| + V(JSObject2) \
|
| + V(JSObject3) \
|
| + V(JSObject4) \
|
| + V(JSObject5) \
|
| + V(JSObject6) \
|
| + V(JSObject7) \
|
| + V(JSObject8) \
|
| + V(JSObject9) \
|
| + V(JSObjectGeneric) \
|
| + V(JSApiObject2) \
|
| + V(JSApiObject3) \
|
| + V(JSApiObject4) \
|
| + V(JSApiObject5) \
|
| + V(JSApiObject6) \
|
| + V(JSApiObject7) \
|
| + V(JSApiObject8) \
|
| + V(JSApiObject9) \
|
| + V(JSApiObjectGeneric) \
|
| + V(Struct2) \
|
| + V(Struct3) \
|
| + V(Struct4) \
|
| + V(Struct5) \
|
| + V(Struct6) \
|
| + V(Struct7) \
|
| + V(Struct8) \
|
| + V(Struct9) \
|
| + V(StructGeneric) \
|
| V(ConsString) \
|
| V(SlicedString) \
|
| V(ThinString) \
|
| @@ -76,7 +107,11 @@
|
| #define VISITOR_ID_ENUM_DECL(id) kVisit##id,
|
| VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
|
| #undef VISITOR_ID_ENUM_DECL
|
| - kVisitorIdCount
|
| + kVisitorIdCount,
|
| + kVisitDataObject = kVisitDataObject2,
|
| + kVisitJSObject = kVisitJSObject2,
|
| + kVisitJSApiObject = kVisitJSApiObject2,
|
| + kVisitStruct = kVisitStruct2,
|
| };
|
|
|
| // Visitor ID should fit in one byte.
|
| @@ -89,6 +124,28 @@
|
|
|
| // Determine which specialized visitor should be used for given map.
|
| static VisitorId GetVisitorId(Map* map);
|
| +
|
| + // For visitors that allow specialization by size calculate VisitorId based
|
| + // on size, base visitor id and generic visitor id.
|
| + static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
|
| + int object_size,
|
| + bool has_unboxed_fields) {
|
| + DCHECK((base == kVisitDataObject) || (base == kVisitStruct) ||
|
| + (base == kVisitJSObject) || (base == kVisitJSApiObject));
|
| + DCHECK(IsAligned(object_size, kPointerSize));
|
| + DCHECK(Heap::kMinObjectSizeInWords * kPointerSize <= object_size);
|
| + DCHECK(object_size <= kMaxRegularHeapObjectSize);
|
| + DCHECK(!has_unboxed_fields || (base == kVisitJSObject) ||
|
| + (base == kVisitJSApiObject));
|
| +
|
| + if (has_unboxed_fields) return generic;
|
| +
|
| + int visitor_id = Min(
|
| + base + (object_size >> kPointerSizeLog2) - Heap::kMinObjectSizeInWords,
|
| + static_cast<int>(generic));
|
| +
|
| + return static_cast<VisitorId>(visitor_id);
|
| + }
|
| };
|
|
|
|
|
| @@ -115,6 +172,30 @@
|
| callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
|
| }
|
|
|
| + template <typename Visitor, StaticVisitorBase::VisitorId base,
|
| + StaticVisitorBase::VisitorId generic, int object_size_in_words>
|
| + void RegisterSpecialization() {
|
| + static const int size = object_size_in_words * kPointerSize;
|
| + Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false),
|
| + &Visitor::template VisitSpecialized<size>);
|
| + }
|
| +
|
| +
|
| + template <typename Visitor, StaticVisitorBase::VisitorId base,
|
| + StaticVisitorBase::VisitorId generic>
|
| + void RegisterSpecializations() {
|
| + STATIC_ASSERT((generic - base + Heap::kMinObjectSizeInWords) == 10);
|
| + RegisterSpecialization<Visitor, base, generic, 2>();
|
| + RegisterSpecialization<Visitor, base, generic, 3>();
|
| + RegisterSpecialization<Visitor, base, generic, 4>();
|
| + RegisterSpecialization<Visitor, base, generic, 5>();
|
| + RegisterSpecialization<Visitor, base, generic, 6>();
|
| + RegisterSpecialization<Visitor, base, generic, 7>();
|
| + RegisterSpecialization<Visitor, base, generic, 8>();
|
| + RegisterSpecialization<Visitor, base, generic, 9>();
|
| + Register(generic, &Visitor::Visit);
|
| + }
|
| +
|
| private:
|
| base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount];
|
| };
|
| @@ -126,6 +207,18 @@
|
| INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
|
| int object_size = BodyDescriptor::SizeOf(map, object);
|
| BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size);
|
| + return static_cast<ReturnType>(object_size);
|
| + }
|
| +
|
| + // This specialization is only suitable for objects containing pointer fields.
|
| + template <int object_size>
|
| + static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
|
| + DCHECK(BodyDescriptor::SizeOf(map, object) == object_size);
|
| + DCHECK(!FLAG_unbox_double_fields || map->HasFastPointerLayout());
|
| + StaticVisitor::VisitPointers(
|
| + object->GetHeap(), object,
|
| + HeapObject::RawField(object, BodyDescriptor::kStartOffset),
|
| + HeapObject::RawField(object, object_size));
|
| return static_cast<ReturnType>(object_size);
|
| }
|
| };
|
| @@ -196,6 +289,10 @@
|
| return FixedDoubleArray::SizeFor(length);
|
| }
|
|
|
| + INLINE(static int VisitJSObject(Map* map, HeapObject* object)) {
|
| + return JSObjectVisitor::Visit(map, object);
|
| + }
|
| +
|
| INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) {
|
| return SeqOneByteString::cast(object)
|
| ->SeqOneByteStringSize(map->instance_type());
|
| @@ -227,10 +324,6 @@
|
|
|
| typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int>
|
| JSObjectVisitor;
|
| -
|
| - // Visitor for JSObjects without unboxed double fields.
|
| - typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, int>
|
| - JSObjectFastVisitor;
|
|
|
| typedef int (*Callback)(Map* map, HeapObject* object);
|
|
|
| @@ -315,13 +408,17 @@
|
| typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void>
|
| FixedArrayVisitor;
|
|
|
| - typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, void>
|
| - JSObjectFastVisitor;
|
| typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void>
|
| JSObjectVisitor;
|
|
|
| class JSApiObjectVisitor : AllStatic {
|
| public:
|
| + template <int size>
|
| + static inline void VisitSpecialized(Map* map, HeapObject* object) {
|
| + TracePossibleWrapper(object);
|
| + JSObjectVisitor::template VisitSpecialized<size>(map, object);
|
| + }
|
| +
|
| INLINE(static void Visit(Map* map, HeapObject* object)) {
|
| TracePossibleWrapper(object);
|
| JSObjectVisitor::Visit(map, object);
|
|
|