[heap] GC should not retain filler objects tracked by deferred handles
Added tests for the scenario when the fillers would be evacuated within the new space and when they would be promoted into the old space. The fix is to treat the deferred handles the same as the local ones: call FixStaleLeftTrimmedHandlesVisitor for them. Bug: v8:9739 Change-Id: Idac233716295f53793657164561bb81f8f729065 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1809815 Commit-Queue: Irina Yatsenko <irinayat@microsoft.com> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#63880}
This commit is contained in:
parent
5097dcb706
commit
a0d01b658f
@ -4317,6 +4317,7 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) {
|
||||
FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this);
|
||||
isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor);
|
||||
isolate_->handle_scope_implementer()->Iterate(v);
|
||||
isolate_->IterateDeferredHandles(&left_trim_visitor);
|
||||
isolate_->IterateDeferredHandles(v);
|
||||
v->Synchronize(VisitorSynchronization::kHandleScope);
|
||||
|
||||
|
@ -3666,6 +3666,55 @@ TEST(DeferredHandles) {
|
||||
deferred.Detach();
|
||||
}
|
||||
|
||||
static void TestFillersFromDeferredHandles(bool promote) {
|
||||
// We assume that the fillers can only arise when left-trimming arrays.
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Heap* heap = isolate->heap();
|
||||
v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
|
||||
|
||||
const size_t n = 10;
|
||||
Handle<FixedArray> array = isolate->factory()->NewFixedArray(n);
|
||||
|
||||
if (promote) {
|
||||
// Age the array so it's ready for promotion on next GC.
|
||||
CcTest::CollectGarbage(NEW_SPACE);
|
||||
}
|
||||
CHECK(Heap::InYoungGeneration(*array));
|
||||
|
||||
DeferredHandleScope deferred_scope(isolate);
|
||||
|
||||
// Trim the array three times to different sizes so all kinds of fillers are
|
||||
// created and tracked by the deferred handles.
|
||||
Handle<FixedArrayBase> filler_1 = Handle<FixedArrayBase>(*array, isolate);
|
||||
Handle<FixedArrayBase> filler_2 =
|
||||
Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_1, 1), isolate);
|
||||
Handle<FixedArrayBase> filler_3 =
|
||||
Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_2, 2), isolate);
|
||||
Handle<FixedArrayBase> tail =
|
||||
Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_3, 3), isolate);
|
||||
|
||||
std::unique_ptr<DeferredHandles> deferred_handles(deferred_scope.Detach());
|
||||
|
||||
// GC should retain the trimmed array but drop all of the three fillers.
|
||||
CcTest::CollectGarbage(NEW_SPACE);
|
||||
if (promote) {
|
||||
CHECK(heap->InOldSpace(*tail));
|
||||
} else {
|
||||
CHECK(Heap::InYoungGeneration(*tail));
|
||||
}
|
||||
CHECK_EQ(n - 6, (*tail).length());
|
||||
CHECK(!filler_1->IsHeapObject());
|
||||
CHECK(!filler_2->IsHeapObject());
|
||||
CHECK(!filler_3->IsHeapObject());
|
||||
}
|
||||
|
||||
TEST(DoNotEvacuateFillersFromDeferredHandles) {
|
||||
TestFillersFromDeferredHandles(false /*promote*/);
|
||||
}
|
||||
|
||||
TEST(DoNotPromoteFillersFromDeferredHandles) {
|
||||
TestFillersFromDeferredHandles(true /*promote*/);
|
||||
}
|
||||
|
||||
TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
|
||||
if (!FLAG_incremental_marking) return;
|
||||
|
Loading…
Reference in New Issue
Block a user