Index: src/objects-visiting.h |
diff --git a/src/objects-visiting.h b/src/objects-visiting.h |
index f6fda9df0a2c9ee0deff359f4a57454d020e9b99..083a8ce5a4828a121f6135b1bcd0e75753cbc04c 100644 |
--- a/src/objects-visiting.h |
+++ b/src/objects-visiting.h |
@@ -104,23 +104,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_non_tagged_fields); |
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) { |
+ static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic, |
+ int object_size, |
+ bool has_non_tagged_fields) { |
ASSERT((base == kVisitDataObject) || |
(base == kVisitStruct) || |
(base == kVisitJSObject)); |
ASSERT(IsAligned(object_size, kPointerSize)); |
ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size); |
ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); |
+ ASSERT(!has_non_tagged_fields || (base == kVisitJSObject)); |
+ |
+ if (has_non_tagged_fields) return generic; |
const VisitorId specialization = static_cast<VisitorId>( |
base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); |
@@ -161,7 +167,7 @@ class VisitorDispatchTable { |
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>); |
} |
@@ -195,11 +201,46 @@ class BodyVisitorBase : public AllStatic { |
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); |
+ ASSERT(!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) { |
+ ASSERT(FLAG_unbox_double_fields); |
+ ASSERT(IsAligned(start_offset, kPointerSize) && |
+ IsAligned(end_offset, kPointerSize)); |
+ |
+ InobjectPropertiesHelper helper(object->map()); |
+ ASSERT(!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); |
+ } |
+ } |
} |
}; |
@@ -209,11 +250,8 @@ class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
public: |
INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
int object_size = BodyDescriptor::SizeOf(map, object); |
- BodyVisitorBase<StaticVisitor>::IteratePointers( |
- map->GetHeap(), |
- object, |
- BodyDescriptor::kStartOffset, |
- object_size); |
+ BodyVisitorBase<StaticVisitor>::IterateBody( |
+ map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); |
return static_cast<ReturnType>(object_size); |
} |
@@ -234,11 +272,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); |
} |
}; |