[heap] Add VisitEphemeron method
This modifies the ObjectVisitor to provide a dedicated VisitEphemeron method invoked when visiting a EphemeronHashTable. This is pre-work for further changes to how ephemerons are handled during scavenging. Bug: v8:8557 Change-Id: Ia423b10667ec222cbe5f44d8a931ea33314625f4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508673 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Cr-Commit-Position: refs/heads/master@{#60119}
This commit is contained in:
parent
d6465298b6
commit
7a6e829b72
@ -508,7 +508,7 @@ class ConcurrentMarkingVisitor final
|
||||
|
||||
// Implements ephemeron semantics: Marks value if key is already reachable.
|
||||
// Returns true if value was actually marked.
|
||||
bool VisitEphemeron(HeapObject key, HeapObject value) {
|
||||
bool ProcessEphemeron(HeapObject key, HeapObject value) {
|
||||
if (marking_state_.IsBlackOrGrey(key)) {
|
||||
if (marking_state_.WhiteToGrey(value)) {
|
||||
shared_.Push(value);
|
||||
@ -776,7 +776,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
|
||||
Ephemeron ephemeron;
|
||||
|
||||
while (weak_objects_->current_ephemerons.Pop(task_id, &ephemeron)) {
|
||||
if (visitor.VisitEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
if (visitor.ProcessEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
ephemeron_marked = true;
|
||||
}
|
||||
}
|
||||
@ -821,7 +821,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
|
||||
Ephemeron ephemeron;
|
||||
|
||||
while (weak_objects_->discovered_ephemerons.Pop(task_id, &ephemeron)) {
|
||||
if (visitor.VisitEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
if (visitor.ProcessEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
ephemeron_marked = true;
|
||||
}
|
||||
}
|
||||
|
@ -1547,7 +1547,7 @@ bool MarkCompactCollector::ProcessEphemerons() {
|
||||
// Drain current_ephemerons and push ephemerons where key and value are still
|
||||
// unreachable into next_ephemerons.
|
||||
while (weak_objects_.current_ephemerons.Pop(kMainThread, &ephemeron)) {
|
||||
if (VisitEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
ephemeron_marked = true;
|
||||
}
|
||||
}
|
||||
@ -1560,7 +1560,7 @@ bool MarkCompactCollector::ProcessEphemerons() {
|
||||
// before) and push ephemerons where key and value are still unreachable into
|
||||
// next_ephemerons.
|
||||
while (weak_objects_.discovered_ephemerons.Pop(kMainThread, &ephemeron)) {
|
||||
if (VisitEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
|
||||
ephemeron_marked = true;
|
||||
}
|
||||
}
|
||||
@ -1583,7 +1583,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() {
|
||||
weak_objects_.current_ephemerons.Swap(weak_objects_.next_ephemerons);
|
||||
|
||||
while (weak_objects_.current_ephemerons.Pop(kMainThread, &ephemeron)) {
|
||||
VisitEphemeron(ephemeron.key, ephemeron.value);
|
||||
ProcessEphemeron(ephemeron.key, ephemeron.value);
|
||||
|
||||
if (non_atomic_marking_state()->IsWhite(ephemeron.value)) {
|
||||
key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value));
|
||||
@ -1610,7 +1610,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() {
|
||||
}
|
||||
|
||||
while (weak_objects_.discovered_ephemerons.Pop(kMainThread, &ephemeron)) {
|
||||
VisitEphemeron(ephemeron.key, ephemeron.value);
|
||||
ProcessEphemeron(ephemeron.key, ephemeron.value);
|
||||
|
||||
if (non_atomic_marking_state()->IsWhite(ephemeron.value)) {
|
||||
key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value));
|
||||
@ -1696,7 +1696,7 @@ void MarkCompactCollector::ProcessMarkingWorklistInternal() {
|
||||
}
|
||||
}
|
||||
|
||||
bool MarkCompactCollector::VisitEphemeron(HeapObject key, HeapObject value) {
|
||||
bool MarkCompactCollector::ProcessEphemeron(HeapObject key, HeapObject value) {
|
||||
if (marking_state()->IsBlackOrGrey(key)) {
|
||||
if (marking_state()->WhiteToGrey(value)) {
|
||||
marking_worklist()->Push(value);
|
||||
|
@ -765,7 +765,7 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
|
||||
|
||||
// Implements ephemeron semantics: Marks value if key is already reachable.
|
||||
// Returns true if value was actually marked.
|
||||
bool VisitEphemeron(HeapObject key, HeapObject value);
|
||||
bool ProcessEphemeron(HeapObject key, HeapObject value);
|
||||
|
||||
// Marks ephemerons and drains marking worklist iteratively
|
||||
// until a fixpoint is reached.
|
||||
|
@ -149,6 +149,16 @@ DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers(
|
||||
HeapObject::RawField(obj, end_offset));
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
DISABLE_CFI_PERF void BodyDescriptorBase::IterateEphemeron(HeapObject obj,
|
||||
int index,
|
||||
int key_offset,
|
||||
int value_offset,
|
||||
ObjectVisitor* v) {
|
||||
v->VisitEphemeron(obj, index, HeapObject::RawField(obj, key_offset),
|
||||
HeapObject::RawField(obj, value_offset));
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject obj, int offset,
|
||||
ObjectVisitor* v) {
|
||||
@ -831,10 +841,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case NUMBER_DICTIONARY_TYPE:
|
||||
case SIMPLE_NUMBER_DICTIONARY_TYPE:
|
||||
case STRING_TABLE_TYPE:
|
||||
case EPHEMERON_HASH_TABLE_TYPE:
|
||||
case SCOPE_INFO_TYPE:
|
||||
case SCRIPT_CONTEXT_TABLE_TYPE:
|
||||
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case EPHEMERON_HASH_TABLE_TYPE:
|
||||
return Op::template apply<EphemeronHashTable::BodyDescriptor>(p1, p2, p3,
|
||||
p4);
|
||||
case AWAIT_CONTEXT_TYPE:
|
||||
case BLOCK_CONTEXT_TYPE:
|
||||
case CATCH_CONTEXT_TYPE:
|
||||
@ -1048,6 +1060,34 @@ void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) {
|
||||
BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, *this,
|
||||
object_size, v);
|
||||
}
|
||||
|
||||
class EphemeronHashTable::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
return (offset >= EphemeronHashTable::kHeaderSize);
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
static inline void IterateBody(Map map, HeapObject obj, int object_size,
|
||||
ObjectVisitor* v) {
|
||||
int entries_start = EphemeronHashTable::kHeaderSize +
|
||||
EphemeronHashTable::kElementsStartIndex * kTaggedSize;
|
||||
IteratePointers(obj, EphemeronHashTable::kHeaderSize, entries_start, v);
|
||||
EphemeronHashTable table = EphemeronHashTable::unchecked_cast(obj);
|
||||
int entries = table.Capacity();
|
||||
for (int i = 0; i < entries; ++i) {
|
||||
const int key_index = EphemeronHashTable::EntryToIndex(i);
|
||||
const int value_index = EphemeronHashTable::EntryToValueIndex(i);
|
||||
IterateEphemeron(obj, i, OffsetOfElementAt(key_index),
|
||||
OffsetOfElementAt(value_index), v);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int SizeOf(Map map, HeapObject object) {
|
||||
return object->SizeFromMap(map);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -46,6 +46,10 @@ class BodyDescriptorBase {
|
||||
static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
|
||||
ObjectVisitor* v);
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
|
||||
int value_offset, ObjectVisitor* v);
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
|
||||
int end_offset, ObjectVisitor* v);
|
||||
|
@ -342,6 +342,7 @@ class EphemeronHashTable
|
||||
public:
|
||||
DECL_CAST(EphemeronHashTable)
|
||||
DECL_PRINTER(EphemeronHashTable)
|
||||
class BodyDescriptor;
|
||||
|
||||
protected:
|
||||
friend class MarkCompactCollector;
|
||||
|
@ -119,6 +119,12 @@ class ObjectVisitor {
|
||||
VisitCustomWeakPointers(host, p, p + 1);
|
||||
}
|
||||
|
||||
virtual void VisitEphemeron(HeapObject host, int index, ObjectSlot key,
|
||||
ObjectSlot value) {
|
||||
VisitPointer(host, key);
|
||||
VisitPointer(host, value);
|
||||
}
|
||||
|
||||
// To allow lazy clearing of inline caches the visitor has
|
||||
// a rich interface for iterating over Code objects ...
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user