| Index: src/heap/objects-visiting.h
|
| diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h
|
| index db6b892ada05de2ec30dfbdf1b3ffdc1c20c1209..b25b44963627e29d20bbef280b4187b02023b6e8 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,47 @@ 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)) {
|
| + // TODO(ishell): call this once for contiguous region of tagged fields.
|
| + IterateRawPointers(heap, object, offset, offset + kPointerSize);
|
| + }
|
| + }
|
| }
|
| };
|
|
|
| @@ -203,7 +248,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 +267,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);
|
| }
|
| };
|
|
|