[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:
Irina Yatsenko 2019-09-18 14:37:20 -07:00 committed by Commit Bot
parent 5097dcb706
commit a0d01b658f
2 changed files with 50 additions and 0 deletions

View File

@ -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);

View File

@ -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;