Commit 682947f8 authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[heap] Clear markbits for evacuated objects in ReRecordPage

Move clearing of markbits in the evacuated area into ReRecordPage,
which also resets all other metadata for that memory area.

Since this case is now handled in ReRecordPage, all other use cases
can delete markbits for the whole chunk and allows the
VisitBlackObjects* methods to not deal with markbits anymore.

Bug: chromium:1359294, v8:12578
Change-Id: Ic98debe04efb7f415cf06efb58af0f728071aa65
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3879499Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83072}
parent 2a8f5628
......@@ -4331,22 +4331,20 @@ void FullEvacuator::RawEvacuatePage(MemoryChunk* chunk, intptr_t* live_bytes) {
#if DEBUG
new_space_visitor_.DisableAbortEvacuationAtAddress(chunk);
#endif // DEBUG
LiveObjectVisitor::VisitBlackObjectsNoFail(
chunk, marking_state, &new_space_visitor_,
LiveObjectVisitor::kClearMarkbits);
LiveObjectVisitor::VisitBlackObjectsNoFail(chunk, marking_state,
&new_space_visitor_);
marking_state->ClearLiveness(chunk);
break;
case kPageNewToOld:
LiveObjectVisitor::VisitBlackObjectsNoFail(
chunk, marking_state, &new_to_old_page_visitor_,
LiveObjectVisitor::kKeepMarking);
LiveObjectVisitor::VisitBlackObjectsNoFail(chunk, marking_state,
&new_to_old_page_visitor_);
new_to_old_page_visitor_.account_moved_bytes(
marking_state->live_bytes(chunk));
break;
case kPageNewToNew:
DCHECK(!v8_flags.minor_mc);
LiveObjectVisitor::VisitBlackObjectsNoFail(
chunk, marking_state, &new_to_new_page_visitor_,
LiveObjectVisitor::kKeepMarking);
LiveObjectVisitor::VisitBlackObjectsNoFail(chunk, marking_state,
&new_to_new_page_visitor_);
new_to_new_page_visitor_.account_moved_bytes(
marking_state->live_bytes(chunk));
break;
......@@ -4358,9 +4356,10 @@ void FullEvacuator::RawEvacuatePage(MemoryChunk* chunk, intptr_t* live_bytes) {
old_space_visitor_.SetUpAbortEvacuationAtAddress(chunk);
#endif // DEBUG
const bool success = LiveObjectVisitor::VisitBlackObjects(
chunk, marking_state, &old_space_visitor_,
LiveObjectVisitor::kClearMarkbits, &failed_object);
if (!success) {
chunk, marking_state, &old_space_visitor_, &failed_object);
if (success) {
marking_state->ClearLiveness(chunk);
} else {
if (v8_flags.crash_on_aborted_evacuation) {
heap_->FatalProcessOutOfMemory("FullEvacuator::RawEvacuatePage");
} else {
......@@ -4611,15 +4610,13 @@ class EvacuationWeakObjectRetainer : public WeakObjectRetainer {
void MarkCompactCollector::RecordLiveSlotsOnPage(Page* page) {
EvacuateRecordOnlyVisitor visitor(heap());
LiveObjectVisitor::VisitBlackObjectsNoFail(page, non_atomic_marking_state(),
&visitor,
LiveObjectVisitor::kKeepMarking);
&visitor);
}
template <class Visitor, typename MarkingState>
bool LiveObjectVisitor::VisitBlackObjects(MemoryChunk* chunk,
MarkingState* marking_state,
Visitor* visitor,
IterationMode iteration_mode,
HeapObject* failed_object) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"),
"LiveObjectVisitor::VisitBlackObjects");
......@@ -4627,26 +4624,17 @@ bool LiveObjectVisitor::VisitBlackObjects(MemoryChunk* chunk,
LiveObjectRange<kBlackObjects>(chunk, marking_state->bitmap(chunk))) {
HeapObject const object = object_and_size.first;
if (!visitor->Visit(object, object_and_size.second)) {
if (iteration_mode == kClearMarkbits) {
marking_state->bitmap(chunk)->ClearRange(
chunk->AddressToMarkbitIndex(chunk->area_start()),
chunk->AddressToMarkbitIndex(object.address()));
*failed_object = object;
}
*failed_object = object;
return false;
}
}
if (iteration_mode == kClearMarkbits) {
marking_state->ClearLiveness(chunk);
}
return true;
}
template <class Visitor, typename MarkingState>
void LiveObjectVisitor::VisitBlackObjectsNoFail(MemoryChunk* chunk,
MarkingState* marking_state,
Visitor* visitor,
IterationMode iteration_mode) {
Visitor* visitor) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"),
"LiveObjectVisitor::VisitBlackObjectsNoFail");
if (chunk->IsLargePage()) {
......@@ -4666,9 +4654,6 @@ void LiveObjectVisitor::VisitBlackObjectsNoFail(MemoryChunk* chunk,
DCHECK(success);
}
}
if (iteration_mode == kClearMarkbits) {
marking_state->ClearLiveness(chunk);
}
}
template <typename MarkingState>
......@@ -5422,6 +5407,11 @@ void ReRecordPage(Heap* heap,
// Aborted compaction page. We have to record slots here, since we
// might not have recorded them in first place.
// Remove mark bits in evacuated area.
marking_state->bitmap(page)->ClearRange(
page->AddressToMarkbitIndex(page->area_start()),
page->AddressToMarkbitIndex(failed_start));
// Remove outdated slots.
RememberedSet<OLD_TO_NEW>::RemoveRange(page, page->address(), failed_start,
SlotSet::FREE_EMPTY_BUCKETS);
......@@ -5448,8 +5438,8 @@ void ReRecordPage(Heap* heap,
LiveObjectVisitor::RecomputeLiveBytes(page, marking_state);
// Re-record slots.
EvacuateRecordOnlyVisitor record_visitor(heap);
LiveObjectVisitor::VisitBlackObjectsNoFail(
page, marking_state, &record_visitor, LiveObjectVisitor::kKeepMarking);
LiveObjectVisitor::VisitBlackObjectsNoFail(page, marking_state,
&record_visitor);
// Array buffers will be processed during pointer updating.
}
......@@ -6646,8 +6636,7 @@ void YoungGenerationEvacuator::RawEvacuatePage(MemoryChunk* chunk,
*live_bytes = marking_state->live_bytes(chunk);
DCHECK_EQ(kPageNewToOld, ComputeEvacuationMode(chunk));
LiveObjectVisitor::VisitBlackObjectsNoFail(chunk, marking_state,
&new_to_old_page_visitor_,
LiveObjectVisitor::kKeepMarking);
&new_to_old_page_visitor_);
new_to_old_page_visitor_.account_moved_bytes(
marking_state->live_bytes(chunk));
if (!chunk->IsLargePage()) {
......
......@@ -156,25 +156,17 @@ class LiveObjectRange {
class LiveObjectVisitor : AllStatic {
public:
enum IterationMode {
kKeepMarking,
kClearMarkbits,
};
// Visits black objects on a MemoryChunk until the Visitor returns |false| for
// an object. If IterationMode::kClearMarkbits is passed the markbits and
// slots for visited objects are cleared for each successfully visited object.
// an object.
template <class Visitor, typename MarkingState>
static bool VisitBlackObjects(MemoryChunk* chunk, MarkingState* state,
Visitor* visitor, IterationMode iteration_mode,
HeapObject* failed_object);
Visitor* visitor, HeapObject* failed_object);
// Visits black objects on a MemoryChunk. The visitor is not allowed to fail
// visitation for an object.
template <class Visitor, typename MarkingState>
static void VisitBlackObjectsNoFail(MemoryChunk* chunk, MarkingState* state,
Visitor* visitor,
IterationMode iteration_mode);
Visitor* visitor);
template <typename MarkingState>
static void RecomputeLiveBytes(MemoryChunk* chunk, MarkingState* state);
......
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