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); |