Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include <stdlib.h>
6 :
7 : #include "src/v8.h"
8 :
9 : #include "src/heap/concurrent-marking.h"
10 : #include "src/heap/heap-inl.h"
11 : #include "src/heap/heap.h"
12 : #include "src/heap/mark-compact.h"
13 : #include "src/heap/worklist.h"
14 : #include "test/cctest/cctest.h"
15 : #include "test/cctest/heap/heap-utils.h"
16 :
17 : namespace v8 {
18 : namespace internal {
19 : namespace heap {
20 :
21 50015 : void PublishSegment(ConcurrentMarking::MarkingWorklist* worklist,
22 : HeapObject object) {
23 6551965 : for (size_t i = 0; i <= ConcurrentMarking::MarkingWorklist::kSegmentCapacity;
24 : i++) {
25 3250975 : worklist->Push(0, object);
26 : }
27 50015 : CHECK(worklist->Pop(0, &object));
28 50015 : }
29 :
30 26644 : TEST(ConcurrentMarking) {
31 5 : if (!i::FLAG_concurrent_marking) return;
32 5 : CcTest::InitializeVM();
33 5 : Heap* heap = CcTest::heap();
34 5 : CcTest::CollectAllGarbage();
35 5 : if (!heap->incremental_marking()->IsStopped()) return;
36 5 : MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
37 5 : if (collector->sweeping_in_progress()) {
38 5 : collector->EnsureSweepingCompleted();
39 : }
40 :
41 5 : ConcurrentMarking::MarkingWorklist shared, on_hold;
42 5 : ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
43 10 : WeakObjects weak_objects;
44 : ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
45 5 : heap, &shared, &on_hold, &weak_objects, &embedder_objects);
46 5 : PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
47 5 : concurrent_marking->ScheduleTasks();
48 : concurrent_marking->Stop(
49 5 : ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
50 5 : delete concurrent_marking;
51 : }
52 :
53 26644 : TEST(ConcurrentMarkingReschedule) {
54 5 : if (!i::FLAG_concurrent_marking) return;
55 5 : CcTest::InitializeVM();
56 5 : Heap* heap = CcTest::heap();
57 5 : CcTest::CollectAllGarbage();
58 5 : if (!heap->incremental_marking()->IsStopped()) return;
59 5 : MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
60 5 : if (collector->sweeping_in_progress()) {
61 5 : collector->EnsureSweepingCompleted();
62 : }
63 :
64 5 : ConcurrentMarking::MarkingWorklist shared, on_hold;
65 5 : ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
66 10 : WeakObjects weak_objects;
67 : ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
68 5 : heap, &shared, &on_hold, &weak_objects, &embedder_objects);
69 5 : PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
70 5 : concurrent_marking->ScheduleTasks();
71 : concurrent_marking->Stop(
72 5 : ConcurrentMarking::StopRequest::COMPLETE_ONGOING_TASKS);
73 5 : PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
74 5 : concurrent_marking->RescheduleTasksIfNeeded();
75 : concurrent_marking->Stop(
76 5 : ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
77 5 : delete concurrent_marking;
78 : }
79 :
80 26644 : TEST(ConcurrentMarkingPreemptAndReschedule) {
81 5 : if (!i::FLAG_concurrent_marking) return;
82 5 : CcTest::InitializeVM();
83 5 : Heap* heap = CcTest::heap();
84 5 : CcTest::CollectAllGarbage();
85 5 : if (!heap->incremental_marking()->IsStopped()) return;
86 5 : MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
87 5 : if (collector->sweeping_in_progress()) {
88 5 : collector->EnsureSweepingCompleted();
89 : }
90 :
91 5 : ConcurrentMarking::MarkingWorklist shared, on_hold;
92 5 : ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
93 10 : WeakObjects weak_objects;
94 : ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
95 5 : heap, &shared, &on_hold, &weak_objects, &embedder_objects);
96 50005 : for (int i = 0; i < 5000; i++)
97 25000 : PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
98 5 : concurrent_marking->ScheduleTasks();
99 5 : concurrent_marking->Stop(ConcurrentMarking::StopRequest::PREEMPT_TASKS);
100 50005 : for (int i = 0; i < 5000; i++)
101 25000 : PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
102 5 : concurrent_marking->RescheduleTasksIfNeeded();
103 : concurrent_marking->Stop(
104 5 : ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
105 5 : delete concurrent_marking;
106 : }
107 :
108 26644 : TEST(ConcurrentMarkingMarkedBytes) {
109 5 : if (!i::FLAG_concurrent_marking) return;
110 5 : CcTest::InitializeVM();
111 : Isolate* isolate = CcTest::i_isolate();
112 5 : Heap* heap = CcTest::heap();
113 : HandleScope sc(isolate);
114 5 : Handle<FixedArray> root = isolate->factory()->NewFixedArray(1000000);
115 5 : CcTest::CollectAllGarbage();
116 5 : if (!heap->incremental_marking()->IsStopped()) return;
117 5 : heap::SimulateIncrementalMarking(heap, false);
118 : heap->concurrent_marking()->Stop(
119 5 : ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
120 15 : CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
121 : }
122 :
123 26644 : UNINITIALIZED_TEST(ConcurrentMarkingStoppedOnTeardown) {
124 5 : if (!i::FLAG_concurrent_marking) return;
125 :
126 : v8::Isolate::CreateParams create_params;
127 5 : create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
128 5 : v8::Isolate* isolate = v8::Isolate::New(create_params);
129 :
130 : {
131 : Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
132 : Factory* factory = i_isolate->factory();
133 :
134 : v8::Isolate::Scope isolate_scope(isolate);
135 10 : v8::HandleScope handle_scope(isolate);
136 10 : v8::Context::New(isolate)->Enter();
137 :
138 100005 : for (int i = 0; i < 10000; i++) {
139 50000 : factory->NewJSWeakMap();
140 : }
141 :
142 : Heap* heap = i_isolate->heap();
143 5 : heap::SimulateIncrementalMarking(heap, false);
144 : }
145 :
146 5 : isolate->Dispose();
147 : }
148 :
149 : } // namespace heap
150 : } // namespace internal
151 79917 : } // namespace v8
|