Commit 7a6e829b authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[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/+/1508673Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60119}
parent d6465298
...@@ -508,7 +508,7 @@ class ConcurrentMarkingVisitor final ...@@ -508,7 +508,7 @@ class ConcurrentMarkingVisitor final
// Implements ephemeron semantics: Marks value if key is already reachable. // Implements ephemeron semantics: Marks value if key is already reachable.
// Returns true if value was actually marked. // 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_.IsBlackOrGrey(key)) {
if (marking_state_.WhiteToGrey(value)) { if (marking_state_.WhiteToGrey(value)) {
shared_.Push(value); shared_.Push(value);
...@@ -776,7 +776,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) { ...@@ -776,7 +776,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
Ephemeron ephemeron; Ephemeron ephemeron;
while (weak_objects_->current_ephemerons.Pop(task_id, &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; ephemeron_marked = true;
} }
} }
...@@ -821,7 +821,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) { ...@@ -821,7 +821,7 @@ void ConcurrentMarking::Run(int task_id, TaskState* task_state) {
Ephemeron ephemeron; Ephemeron ephemeron;
while (weak_objects_->discovered_ephemerons.Pop(task_id, &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; ephemeron_marked = true;
} }
} }
......
...@@ -1547,7 +1547,7 @@ bool MarkCompactCollector::ProcessEphemerons() { ...@@ -1547,7 +1547,7 @@ bool MarkCompactCollector::ProcessEphemerons() {
// Drain current_ephemerons and push ephemerons where key and value are still // Drain current_ephemerons and push ephemerons where key and value are still
// unreachable into next_ephemerons. // unreachable into next_ephemerons.
while (weak_objects_.current_ephemerons.Pop(kMainThread, &ephemeron)) { while (weak_objects_.current_ephemerons.Pop(kMainThread, &ephemeron)) {
if (VisitEphemeron(ephemeron.key, ephemeron.value)) { if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
ephemeron_marked = true; ephemeron_marked = true;
} }
} }
...@@ -1560,7 +1560,7 @@ bool MarkCompactCollector::ProcessEphemerons() { ...@@ -1560,7 +1560,7 @@ bool MarkCompactCollector::ProcessEphemerons() {
// before) and push ephemerons where key and value are still unreachable into // before) and push ephemerons where key and value are still unreachable into
// next_ephemerons. // next_ephemerons.
while (weak_objects_.discovered_ephemerons.Pop(kMainThread, &ephemeron)) { while (weak_objects_.discovered_ephemerons.Pop(kMainThread, &ephemeron)) {
if (VisitEphemeron(ephemeron.key, ephemeron.value)) { if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
ephemeron_marked = true; ephemeron_marked = true;
} }
} }
...@@ -1583,7 +1583,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() { ...@@ -1583,7 +1583,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() {
weak_objects_.current_ephemerons.Swap(weak_objects_.next_ephemerons); weak_objects_.current_ephemerons.Swap(weak_objects_.next_ephemerons);
while (weak_objects_.current_ephemerons.Pop(kMainThread, &ephemeron)) { 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)) { if (non_atomic_marking_state()->IsWhite(ephemeron.value)) {
key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value)); key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value));
...@@ -1610,7 +1610,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() { ...@@ -1610,7 +1610,7 @@ void MarkCompactCollector::ProcessEphemeronsLinear() {
} }
while (weak_objects_.discovered_ephemerons.Pop(kMainThread, &ephemeron)) { 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)) { if (non_atomic_marking_state()->IsWhite(ephemeron.value)) {
key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value)); key_to_values.insert(std::make_pair(ephemeron.key, ephemeron.value));
...@@ -1696,7 +1696,7 @@ void MarkCompactCollector::ProcessMarkingWorklistInternal() { ...@@ -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()->IsBlackOrGrey(key)) {
if (marking_state()->WhiteToGrey(value)) { if (marking_state()->WhiteToGrey(value)) {
marking_worklist()->Push(value); marking_worklist()->Push(value);
......
...@@ -765,7 +765,7 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -765,7 +765,7 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
// Implements ephemeron semantics: Marks value if key is already reachable. // Implements ephemeron semantics: Marks value if key is already reachable.
// Returns true if value was actually marked. // 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 // Marks ephemerons and drains marking worklist iteratively
// until a fixpoint is reached. // until a fixpoint is reached.
......
...@@ -149,6 +149,16 @@ DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers( ...@@ -149,6 +149,16 @@ DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers(
HeapObject::RawField(obj, end_offset)); 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> template <typename ObjectVisitor>
void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject obj, int offset, void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject obj, int offset,
ObjectVisitor* v) { ObjectVisitor* v) {
...@@ -831,10 +841,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { ...@@ -831,10 +841,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case NUMBER_DICTIONARY_TYPE: case NUMBER_DICTIONARY_TYPE:
case SIMPLE_NUMBER_DICTIONARY_TYPE: case SIMPLE_NUMBER_DICTIONARY_TYPE:
case STRING_TABLE_TYPE: case STRING_TABLE_TYPE:
case EPHEMERON_HASH_TABLE_TYPE:
case SCOPE_INFO_TYPE: case SCOPE_INFO_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE: case SCRIPT_CONTEXT_TABLE_TYPE:
return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4); 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 AWAIT_CONTEXT_TYPE:
case BLOCK_CONTEXT_TYPE: case BLOCK_CONTEXT_TYPE:
case CATCH_CONTEXT_TYPE: case CATCH_CONTEXT_TYPE:
...@@ -1048,6 +1060,34 @@ void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) { ...@@ -1048,6 +1060,34 @@ void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) {
BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, *this, BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, *this,
object_size, v); 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 internal
} // namespace v8 } // namespace v8
......
...@@ -46,6 +46,10 @@ class BodyDescriptorBase { ...@@ -46,6 +46,10 @@ class BodyDescriptorBase {
static inline void IterateCustomWeakPointer(HeapObject obj, int offset, static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
ObjectVisitor* v); ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
int value_offset, ObjectVisitor* v);
template <typename ObjectVisitor> template <typename ObjectVisitor>
static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset, static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
int end_offset, ObjectVisitor* v); int end_offset, ObjectVisitor* v);
......
...@@ -342,6 +342,7 @@ class EphemeronHashTable ...@@ -342,6 +342,7 @@ class EphemeronHashTable
public: public:
DECL_CAST(EphemeronHashTable) DECL_CAST(EphemeronHashTable)
DECL_PRINTER(EphemeronHashTable) DECL_PRINTER(EphemeronHashTable)
class BodyDescriptor;
protected: protected:
friend class MarkCompactCollector; friend class MarkCompactCollector;
......
...@@ -119,6 +119,12 @@ class ObjectVisitor { ...@@ -119,6 +119,12 @@ class ObjectVisitor {
VisitCustomWeakPointers(host, p, p + 1); 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 // To allow lazy clearing of inline caches the visitor has
// a rich interface for iterating over Code objects ... // a rich interface for iterating over Code objects ...
......
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