2017-03-06 15:19:36 +00:00
|
|
|
// 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/heap/concurrent-marking.h"
|
|
|
|
#include "src/heap/heap-inl.h"
|
|
|
|
#include "src/heap/heap.h"
|
2017-08-11 08:37:26 +00:00
|
|
|
#include "src/heap/mark-compact.h"
|
2020-08-10 14:38:05 +00:00
|
|
|
#include "src/heap/marking-worklist-inl.h"
|
|
|
|
#include "src/heap/marking-worklist.h"
|
2017-06-26 14:47:36 +00:00
|
|
|
#include "src/heap/worklist.h"
|
2020-08-10 14:38:05 +00:00
|
|
|
#include "src/init/v8.h"
|
2017-03-06 15:19:36 +00:00
|
|
|
#include "test/cctest/cctest.h"
|
|
|
|
#include "test/cctest/heap/heap-utils.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
2017-08-11 10:04:47 +00:00
|
|
|
namespace heap {
|
2017-07-17 11:00:33 +00:00
|
|
|
|
2019-10-29 16:20:49 +00:00
|
|
|
void PublishSegment(MarkingWorklist* worklist, HeapObject object) {
|
2020-08-10 14:38:05 +00:00
|
|
|
MarkingWorklist::Local local(worklist);
|
|
|
|
for (size_t i = 0; i <= MarkingWorklist::kSegmentSize; i++) {
|
|
|
|
local.Push(object);
|
2017-07-17 11:00:33 +00:00
|
|
|
}
|
2020-08-10 14:38:05 +00:00
|
|
|
CHECK(local.Pop(&object));
|
2017-07-17 11:00:33 +00:00
|
|
|
}
|
|
|
|
|
2017-03-06 15:19:36 +00:00
|
|
|
TEST(ConcurrentMarking) {
|
2017-04-10 14:22:31 +00:00
|
|
|
if (!i::FLAG_concurrent_marking) return;
|
2017-03-06 15:19:36 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
Heap* heap = CcTest::heap();
|
2017-10-05 14:16:30 +00:00
|
|
|
CcTest::CollectAllGarbage();
|
|
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
2017-10-09 12:33:53 +00:00
|
|
|
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
|
|
|
|
if (collector->sweeping_in_progress()) {
|
|
|
|
collector->EnsureSweepingCompleted();
|
|
|
|
}
|
2017-10-10 10:45:54 +00:00
|
|
|
|
2020-08-10 14:38:05 +00:00
|
|
|
MarkingWorklists marking_worklists;
|
2017-08-11 08:37:26 +00:00
|
|
|
WeakObjects weak_objects;
|
2019-12-03 13:58:10 +00:00
|
|
|
ConcurrentMarking* concurrent_marking =
|
2020-08-10 14:38:05 +00:00
|
|
|
new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
|
|
|
|
PublishSegment(marking_worklists.shared(),
|
2019-12-03 13:58:10 +00:00
|
|
|
ReadOnlyRoots(heap).undefined_value());
|
2020-09-22 12:31:47 +00:00
|
|
|
concurrent_marking->ScheduleTasks();
|
|
|
|
concurrent_marking->Stop(
|
|
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
2017-07-17 11:00:33 +00:00
|
|
|
delete concurrent_marking;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(ConcurrentMarkingReschedule) {
|
|
|
|
if (!i::FLAG_concurrent_marking) return;
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
Heap* heap = CcTest::heap();
|
2017-10-05 14:16:30 +00:00
|
|
|
CcTest::CollectAllGarbage();
|
|
|
|
if (!heap->incremental_marking()->IsStopped()) return;
|
2017-10-09 12:33:53 +00:00
|
|
|
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
|
|
|
|
if (collector->sweeping_in_progress()) {
|
|
|
|
collector->EnsureSweepingCompleted();
|
|
|
|
}
|
|
|
|
|
2020-08-10 14:38:05 +00:00
|
|
|
MarkingWorklists marking_worklists;
|
2017-08-11 08:37:26 +00:00
|
|
|
WeakObjects weak_objects;
|
2019-12-03 13:58:10 +00:00
|
|
|
ConcurrentMarking* concurrent_marking =
|
2020-08-10 14:38:05 +00:00
|
|
|
new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
|
|
|
|
PublishSegment(marking_worklists.shared(),
|
2019-12-03 13:58:10 +00:00
|
|
|
ReadOnlyRoots(heap).undefined_value());
|
2020-09-22 12:31:47 +00:00
|
|
|
concurrent_marking->ScheduleTasks();
|
|
|
|
concurrent_marking->Stop(
|
|
|
|
ConcurrentMarking::StopRequest::COMPLETE_ONGOING_TASKS);
|
2020-08-10 14:38:05 +00:00
|
|
|
PublishSegment(marking_worklists.shared(),
|
2019-12-03 13:58:10 +00:00
|
|
|
ReadOnlyRoots(heap).undefined_value());
|
2020-09-22 12:31:47 +00:00
|
|
|
concurrent_marking->RescheduleTasksIfNeeded();
|
|
|
|
concurrent_marking->Stop(
|
|
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
2018-02-19 10:03:12 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2020-08-10 14:38:05 +00:00
|
|
|
MarkingWorklists marking_worklists;
|
2018-02-19 10:03:12 +00:00
|
|
|
WeakObjects weak_objects;
|
2019-12-03 13:58:10 +00:00
|
|
|
ConcurrentMarking* concurrent_marking =
|
2020-08-10 14:38:05 +00:00
|
|
|
new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
|
2018-02-19 10:03:12 +00:00
|
|
|
for (int i = 0; i < 5000; i++)
|
2020-08-10 14:38:05 +00:00
|
|
|
PublishSegment(marking_worklists.shared(),
|
2019-12-03 13:58:10 +00:00
|
|
|
ReadOnlyRoots(heap).undefined_value());
|
2020-09-22 12:31:47 +00:00
|
|
|
concurrent_marking->ScheduleTasks();
|
|
|
|
concurrent_marking->Stop(ConcurrentMarking::StopRequest::PREEMPT_TASKS);
|
2018-02-19 10:03:12 +00:00
|
|
|
for (int i = 0; i < 5000; i++)
|
2020-08-10 14:38:05 +00:00
|
|
|
PublishSegment(marking_worklists.shared(),
|
2019-12-03 13:58:10 +00:00
|
|
|
ReadOnlyRoots(heap).undefined_value());
|
2020-09-22 12:31:47 +00:00
|
|
|
concurrent_marking->RescheduleTasksIfNeeded();
|
|
|
|
concurrent_marking->Stop(
|
|
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
2017-07-13 13:03:04 +00:00
|
|
|
delete concurrent_marking;
|
|
|
|
}
|
|
|
|
|
2017-10-09 11:23:59 +00:00
|
|
|
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);
|
2020-09-22 12:31:47 +00:00
|
|
|
heap->concurrent_marking()->Stop(
|
|
|
|
ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
|
2017-10-09 11:23:59 +00:00
|
|
|
CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
|
|
|
|
}
|
|
|
|
|
2018-06-13 14:38:59 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2017-08-11 10:04:47 +00:00
|
|
|
} // namespace heap
|
2017-03-06 15:19:36 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|