Chromium Code Reviews| Index: src/heap/objects-visiting.h |
| diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h |
| index db6b892ada05de2ec30dfbdf1b3ffdc1c20c1209..bff74436f28e2e90a9609f5f9567df06b49c977e 100644 |
| --- a/src/heap/objects-visiting.h |
| +++ b/src/heap/objects-visiting.h |
| @@ -6,6 +6,7 @@ |
| #define V8_OBJECTS_VISITING_H_ |
| #include "src/allocation.h" |
| +#include "src/layout-descriptor.h" |
| // This file provides base classes and auxiliary methods for defining |
| // static object visitors used during GC. |
| @@ -105,21 +106,29 @@ class StaticVisitorBase : public AllStatic { |
| // Determine which specialized visitor should be used for given instance type |
| // and instance type. |
| - static VisitorId GetVisitorId(int instance_type, int instance_size); |
| + static VisitorId GetVisitorId(int instance_type, int instance_size, |
| + bool has_unboxed_fields); |
| + // Determine which specialized visitor should be used for given map. |
| static VisitorId GetVisitorId(Map* map) { |
| - return GetVisitorId(map->instance_type(), map->instance_size()); |
| + return GetVisitorId(map->instance_type(), map->instance_size(), |
| + FLAG_unbox_double_fields && |
| + !map->layout_descriptor()->IsFastPointerLayout()); |
| } |
| // 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) { |
| + int object_size, |
| + bool has_unboxed_fields) { |
| DCHECK((base == kVisitDataObject) || (base == kVisitStruct) || |
| (base == kVisitJSObject)); |
| DCHECK(IsAligned(object_size, kPointerSize)); |
| DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size); |
| DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| + DCHECK(!has_unboxed_fields || (base == kVisitJSObject)); |
| + |
| + if (has_unboxed_fields) return generic; |
| const VisitorId specialization = static_cast<VisitorId>( |
| base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); |
| @@ -158,7 +167,7 @@ class VisitorDispatchTable { |
| 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), |
| + Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false), |
| &Visitor::template VisitSpecialized<size>); |
| } |
| @@ -189,11 +198,46 @@ class BodyVisitorBase : public AllStatic { |
| public: |
| INLINE(static void IteratePointers(Heap* heap, HeapObject* object, |
| int start_offset, int end_offset)) { |
| - Object** start_slot = |
| - reinterpret_cast<Object**>(object->address() + start_offset); |
| - Object** end_slot = |
| - reinterpret_cast<Object**>(object->address() + end_offset); |
| - StaticVisitor::VisitPointers(heap, start_slot, end_slot); |
| + DCHECK(!FLAG_unbox_double_fields || |
| + object->map()->layout_descriptor()->IsFastPointerLayout()); |
| + IterateRawPointers(heap, object, start_offset, end_offset); |
| + } |
| + |
| + INLINE(static void IterateBody(Heap* heap, HeapObject* object, |
| + int start_offset, int end_offset)) { |
| + if (!FLAG_unbox_double_fields || |
| + object->map()->layout_descriptor()->IsFastPointerLayout()) { |
| + IterateRawPointers(heap, object, start_offset, end_offset); |
| + } else { |
| + IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset); |
| + } |
| + } |
| + |
| + private: |
| + INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object, |
| + int start_offset, int end_offset)) { |
| + StaticVisitor::VisitPointers(heap, |
| + HeapObject::RawField(object, start_offset), |
| + HeapObject::RawField(object, end_offset)); |
| + } |
| + |
| + static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object, |
| + int start_offset, |
| + int end_offset) { |
| + DCHECK(FLAG_unbox_double_fields); |
| + DCHECK(IsAligned(start_offset, kPointerSize) && |
| + IsAligned(end_offset, kPointerSize)); |
| + |
| + InobjectPropertiesHelper helper(object->map()); |
| + DCHECK(!helper.all_fields_tagged()); |
| + |
| + for (int offset = start_offset; offset < end_offset; |
| + offset += kPointerSize) { |
| + // Visit tagged fields only. |
| + if (helper.IsTagged(offset)) { |
| + IterateRawPointers(heap, object, offset, offset + kPointerSize); |
|
Hannes Payer (out of office)
2014/11/06 12:29:46
Instead of calling this for each field, do you thi
Igor Sheludko
2014/11/07 08:03:52
Good point! But let me do that in a next CL.
Hannes Payer (out of office)
2014/11/10 15:26:08
Then please leave a todo.
Igor Sheludko
2014/11/10 15:43:54
Done.
|
| + } |
| + } |
| } |
| }; |
| @@ -203,7 +247,7 @@ class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
| public: |
| INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
| int object_size = BodyDescriptor::SizeOf(map, object); |
| - BodyVisitorBase<StaticVisitor>::IteratePointers( |
| + BodyVisitorBase<StaticVisitor>::IterateBody( |
| map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); |
| return static_cast<ReturnType>(object_size); |
| } |
| @@ -222,9 +266,9 @@ template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
| class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
| public: |
| INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
| - BodyVisitorBase<StaticVisitor>::IteratePointers( |
| - map->GetHeap(), object, BodyDescriptor::kStartOffset, |
| - BodyDescriptor::kEndOffset); |
| + BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object, |
| + BodyDescriptor::kStartOffset, |
| + BodyDescriptor::kEndOffset); |
| return static_cast<ReturnType>(BodyDescriptor::kSize); |
| } |
| }; |