Commit ab5d90da authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[heap] Make concurrent marker use JSObject::FastBodyDescriptor

when applicable.

This CL also renames BodyDescriptorBase helpers
  IsValidSlotImpl() -> IsValidJSObjectSlotImpl()
  IterateBodyImpl() -> IterateJSObjectBodyImpl()
to make it clear that these methods are only applicable to JSObject subclasses
and fixes SmallOrderedHashTable::BodyDescriptor which used IsValidSlotImpl().

Bug: v8:8518
Change-Id: I11565bed6ebf56c6830ac0e21f866846e65025e6
Reviewed-on: https://chromium-review.googlesource.com/c/1372068
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58170}
parent 49fe8291
......@@ -214,7 +214,7 @@ class ConcurrentMarkingVisitor final
}
int VisitJSObjectFast(Map map, JSObject object) {
return VisitJSObjectSubclass(map, object);
return VisitJSObjectSubclassFast(map, object);
}
int VisitWasmInstanceObject(Map map, WasmInstanceObject object) {
......@@ -268,18 +268,15 @@ class ConcurrentMarkingVisitor final
// ===========================================================================
int VisitConsString(Map map, ConsString object) {
int size = ConsString::BodyDescriptor::SizeOf(map, object);
return VisitWithSnapshot(map, object, size, size);
return VisitFullyWithSnapshot(map, object);
}
int VisitSlicedString(Map map, SlicedString object) {
int size = SlicedString::BodyDescriptor::SizeOf(map, object);
return VisitWithSnapshot(map, object, size, size);
return VisitFullyWithSnapshot(map, object);
}
int VisitThinString(Map map, ThinString object) {
int size = ThinString::BodyDescriptor::SizeOf(map, object);
return VisitWithSnapshot(map, object, size, size);
return VisitFullyWithSnapshot(map, object);
}
// ===========================================================================
......@@ -485,12 +482,20 @@ class ConcurrentMarkingVisitor final
};
template <typename T>
int VisitJSObjectSubclassFast(Map map, T object) {
DCHECK_IMPLIES(FLAG_unbox_double_fields, map->HasFastPointerLayout());
using TBodyDescriptor = typename T::FastBodyDescriptor;
return VisitJSObjectSubclass<T, TBodyDescriptor>(map, object);
}
template <typename T, typename TBodyDescriptor = typename T::BodyDescriptor>
int VisitJSObjectSubclass(Map map, T object) {
int size = T::BodyDescriptor::SizeOf(map, object);
int size = TBodyDescriptor::SizeOf(map, object);
int used_size = map->UsedInstanceSize();
DCHECK_LE(used_size, size);
DCHECK_GE(used_size, T::kHeaderSize);
return VisitWithSnapshot(map, object, used_size, size);
return VisitPartiallyWithSnapshot<T, TBodyDescriptor>(map, object,
used_size, size);
}
template <typename T>
......@@ -521,20 +526,27 @@ class ConcurrentMarkingVisitor final
}
template <typename T>
int VisitWithSnapshot(Map map, T object, int used_size, int size) {
const SlotSnapshot& snapshot = MakeSlotSnapshot(map, object, used_size);
int VisitFullyWithSnapshot(Map map, T object) {
using TBodyDescriptor = typename T::BodyDescriptor;
int size = TBodyDescriptor::SizeOf(map, object);
return VisitPartiallyWithSnapshot<T, TBodyDescriptor>(map, object, size,
size);
}
template <typename T, typename TBodyDescriptor = typename T::BodyDescriptor>
int VisitPartiallyWithSnapshot(Map map, T object, int used_size, int size) {
const SlotSnapshot& snapshot =
MakeSlotSnapshot<T, TBodyDescriptor>(map, object, used_size);
if (!ShouldVisit(object)) return 0;
VisitPointersInSnapshot(object, snapshot);
return size;
}
template <typename T>
template <typename T, typename TBodyDescriptor>
const SlotSnapshot& MakeSlotSnapshot(Map map, T object, int size) {
SlotSnapshottingVisitor visitor(&slot_snapshot_);
visitor.VisitPointer(object, ObjectSlot(object->map_slot().address()));
// TODO(3770): Drop std::remove_pointer after the migration.
std::remove_pointer<T>::type::BodyDescriptor::IterateBody(map, object, size,
&visitor);
TBodyDescriptor::IterateBody(map, object, size, &visitor);
return slot_snapshot_;
}
......
......@@ -29,7 +29,8 @@ int FlexibleWeakBodyDescriptor<start_offset>::SizeOf(Map map,
return object->SizeFromMap(map);
}
bool BodyDescriptorBase::IsValidSlotImpl(Map map, HeapObject* obj, int offset) {
bool BodyDescriptorBase::IsValidJSObjectSlotImpl(Map map, HeapObject* obj,
int offset) {
if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
return true;
} else {
......@@ -43,9 +44,10 @@ bool BodyDescriptorBase::IsValidSlotImpl(Map map, HeapObject* obj, int offset) {
}
template <typename ObjectVisitor>
void BodyDescriptorBase::IterateBodyImpl(Map map, HeapObject* obj,
int start_offset, int end_offset,
ObjectVisitor* v) {
void BodyDescriptorBase::IterateJSObjectBodyImpl(Map map, HeapObject* obj,
int start_offset,
int end_offset,
ObjectVisitor* v) {
if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
IteratePointers(obj, start_offset, end_offset, v);
} else {
......@@ -112,13 +114,13 @@ class JSObject::BodyDescriptor final : public BodyDescriptorBase {
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
if (offset < kStartOffset) return false;
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateBodyImpl(map, obj, kStartOffset, object_size, v);
IterateJSObjectBodyImpl(map, obj, kStartOffset, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......@@ -152,7 +154,7 @@ class JSFunction::BodyDescriptor final : public BodyDescriptorBase {
if (offset < kSizeWithPrototype && map->has_prototype_slot()) {
return true;
}
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
......@@ -161,7 +163,7 @@ class JSFunction::BodyDescriptor final : public BodyDescriptorBase {
int header_size = JSFunction::GetHeaderSize(map->has_prototype_slot());
DCHECK_EQ(header_size, JSObject::GetHeaderSize(map));
IteratePointers(obj, kPropertiesOrHashOffset, header_size, v);
IterateBodyImpl(map, obj, header_size, object_size, v);
IterateJSObjectBodyImpl(map, obj, header_size, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......@@ -256,7 +258,7 @@ class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
if (offset < kEndOfTaggedFieldsOffset) return true;
if (offset < kHeaderSize) return false;
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
......@@ -264,7 +266,7 @@ class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
ObjectVisitor* v) {
// JSArrayBuffer instances contain raw data that the GC does not know about.
IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
IterateBodyImpl(map, obj, kHeaderSize, object_size, v);
IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......@@ -277,7 +279,7 @@ class JSArrayBufferView::BodyDescriptor final : public BodyDescriptorBase {
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
if (offset < kEndOfTaggedFieldsOffset) return true;
if (offset < kHeaderSize) return false;
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
......@@ -285,7 +287,7 @@ class JSArrayBufferView::BodyDescriptor final : public BodyDescriptorBase {
ObjectVisitor* v) {
// JSArrayBufferView contains raw data that the GC does not know about.
IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
IterateBodyImpl(map, obj, kHeaderSize, object_size, v);
IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......@@ -299,24 +301,18 @@ class SmallOrderedHashTable<Derived>::BodyDescriptor final
public:
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
Derived table = Derived::cast(obj);
if (offset < DataTableStartOffset()) return false;
if (offset >= table->GetBucketsStartOffset()) return false;
return IsValidSlotImpl(map, obj, offset);
// Only data table part contains tagged values.
return (offset >= DataTableStartOffset()) &&
(offset < table->GetBucketsStartOffset());
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
Derived table = Derived::cast(obj);
int offset = DataTableStartOffset();
int entry = 0;
for (int i = 0; i < table->Capacity(); i++) {
for (int j = 0; j < Derived::kEntrySize; j++) {
IteratePointer(obj, offset + (entry * kPointerSize), v);
entry++;
}
}
int start_offset = DataTableStartOffset();
int end_offset = table->GetBucketsStartOffset();
IteratePointers(obj, start_offset, end_offset, v);
}
static inline int SizeOf(Map map, HeapObject* obj) {
......@@ -487,13 +483,13 @@ class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
STATIC_ASSERT(kTableOffset + kPointerSize == kSize);
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
IterateBodyImpl(map, obj, kPropertiesOrHashOffset, object_size, v);
IterateJSObjectBodyImpl(map, obj, kPropertiesOrHashOffset, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......@@ -625,14 +621,14 @@ class WasmInstanceObject::BodyDescriptor final : public BodyDescriptorBase {
static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
if (offset < kMemoryStartOffset) return true;
if (offset < kModuleObjectOffset) return false;
return IsValidSlotImpl(map, obj, offset);
return IsValidJSObjectSlotImpl(map, obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject* obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, kPropertiesOrHashOffset, kFirstUntaggedOffset, v);
IterateBodyImpl(map, obj, kSize, object_size, v);
IterateJSObjectBodyImpl(map, obj, kSize, object_size, v);
}
static inline int SizeOf(Map map, HeapObject* object) {
......
......@@ -56,12 +56,18 @@ class BodyDescriptorBase {
protected:
// Returns true for all header and embedder fields.
static inline bool IsValidSlotImpl(Map map, HeapObject* obj, int offset);
static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject* obj,
int offset);
// Returns true for all header and embedder fields.
static inline bool IsValidEmbedderJSObjectSlotImpl(Map map, HeapObject* obj,
int offset);
// Treats all header and embedder fields in the range as tagged.
template <typename ObjectVisitor>
static inline void IterateBodyImpl(Map map, HeapObject* obj, int start_offset,
int end_offset, ObjectVisitor* v);
static inline void IterateJSObjectBodyImpl(Map map, HeapObject* obj,
int start_offset, int end_offset,
ObjectVisitor* v);
};
......
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