Commit 138eb324 authored by ishell's avatar ishell Committed by Commit bot

Object's body descriptors refactoring.

1) Body descriptors moved to their own header files.
2) Missing body descriptors added.
3) Template versions of HeapObject::Iterate*() methods added.
4) Body descriptors support new kind of queries: IsValidSlot(offset) which can be used for invalid slots filtering.

This is a first step towards virtual and static visitors unification and support in-object properties in built-in (sub-)classes.

Review URL: https://codereview.chromium.org/1440243002

Cr-Commit-Position: refs/heads/master@{#31980}
parent 55c07a8b
......@@ -1127,6 +1127,8 @@ source_set("v8_base") {
"src/modules.cc",
"src/modules.h",
"src/msan.h",
"src/objects-body-descriptors-inl.h",
"src/objects-body-descriptors.h",
"src/objects-debug.cc",
"src/objects-inl.h",
"src/objects-printer.cc",
......
......@@ -1813,7 +1813,7 @@ void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) {
if (it.frame()->type() == StackFrame::OPTIMIZED) {
Code* code = it.frame()->LookupCode();
if (!code->CanDeoptAt(it.frame()->pc())) {
code->CodeIterateBody(visitor);
Code::BodyDescriptor::IterateBody(code, visitor);
}
ProcessMarkingDeque();
return;
......@@ -2723,8 +2723,7 @@ void MarkCompactCollector::MigrateObjectMixed(
heap()->MoveBlock(dst->address(), src->address(), size);
// Visit inherited JSObject properties and byte length of ArrayBuffer
Address regular_slot =
dst->address() + JSArrayBuffer::BodyDescriptor::kStartOffset;
Address regular_slot = dst->address() + JSArrayBuffer::kPropertiesOffset;
Address regular_slots_end =
dst->address() + JSArrayBuffer::kByteLengthOffset + kPointerSize;
while (regular_slot < regular_slots_end) {
......@@ -2793,7 +2792,7 @@ static inline void UpdateSlot(Isolate* isolate, ObjectVisitor* v,
}
case SlotsBuffer::RELOCATED_CODE_OBJECT: {
HeapObject* obj = HeapObject::FromAddress(addr);
Code::cast(obj)->CodeIterateBody(v);
Code::BodyDescriptor::IterateBody(obj, v);
break;
}
case SlotsBuffer::DEBUG_TARGET_SLOT: {
......@@ -3140,7 +3139,7 @@ bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
BytecodeArray::kConstantPoolOffset;
} else if (object->IsJSArrayBuffer()) {
int off = static_cast<int>(slot - object->address());
return (off >= JSArrayBuffer::BodyDescriptor::kStartOffset &&
return (off >= JSArrayBuffer::kPropertiesOffset &&
off <= JSArrayBuffer::kByteLengthOffset) ||
(off >= JSArrayBuffer::kSize &&
off < JSArrayBuffer::kSizeWithInternalFields);
......
......@@ -9,6 +9,7 @@
#include "src/heap/objects-visiting.h"
#include "src/ic/ic-state.h"
#include "src/macro-assembler.h"
#include "src/objects-body-descriptors-inl.h"
namespace v8 {
namespace internal {
......@@ -94,14 +95,14 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
template <typename StaticVisitor>
int StaticNewSpaceVisitor<StaticVisitor>::VisitJSArrayBuffer(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
typedef FlexibleBodyVisitor<StaticVisitor, JSArrayBuffer::BodyDescriptor, int>
JSArrayBufferBodyVisitor;
JSArrayBuffer::JSArrayBufferIterateBody<
StaticNewSpaceVisitor<StaticVisitor> >(heap, object);
if (!JSArrayBuffer::cast(object)->is_external()) {
Heap* heap = map->GetHeap();
heap->array_buffer_tracker()->MarkLive(JSArrayBuffer::cast(object));
}
return JSArrayBuffer::kSizeWithInternalFields;
return JSArrayBufferBodyVisitor::Visit(map, object);
}
......@@ -427,6 +428,8 @@ void StaticMarkingVisitor<StaticVisitor>::VisitWeakCollection(
template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map,
HeapObject* object) {
typedef FlexibleBodyVisitor<StaticVisitor, Code::BodyDescriptor, void>
CodeBodyVisitor;
Heap* heap = map->GetHeap();
Code* code = Code::cast(object);
if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
......@@ -439,7 +442,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map,
MarkInlinedFunctionsCode(heap, code);
}
}
code->CodeIterateBody<StaticVisitor>(heap);
CodeBodyVisitor::Visit(map, object);
}
......@@ -525,12 +528,9 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSFunction(Map* map,
template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(Map* map,
HeapObject* object) {
int last_property_offset =
JSRegExp::kSize + kPointerSize * map->GetInObjectProperties();
StaticVisitor::VisitPointers(
map->GetHeap(), object,
HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
HeapObject::RawField(object, last_property_offset));
typedef FlexibleBodyVisitor<StaticVisitor, JSRegExp::BodyDescriptor, void>
JSRegExpBodyVisitor;
JSRegExpBodyVisitor::Visit(map, object);
}
......@@ -539,7 +539,11 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
JSArrayBuffer::JSArrayBufferIterateBody<StaticVisitor>(heap, object);
typedef FlexibleBodyVisitor<StaticVisitor, JSArrayBuffer::BodyDescriptor,
void> JSArrayBufferBodyVisitor;
JSArrayBufferBodyVisitor::Visit(map, object);
if (!JSArrayBuffer::cast(object)->is_external() &&
!heap->InNewSpace(object)) {
heap->array_buffer_tracker()->MarkLive(JSArrayBuffer::cast(object));
......@@ -550,20 +554,18 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer(
template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSTypedArray(
Map* map, HeapObject* object) {
StaticVisitor::VisitPointers(
map->GetHeap(), object,
HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset),
HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields));
typedef FlexibleBodyVisitor<StaticVisitor, JSTypedArray::BodyDescriptor, void>
JSTypedArrayBodyVisitor;
JSTypedArrayBodyVisitor::Visit(map, object);
}
template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSDataView(Map* map,
HeapObject* object) {
StaticVisitor::VisitPointers(
map->GetHeap(), object,
HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset),
HeapObject::RawField(object, JSDataView::kSizeWithInternalFields));
typedef FlexibleBodyVisitor<StaticVisitor, JSDataView::BodyDescriptor, void>
JSDataViewBodyVisitor;
JSDataViewBodyVisitor::Visit(map, object);
}
......@@ -822,66 +824,6 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode(
}
void Code::CodeIterateBody(ObjectVisitor* v) {
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::CELL) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
RelocInfo::kDebugBreakSlotMask;
// There are two places where we iterate code bodies: here and the
// templated CodeIterateBody (below). They should be kept in sync.
IteratePointer(v, kRelocationInfoOffset);
IteratePointer(v, kHandlerTableOffset);
IteratePointer(v, kDeoptimizationDataOffset);
IteratePointer(v, kTypeFeedbackInfoOffset);
IterateNextCodeLink(v, kNextCodeLinkOffset);
RelocIterator it(this, mode_mask);
Isolate* isolate = this->GetIsolate();
for (; !it.done(); it.next()) {
it.rinfo()->Visit(isolate, v);
}
}
template <typename StaticVisitor>
void Code::CodeIterateBody(Heap* heap) {
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::CELL) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
RelocInfo::kDebugBreakSlotMask;
// There are two places where we iterate code bodies: here and the non-
// templated CodeIterateBody (above). They should be kept in sync.
StaticVisitor::VisitPointer(
heap, this,
reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset));
StaticVisitor::VisitPointer(
heap, this,
reinterpret_cast<Object**>(this->address() + kHandlerTableOffset));
StaticVisitor::VisitPointer(
heap, this,
reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset));
StaticVisitor::VisitPointer(
heap, this,
reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset));
StaticVisitor::VisitNextCodeLink(
heap, reinterpret_cast<Object**>(this->address() + kNextCodeLinkOffset));
RelocIterator it(this, mode_mask);
for (; !it.done(); it.next()) {
it.rinfo()->template Visit<StaticVisitor>(heap);
}
}
} // namespace internal
} // namespace v8
......
......@@ -179,138 +179,6 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
}
void HeapObject::IterateBody(InstanceType type, int object_size,
ObjectVisitor* v) {
// Avoiding <Type>::cast(this) because it accesses the map pointer field.
// During GC, the map pointer field is encoded.
if (type < FIRST_NONSTRING_TYPE) {
switch (type & kStringRepresentationMask) {
case kSeqStringTag:
break;
case kConsStringTag:
ConsString::BodyDescriptor::IterateBody(this, v);
break;
case kSlicedStringTag:
SlicedString::BodyDescriptor::IterateBody(this, v);
break;
case kExternalStringTag:
if ((type & kStringEncodingMask) == kOneByteStringTag) {
reinterpret_cast<ExternalOneByteString*>(this)
->ExternalOneByteStringIterateBody(v);
} else {
reinterpret_cast<ExternalTwoByteString*>(this)
->ExternalTwoByteStringIterateBody(v);
}
break;
}
return;
}
switch (type) {
case FIXED_ARRAY_TYPE:
FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
break;
case FIXED_DOUBLE_ARRAY_TYPE:
break;
case JS_OBJECT_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
case JS_MODULE_TYPE:
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_ARRAY_TYPE:
case JS_TYPED_ARRAY_TYPE:
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_ITERATOR_RESULT_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
case JS_REGEXP_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
JSObject::BodyDescriptor::IterateBody(this, object_size, v);
break;
case JS_ARRAY_BUFFER_TYPE:
JSArrayBuffer::JSArrayBufferIterateBody(this, v);
break;
case JS_FUNCTION_TYPE:
JSFunction::BodyDescriptor::IterateBody(this, object_size, v);
break;
case ODDBALL_TYPE:
Oddball::BodyDescriptor::IterateBody(this, v);
break;
case JS_PROXY_TYPE:
JSProxy::BodyDescriptor::IterateBody(this, v);
break;
case JS_FUNCTION_PROXY_TYPE:
JSFunctionProxy::BodyDescriptor::IterateBody(this, v);
break;
case FOREIGN_TYPE:
reinterpret_cast<Foreign*>(this)->ForeignIterateBody(v);
break;
case MAP_TYPE:
Map::BodyDescriptor::IterateBody(this, v);
break;
case CODE_TYPE:
reinterpret_cast<Code*>(this)->CodeIterateBody(v);
break;
case CELL_TYPE:
Cell::BodyDescriptor::IterateBody(this, v);
break;
case PROPERTY_CELL_TYPE:
PropertyCell::BodyDescriptor::IterateBody(this, v);
break;
case WEAK_CELL_TYPE:
WeakCell::BodyDescriptor::IterateBody(this, v);
break;
case SYMBOL_TYPE:
Symbol::BodyDescriptor::IterateBody(this, v);
break;
case BYTECODE_ARRAY_TYPE:
reinterpret_cast<BytecodeArray*>(this)->BytecodeArrayIterateBody(v);
break;
case HEAP_NUMBER_TYPE:
case MUTABLE_HEAP_NUMBER_TYPE:
case SIMD128_VALUE_TYPE:
case FILLER_TYPE:
case BYTE_ARRAY_TYPE:
case FREE_SPACE_TYPE:
break;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case FIXED_##TYPE##_ARRAY_TYPE: \
reinterpret_cast<FixedTypedArrayBase*>(this) \
->FixedTypedArrayBaseIterateBody(v); \
break;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
case SHARED_FUNCTION_INFO_TYPE: {
SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
break;
}
#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE
if (type == ALLOCATION_SITE_TYPE) {
AllocationSite::BodyDescriptor::IterateBody(this, v);
} else {
StructBodyDescriptor::IterateBody(this, object_size, v);
}
break;
default:
PrintF("Unknown type: %d\n", type);
UNREACHABLE();
}
}
// We don't record weak slots during marking or scavenges. Instead we do it
// once when we complete mark-compact cycle. Note that write barrier has no
// effect if we are already in the middle of compacting mark-sweep cycle and we
......
......@@ -9,6 +9,7 @@
#include "src/heap/heap.h"
#include "src/heap/spaces.h"
#include "src/layout-descriptor.h"
#include "src/objects-body-descriptors.h"
// This file provides base classes and auxiliary methods for defining
// static object visitors used during GC.
......
......@@ -266,7 +266,8 @@ class ScavengingVisitor : public StaticVisitorBase {
static inline void EvacuateFixedArray(Map* map, HeapObject** slot,
HeapObject* object) {
int object_size = FixedArray::BodyDescriptor::SizeOf(map, object);
int length = reinterpret_cast<FixedArray*>(object)->synchronized_length();
int object_size = FixedArray::SizeFor(length);
EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object,
object_size);
}
......
......@@ -502,8 +502,7 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
slot_callback);
} else if (heap_object->IsJSArrayBuffer()) {
FindPointersToNewSpaceInRegion(
obj_address +
JSArrayBuffer::BodyDescriptor::kStartOffset,
obj_address + JSArrayBuffer::kPropertiesOffset,
obj_address + JSArrayBuffer::kByteLengthOffset +
kPointerSize,
slot_callback);
......
This diff is collapsed.
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_BODY_DESCRIPTORS_H_
#define V8_OBJECTS_BODY_DESCRIPTORS_H_
#include "src/objects.h"
namespace v8 {
namespace internal {
// This is the base class for object's body descriptors.
//
// Each BodyDescriptor subclass must provide the following methods:
//
// 1) Returns true if the object contains a tagged value at given offset.
// It is used for invalid slots filtering. If the offset points outside
// of the object or to the map word, the result is UNDEFINED (!!!).
//
// static bool IsValidSlot(HeapObject* obj, int offset);
//
//
// 2) Iterate object's body using stateful object visitor.
//
// template <typename ObjectVisitor>
// static inline void IterateBody(HeapObject* obj, int object_size,
// ObjectVisitor* v);
//
//
// 3) Iterate object's body using stateless object visitor.
//
// template <typename StaticVisitor>
// static inline void IterateBody(HeapObject* obj, int object_size);
//
class BodyDescriptorBase BASE_EMBEDDED {
public:
template <typename ObjectVisitor>
static inline void IteratePointers(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename StaticVisitor>
static inline void IteratePointers(Heap* heap, HeapObject* obj,
int start_offset, int end_offset);
template <typename ObjectVisitor>
static inline void IteratePointer(HeapObject* obj, int offset,
ObjectVisitor* v);
template <typename StaticVisitor>
static inline void IteratePointer(Heap* heap, HeapObject* obj, int offset);
protected:
// Returns true for all header fields.
static inline bool IsValidSlotImpl(HeapObject* obj, int offset);
template <typename ObjectVisitor>
static inline void IterateBodyImpl(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename StaticVisitor>
static inline void IterateBodyImpl(Heap* heap, HeapObject* obj,
int start_offset, int end_offset);
};
// This class describes a body of an object of a fixed size
// in which all pointer fields are located in the [start_offset, end_offset)
// interval.
template <int start_offset, int end_offset, int size>
class FixedBodyDescriptor final : public BodyDescriptorBase {
public:
static const int kStartOffset = start_offset;
static const int kEndOffset = end_offset;
static const int kSize = size;
static bool IsValidSlot(HeapObject* obj, int offset) {
return offset >= kStartOffset && offset < kEndOffset;
}
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
IterateBodyImpl(obj, start_offset, end_offset, v);
}
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateBody(obj, v);
}
template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj) {
Heap* heap = obj->GetHeap();
IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, end_offset);
}
template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) {
IterateBody(obj);
}
};
// This class describes a body of an object of a variable size
// in which all pointer fields are located in the [start_offset, object_size)
// interval.
template <int start_offset>
class FlexibleBodyDescriptor final : public BodyDescriptorBase {
public:
static const int kStartOffset = start_offset;
static bool IsValidSlot(HeapObject* obj, int offset) {
if (offset < kStartOffset) return false;
return IsValidSlotImpl(obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateBodyImpl(obj, start_offset, object_size, v);
}
template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) {
Heap* heap = obj->GetHeap();
IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, object_size);
}
static inline int SizeOf(Map* map, HeapObject* object);
};
typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_BODY_DESCRIPTORS_H_
......@@ -1530,22 +1530,6 @@ HeapObjectContents HeapObject::ContentType() {
}
void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
}
void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
}
void HeapObject::IterateNextCodeLink(ObjectVisitor* v, int offset) {
v->VisitNextCodeLink(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
}
double HeapNumber::value() const {
return READ_DOUBLE_FIELD(this, kValueOffset);
}
......@@ -4173,11 +4157,6 @@ Address ByteArray::GetDataStartAddress() {
}
void BytecodeArray::BytecodeArrayIterateBody(ObjectVisitor* v) {
IteratePointer(v, kConstantPoolOffset);
}
byte BytecodeArray::get(int index) {
DCHECK(index >= 0 && index < this->length());
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
......@@ -4538,7 +4517,8 @@ int HeapObject::SizeFromMap(Map* map) {
// Only inline the most frequent cases.
InstanceType instance_type = map->instance_type();
if (instance_type == FIXED_ARRAY_TYPE) {
return FixedArray::BodyDescriptor::SizeOf(map, this);
return FixedArray::SizeFor(
reinterpret_cast<FixedArray*>(this)->synchronized_length());
}
if (instance_type == ONE_BYTE_STRING_TYPE ||
instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
......@@ -6677,32 +6657,6 @@ void JSArrayBuffer::set_is_shared(bool value) {
}
// static
template <typename StaticVisitor>
void JSArrayBuffer::JSArrayBufferIterateBody(Heap* heap, HeapObject* obj) {
StaticVisitor::VisitPointers(
heap, obj,
HeapObject::RawField(obj, JSArrayBuffer::BodyDescriptor::kStartOffset),
HeapObject::RawField(obj,
JSArrayBuffer::kByteLengthOffset + kPointerSize));
StaticVisitor::VisitPointers(
heap, obj, HeapObject::RawField(obj, JSArrayBuffer::kSize),
HeapObject::RawField(obj, JSArrayBuffer::kSizeWithInternalFields));
}
void JSArrayBuffer::JSArrayBufferIterateBody(HeapObject* obj,
ObjectVisitor* v) {
v->VisitPointers(
HeapObject::RawField(obj, JSArrayBuffer::BodyDescriptor::kStartOffset),
HeapObject::RawField(obj,
JSArrayBuffer::kByteLengthOffset + kPointerSize));
v->VisitPointers(
HeapObject::RawField(obj, JSArrayBuffer::kSize),
HeapObject::RawField(obj, JSArrayBuffer::kSizeWithInternalFields));
}
Object* JSArrayBufferView::byte_offset() const {
if (WasNeutered()) return Smi::FromInt(0);
return Object::cast(READ_FIELD(this, kByteOffsetOffset));
......@@ -7835,189 +7789,6 @@ Relocatable::~Relocatable() {
}
// static
template <int start_offset>
int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) {
return map->instance_size();
}
// static
int FixedArray::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
return SizeFor(reinterpret_cast<FixedArray*>(object)->synchronized_length());
}
void Foreign::ForeignIterateBody(ObjectVisitor* v) {
v->VisitExternalReference(
reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
}
template<typename StaticVisitor>
void Foreign::ForeignIterateBody() {
StaticVisitor::VisitExternalReference(
reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
}
void FixedTypedArrayBase::FixedTypedArrayBaseIterateBody(ObjectVisitor* v) {
v->VisitPointer(
reinterpret_cast<Object**>(FIELD_ADDR(this, kBasePointerOffset)));
}
template <typename StaticVisitor>
void FixedTypedArrayBase::FixedTypedArrayBaseIterateBody() {
StaticVisitor::VisitPointer(
reinterpret_cast<Object**>(FIELD_ADDR(this, kBasePointerOffset)));
}
void ExternalOneByteString::ExternalOneByteStringIterateBody(ObjectVisitor* v) {
typedef v8::String::ExternalOneByteStringResource Resource;
v->VisitExternalOneByteString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}
template <typename StaticVisitor>
void ExternalOneByteString::ExternalOneByteStringIterateBody() {
typedef v8::String::ExternalOneByteStringResource Resource;
StaticVisitor::VisitExternalOneByteString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}
void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
typedef v8::String::ExternalStringResource Resource;
v->VisitExternalTwoByteString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}
template<typename StaticVisitor>
void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
typedef v8::String::ExternalStringResource Resource;
StaticVisitor::VisitExternalTwoByteString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}
void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v) {
if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
IteratePointers(obj, start_offset, end_offset, v);
} else {
DCHECK(FLAG_unbox_double_fields);
DCHECK(IsAligned(start_offset, kPointerSize) &&
IsAligned(end_offset, kPointerSize));
LayoutDescriptorHelper helper(obj->map());
DCHECK(!helper.all_fields_tagged());
for (int offset = start_offset; offset < end_offset;) {
int end_of_region_offset;
if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
IteratePointers(obj, offset, end_of_region_offset, v);
}
offset = end_of_region_offset;
}
}
}
template <typename StaticVisitor>
void BodyDescriptorBase::IterateBodyImpl(Heap* heap, HeapObject* obj,
int start_offset, int end_offset) {
if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
IteratePointers<StaticVisitor>(heap, obj, start_offset, end_offset);
} else {
DCHECK(FLAG_unbox_double_fields);
DCHECK(IsAligned(start_offset, kPointerSize) &&
IsAligned(end_offset, kPointerSize));
LayoutDescriptorHelper helper(obj->map());
DCHECK(!helper.all_fields_tagged());
for (int offset = start_offset; offset < end_offset;) {
int end_of_region_offset;
if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
IteratePointers<StaticVisitor>(heap, obj, offset, end_of_region_offset);
}
offset = end_of_region_offset;
}
}
}
void BodyDescriptorBase::IteratePointers(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v) {
v->VisitPointers(HeapObject::RawField(obj, start_offset),
HeapObject::RawField(obj, end_offset));
}
template <typename StaticVisitor>
void BodyDescriptorBase::IteratePointers(Heap* heap, HeapObject* obj,
int start_offset, int end_offset) {
StaticVisitor::VisitPointers(heap, obj,
HeapObject::RawField(obj, start_offset),
HeapObject::RawField(obj, end_offset));
}
// Iterates the function object according to the visiting policy.
template <JSFunction::BodyVisitingPolicy body_visiting_policy>
class JSFunction::BodyDescriptorImpl : public BodyDescriptorBase {
public:
STATIC_ASSERT(kNonWeakFieldsEndOffset == kCodeEntryOffset);
STATIC_ASSERT(kCodeEntryOffset + kPointerSize == kNextFunctionLinkOffset);
STATIC_ASSERT(kNextFunctionLinkOffset + kPointerSize == kSize);
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, kPropertiesOffset, kNonWeakFieldsEndOffset, v);
if (body_visiting_policy & kVisitCodeEntry) {
v->VisitCodeEntry(obj->address() + kCodeEntryOffset);
}
if (body_visiting_policy & kVisitNextFunction) {
IteratePointers(obj, kNextFunctionLinkOffset, kSize, v);
}
// TODO(ishell): v8:4531, fix when JFunctions are allowed to have in-object
// properties
// IterateBodyImpl(obj, kSize, object_size, v);
}
template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) {
Heap* heap = obj->GetHeap();
IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset,
kNonWeakFieldsEndOffset);
if (body_visiting_policy & kVisitCodeEntry) {
StaticVisitor::VisitCodeEntry(heap, obj,
obj->address() + kCodeEntryOffset);
}
if (body_visiting_policy & kVisitNextFunction) {
IteratePointers<StaticVisitor>(heap, obj, kNextFunctionLinkOffset, kSize);
}
// TODO(ishell): v8:4531, fix when JFunctions are allowed to have in-object
// properties
// IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size);
}
static inline int SizeOf(Map* map, HeapObject* object) {
// TODO(ishell): v8:4531, fix when JFunctions are allowed to have in-object
// properties
return JSFunction::kSize;
}
};
template<class Derived, class TableType>
Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
TableType* table(TableType::cast(this->table()));
......
......@@ -37,6 +37,7 @@
#include "src/macro-assembler.h"
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/objects-body-descriptors-inl.h"
#include "src/profiler/cpu-profiler.h"
#include "src/property-descriptor.h"
#include "src/prototype.h"
......@@ -1999,12 +2000,33 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
}
void HeapObject::Iterate(ObjectVisitor* v) {
// Handle header
IteratePointer(v, kMapOffset);
// Handle object body
void HeapObject::Iterate(ObjectVisitor* v) { IterateFast<ObjectVisitor>(v); }
void HeapObject::IterateBody(ObjectVisitor* v) {
Map* m = map();
IterateBody(m->instance_type(), SizeFromMap(m), v);
IterateBodyFast<ObjectVisitor>(m->instance_type(), SizeFromMap(m), v);
}
void HeapObject::IterateBody(InstanceType type, int object_size,
ObjectVisitor* v) {
IterateBodyFast<ObjectVisitor>(type, object_size, v);
}
struct CallIsValidSlot {
template <typename BodyDescriptor>
static bool apply(HeapObject* obj, int offset, int) {
return BodyDescriptor::IsValidSlot(obj, offset);
}
};
bool HeapObject::IsValidSlot(int offset) {
DCHECK_NE(0, offset);
return BodyDescriptorApply<CallIsValidSlot, bool>(map()->instance_type(),
this, offset, 0);
}
......@@ -15249,15 +15271,14 @@ class InternalizedStringKey : public HashTableKey {
template<typename Derived, typename Shape, typename Key>
void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) {
IteratePointers(v, 0, kElementsStartOffset);
BodyDescriptorBase::IteratePointers(this, 0, kElementsStartOffset, v);
}
template<typename Derived, typename Shape, typename Key>
void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) {
IteratePointers(v,
kElementsStartOffset,
kHeaderSize + length() * kPointerSize);
BodyDescriptorBase::IteratePointers(this, kElementsStartOffset,
kHeaderSize + length() * kPointerSize, v);
}
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include "src/code-stubs.h"
#include "src/conversions.h"
#include "src/debug/debug.h"
#include "src/objects-body-descriptors.h"
#include "src/profiler/allocation-tracker.h"
#include "src/profiler/heap-profiler.h"
#include "src/profiler/heap-snapshot-generator-inl.h"
......@@ -1542,7 +1543,7 @@ void V8HeapExplorer::ExtractAllocationSiteReferences(int entry,
// Do not visit weak_next as it is not visited by the StaticVisitor,
// and we're not very interested in weak_next field here.
STATIC_ASSERT(AllocationSite::kWeakNextOffset >=
AllocationSite::BodyDescriptor::kEndOffset);
AllocationSite::BodyDescriptor::kEndOffset);
}
......
......@@ -867,6 +867,8 @@
'../../src/modules.cc',
'../../src/modules.h',
'../../src/msan.h',
'../../src/objects-body-descriptors-inl.h',
'../../src/objects-body-descriptors.h',
'../../src/objects-debug.cc',
'../../src/objects-inl.h',
'../../src/objects-printer.cc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment