68a8bdd829
The concurrent marker can now process all objects. This patch also eagerly visits the objects that undergo layout changes. This is because previously such objects were pushed onto the bailout worklist, which is gone now. To preserve the incremental step accounting, the patch introduces a new GC tracer scope called MC_INCREMENTAL_LAYOUT_CHANGE. Bug: v8:8486 Change-Id: Ic1c2f0d4e2ac0602fc945f3258af9624247bd65f Reviewed-on: https://chromium-review.googlesource.com/c/1386486 Commit-Queue: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#58712}
152 lines
5.2 KiB
C++
152 lines
5.2 KiB
C++
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "src/v8.h"
|
|
|
|
#include "src/heap/concurrent-marking.h"
|
|
#include "src/heap/heap-inl.h"
|
|
#include "src/heap/heap.h"
|
|
#include "src/heap/mark-compact.h"
|
|
#include "src/heap/worklist.h"
|
|
#include "test/cctest/cctest.h"
|
|
#include "test/cctest/heap/heap-utils.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace heap {
|
|
|
|
void PublishSegment(ConcurrentMarking::MarkingWorklist* worklist,
|
|
HeapObject object) {
|
|
for (size_t i = 0; i <= ConcurrentMarking::MarkingWorklist::kSegmentCapacity;
|
|
i++) {
|
|
worklist->Push(0, object);
|
|
}
|
|
CHECK(worklist->Pop(0, &object));
|
|
}
|
|
|
|
TEST(ConcurrentMarking) {
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
CcTest::InitializeVM();
|
|
Heap* heap = CcTest::heap();
|
|
CcTest::CollectAllGarbage();
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
|
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
|
|
if (collector->sweeping_in_progress()) {
|
|
collector->EnsureSweepingCompleted();
|
|
}
|
|
|
|
ConcurrentMarking::MarkingWorklist shared, on_hold;
|
|
ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
|
|
WeakObjects weak_objects;
|
|
ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
|
|
heap, &shared, &on_hold, &weak_objects, &embedder_objects);
|
|
PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
|
|
concurrent_marking->ScheduleTasks();
|
|
concurrent_marking->Stop(
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
|
delete concurrent_marking;
|
|
}
|
|
|
|
TEST(ConcurrentMarkingReschedule) {
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
CcTest::InitializeVM();
|
|
Heap* heap = CcTest::heap();
|
|
CcTest::CollectAllGarbage();
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
|
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
|
|
if (collector->sweeping_in_progress()) {
|
|
collector->EnsureSweepingCompleted();
|
|
}
|
|
|
|
ConcurrentMarking::MarkingWorklist shared, on_hold;
|
|
ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
|
|
WeakObjects weak_objects;
|
|
ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
|
|
heap, &shared, &on_hold, &weak_objects, &embedder_objects);
|
|
PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
|
|
concurrent_marking->ScheduleTasks();
|
|
concurrent_marking->Stop(
|
|
ConcurrentMarking::StopRequest::COMPLETE_ONGOING_TASKS);
|
|
PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
|
|
concurrent_marking->RescheduleTasksIfNeeded();
|
|
concurrent_marking->Stop(
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
|
delete concurrent_marking;
|
|
}
|
|
|
|
TEST(ConcurrentMarkingPreemptAndReschedule) {
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
CcTest::InitializeVM();
|
|
Heap* heap = CcTest::heap();
|
|
CcTest::CollectAllGarbage();
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
|
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
|
|
if (collector->sweeping_in_progress()) {
|
|
collector->EnsureSweepingCompleted();
|
|
}
|
|
|
|
ConcurrentMarking::MarkingWorklist shared, on_hold;
|
|
ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
|
|
WeakObjects weak_objects;
|
|
ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
|
|
heap, &shared, &on_hold, &weak_objects, &embedder_objects);
|
|
for (int i = 0; i < 5000; i++)
|
|
PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
|
|
concurrent_marking->ScheduleTasks();
|
|
concurrent_marking->Stop(ConcurrentMarking::StopRequest::PREEMPT_TASKS);
|
|
for (int i = 0; i < 5000; i++)
|
|
PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
|
|
concurrent_marking->RescheduleTasksIfNeeded();
|
|
concurrent_marking->Stop(
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
|
delete concurrent_marking;
|
|
}
|
|
|
|
TEST(ConcurrentMarkingMarkedBytes) {
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
CcTest::InitializeVM();
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
Heap* heap = CcTest::heap();
|
|
HandleScope sc(isolate);
|
|
Handle<FixedArray> root = isolate->factory()->NewFixedArray(1000000);
|
|
CcTest::CollectAllGarbage();
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
|
heap::SimulateIncrementalMarking(heap, false);
|
|
heap->concurrent_marking()->Stop(
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
|
CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
|
|
}
|
|
|
|
UNINITIALIZED_TEST(ConcurrentMarkingStoppedOnTeardown) {
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
|
|
v8::Isolate::CreateParams create_params;
|
|
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
|
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
|
|
|
{
|
|
Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
|
|
Factory* factory = i_isolate->factory();
|
|
|
|
v8::Isolate::Scope isolate_scope(isolate);
|
|
v8::HandleScope handle_scope(isolate);
|
|
v8::Context::New(isolate)->Enter();
|
|
|
|
for (int i = 0; i < 10000; i++) {
|
|
factory->NewJSWeakMap();
|
|
}
|
|
|
|
Heap* heap = i_isolate->heap();
|
|
heap::SimulateIncrementalMarking(heap, false);
|
|
}
|
|
|
|
isolate->Dispose();
|
|
}
|
|
|
|
} // namespace heap
|
|
} // namespace internal
|
|
} // namespace v8
|