Commit e8cab885 authored by ishell's avatar ishell Committed by Commit bot

Move both dynamic and static object body visiting logic to BodyDescriptorBase class.

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

Cr-Commit-Position: refs/heads/master@{#31829}
parent 9c8f4f91
...@@ -188,79 +188,34 @@ class VisitorDispatchTable { ...@@ -188,79 +188,34 @@ class VisitorDispatchTable {
}; };
template <typename StaticVisitor>
class BodyVisitorBase : public AllStatic {
public:
INLINE(static void IteratePointers(Heap* heap, HeapObject* object,
int start_offset, int end_offset)) {
DCHECK(!FLAG_unbox_double_fields || object->map()->HasFastPointerLayout());
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()->HasFastPointerLayout()) {
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, object,
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));
LayoutDescriptorHelper helper(object->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)) {
IterateRawPointers(heap, object, offset, end_of_region_offset);
}
offset = end_of_region_offset;
}
}
};
template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { class FlexibleBodyVisitor : public AllStatic {
public: public:
INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
int object_size = BodyDescriptor::SizeOf(map, object); int object_size = BodyDescriptor::SizeOf(map, object);
BodyVisitorBase<StaticVisitor>::IterateBody( BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size);
map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
return static_cast<ReturnType>(object_size); return static_cast<ReturnType>(object_size);
} }
// This specialization is only suitable for objects containing pointer fields.
template <int object_size> template <int object_size>
static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); DCHECK(BodyDescriptor::SizeOf(map, object) == object_size);
BodyVisitorBase<StaticVisitor>::IteratePointers( DCHECK(!FLAG_unbox_double_fields || map->HasFastPointerLayout());
map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); StaticVisitor::VisitPointers(
object->GetHeap(), object,
HeapObject::RawField(object, BodyDescriptor::kStartOffset),
HeapObject::RawField(object, object_size));
return static_cast<ReturnType>(object_size); return static_cast<ReturnType>(object_size);
} }
}; };
template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { class FixedBodyVisitor : public AllStatic {
public: public:
INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object, BodyDescriptor::template IterateBody<StaticVisitor>(object);
BodyDescriptor::kStartOffset,
BodyDescriptor::kEndOffset);
return static_cast<ReturnType>(BodyDescriptor::kSize); return static_cast<ReturnType>(BodyDescriptor::kSize);
} }
}; };
......
...@@ -7841,7 +7841,8 @@ Relocatable::~Relocatable() { ...@@ -7841,7 +7841,8 @@ Relocatable::~Relocatable() {
// static // static
int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) { template <int start_offset>
int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) {
return map->instance_size(); return map->instance_size();
} }
...@@ -7852,12 +7853,6 @@ int FixedArray::BodyDescriptor::SizeOf(Map* map, HeapObject* object) { ...@@ -7852,12 +7853,6 @@ int FixedArray::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
} }
// static
int StructBodyDescriptor::SizeOf(Map* map, HeapObject* object) {
return map->instance_size();
}
void Foreign::ForeignIterateBody(ObjectVisitor* v) { void Foreign::ForeignIterateBody(ObjectVisitor* v) {
v->VisitExternalReference( v->VisitExternalReference(
reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset))); reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
...@@ -7914,48 +7909,54 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { ...@@ -7914,48 +7909,54 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
} }
static inline void IterateBodyUsingLayoutDescriptor(HeapObject* object, void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset,
int start_offset, int end_offset, ObjectVisitor* v) {
int end_offset,
ObjectVisitor* v) {
DCHECK(FLAG_unbox_double_fields);
DCHECK(IsAligned(start_offset, kPointerSize) &&
IsAligned(end_offset, kPointerSize));
LayoutDescriptorHelper helper(object->map());
DCHECK(!helper.all_fields_tagged());
for (int offset = start_offset; offset < end_offset; offset += kPointerSize) {
// Visit all tagged fields.
if (helper.IsTagged(offset)) {
v->VisitPointer(HeapObject::RawField(object, offset));
}
}
}
template<int start_offset, int end_offset, int size>
void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
HeapObject* obj,
ObjectVisitor* v) {
if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) { if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
v->VisitPointers(HeapObject::RawField(obj, start_offset), v->VisitPointers(HeapObject::RawField(obj, start_offset),
HeapObject::RawField(obj, end_offset)); HeapObject::RawField(obj, end_offset));
} else { } else {
IterateBodyUsingLayoutDescriptor(obj, start_offset, end_offset, v); 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)) {
v->VisitPointers(HeapObject::RawField(obj, offset),
HeapObject::RawField(obj, end_of_region_offset));
}
offset = end_of_region_offset;
}
} }
} }
template<int start_offset> template <typename StaticVisitor>
void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj, void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset,
int object_size, int end_offset) {
ObjectVisitor* v) { Heap* heap = obj->GetHeap();
if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) { if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
v->VisitPointers(HeapObject::RawField(obj, start_offset), StaticVisitor::VisitPointers(heap, obj,
HeapObject::RawField(obj, object_size)); HeapObject::RawField(obj, start_offset),
HeapObject::RawField(obj, end_offset));
} else { } else {
IterateBodyUsingLayoutDescriptor(obj, start_offset, object_size, v); 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)) {
StaticVisitor::VisitPointers(
heap, obj, HeapObject::RawField(obj, offset),
HeapObject::RawField(obj, end_of_region_offset));
}
offset = end_of_region_offset;
}
} }
} }
......
...@@ -1637,46 +1637,69 @@ class HeapObject: public Object { ...@@ -1637,46 +1637,69 @@ class HeapObject: public Object {
}; };
// This is the base class for object's body descriptors.
class BodyDescriptorBase {
protected:
static inline void IterateBodyImpl(HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename StaticVisitor>
static inline void IterateBodyImpl(HeapObject* obj, int start_offset,
int end_offset);
};
// This class describes a body of an object of a fixed size // 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) // in which all pointer fields are located in the [start_offset, end_offset)
// interval. // interval.
template<int start_offset, int end_offset, int size> template <int start_offset, int end_offset, int size>
class FixedBodyDescriptor { class FixedBodyDescriptor : public BodyDescriptorBase {
public: public:
static const int kStartOffset = start_offset; static const int kStartOffset = start_offset;
static const int kEndOffset = end_offset; static const int kEndOffset = end_offset;
static const int kSize = size; static const int kSize = size;
static inline void IterateBody(HeapObject* obj, ObjectVisitor* v); static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
IterateBodyImpl(obj, start_offset, end_offset, v);
}
template<typename StaticVisitor> template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj) { static inline void IterateBody(HeapObject* obj) {
StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset), IterateBodyImpl<StaticVisitor>(obj, start_offset, end_offset);
HeapObject::RawField(obj, end_offset));
} }
}; };
// This class describes a body of an object of a variable size // This base class describes a body of an object of a variable size
// in which all pointer fields are located in the [start_offset, object_size) // in which all pointer fields are located in the [start_offset, object_size)
// interval. // interval.
template<int start_offset> template <int start_offset>
class FlexibleBodyDescriptor { class FlexibleBodyDescriptorBase : public BodyDescriptorBase {
public: public:
static const int kStartOffset = start_offset; static const int kStartOffset = start_offset;
static inline void IterateBody(HeapObject* obj, static inline void IterateBody(HeapObject* obj, int object_size,
int object_size, ObjectVisitor* v) {
ObjectVisitor* v); IterateBodyImpl(obj, start_offset, object_size, v);
}
template<typename StaticVisitor> template <typename StaticVisitor>
static inline void IterateBody(HeapObject* obj, int object_size) { static inline void IterateBody(HeapObject* obj, int object_size) {
StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset), IterateBodyImpl<StaticVisitor>(obj, start_offset, object_size);
HeapObject::RawField(obj, object_size));
} }
}; };
// 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. The size of the object is taken from the map.
template <int start_offset>
class FlexibleBodyDescriptor : public FlexibleBodyDescriptorBase<start_offset> {
public:
static inline int SizeOf(Map* map, HeapObject* object);
};
// The HeapNumber class describes heap allocated numbers that cannot be // The HeapNumber class describes heap allocated numbers that cannot be
// represented in a Smi (small integer) // represented in a Smi (small integer)
class HeapNumber: public HeapObject { class HeapNumber: public HeapObject {
...@@ -2477,10 +2500,7 @@ class JSObject: public JSReceiver { ...@@ -2477,10 +2500,7 @@ class JSObject: public JSReceiver {
STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize); STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> { typedef FlexibleBodyDescriptor<kPropertiesOffset> BodyDescriptor;
public:
static inline int SizeOf(Map* map, HeapObject* object);
};
Context* GetCreationContext(); Context* GetCreationContext();
...@@ -2659,7 +2679,7 @@ class FixedArray: public FixedArrayBase { ...@@ -2659,7 +2679,7 @@ class FixedArray: public FixedArrayBase {
// object, the prefix of this array is sorted. // object, the prefix of this array is sorted.
void SortPairs(FixedArray* numbers, uint32_t len); void SortPairs(FixedArray* numbers, uint32_t len);
class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { class BodyDescriptor : public FlexibleBodyDescriptorBase<kHeaderSize> {
public: public:
static inline int SizeOf(Map* map, HeapObject* object); static inline int SizeOf(Map* map, HeapObject* object);
}; };
...@@ -10713,11 +10733,7 @@ class ObjectVisitor BASE_EMBEDDED { ...@@ -10713,11 +10733,7 @@ class ObjectVisitor BASE_EMBEDDED {
}; };
class StructBodyDescriptor : public typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
public:
static inline int SizeOf(Map* map, HeapObject* object);
};
// BooleanBit is a helper class for setting and getting a bit in an integer. // BooleanBit is a helper class for setting and getting a bit in an integer.
......
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