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