OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "src/heap/array-buffer-tracker.h" | |
6 #include "test/cctest/cctest.h" | |
7 #include "test/cctest/heap/utils-inl.h" | |
8 | |
9 namespace { | |
10 | |
11 typedef i::ArrayBufferTracker Tracker; | |
12 | |
13 void VerifyTrackedInNewSpace(Tracker* tracker, i::JSArrayBuffer* buf) { | |
14 CHECK(tracker->IsTrackedInYoungGenForTesting(buf)); | |
15 CHECK(!tracker->IsTrackedInOldGenForTesting(buf)); | |
16 } | |
17 | |
18 void VerifyTrackedInOldSpace(Tracker* tracker, i::JSArrayBuffer* buf) { | |
19 CHECK(!tracker->IsTrackedInYoungGenForTesting(buf)); | |
20 CHECK(tracker->IsTrackedInOldGenForTesting(buf)); | |
21 } | |
22 | |
23 void VerifyUntracked(Tracker* tracker, i::JSArrayBuffer* buf) { | |
24 CHECK(!tracker->IsTrackedInYoungGenForTesting(buf)); | |
25 CHECK(!tracker->IsTrackedInOldGenForTesting(buf)); | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 namespace v8 { | |
31 namespace internal { | |
32 | |
33 // The following tests make sure that JSArrayBuffer tracking works expected when | |
34 // moving the objects through various spaces during GC phases. | |
35 | |
36 TEST(ArrayBuffer_OnlyMC) { | |
37 CcTest::InitializeVM(); | |
38 LocalContext env; | |
39 v8::Isolate* isolate = env->GetIsolate(); | |
40 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
41 Tracker* tracker = heap->array_buffer_tracker(); | |
42 | |
43 JSArrayBuffer* raw_ab = nullptr; | |
44 { | |
45 v8::HandleScope handle_scope(isolate); | |
46 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
47 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
48 VerifyTrackedInNewSpace(tracker, *buf); | |
49 heap->CollectGarbage(OLD_SPACE); | |
50 VerifyTrackedInNewSpace(tracker, *buf); | |
51 heap->CollectGarbage(OLD_SPACE); | |
52 VerifyTrackedInOldSpace(tracker, *buf); | |
53 raw_ab = *buf; | |
54 } | |
55 heap->CollectGarbage(OLD_SPACE); | |
56 VerifyUntracked(tracker, raw_ab); | |
57 } | |
58 | |
59 TEST(ArrayBuffer_OnlyScavenge) { | |
60 CcTest::InitializeVM(); | |
61 LocalContext env; | |
62 v8::Isolate* isolate = env->GetIsolate(); | |
63 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
64 Tracker* tracker = heap->array_buffer_tracker(); | |
65 | |
66 JSArrayBuffer* raw_ab = nullptr; | |
67 { | |
68 v8::HandleScope handle_scope(isolate); | |
69 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
70 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
71 VerifyTrackedInNewSpace(tracker, *buf); | |
72 heap->CollectGarbage(NEW_SPACE); | |
73 VerifyTrackedInNewSpace(tracker, *buf); | |
74 heap->CollectGarbage(NEW_SPACE); | |
75 VerifyTrackedInOldSpace(tracker, *buf); | |
76 heap->CollectGarbage(NEW_SPACE); | |
77 VerifyTrackedInOldSpace(tracker, *buf); | |
78 raw_ab = *buf; | |
79 } | |
80 heap->CollectGarbage(NEW_SPACE); | |
81 VerifyTrackedInOldSpace(tracker, raw_ab); | |
82 } | |
83 | |
84 TEST(ArrayBuffer_ScavengeAndMC) { | |
85 CcTest::InitializeVM(); | |
86 LocalContext env; | |
87 v8::Isolate* isolate = env->GetIsolate(); | |
88 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
89 Tracker* tracker = heap->array_buffer_tracker(); | |
90 | |
91 JSArrayBuffer* raw_ab = nullptr; | |
92 { | |
93 v8::HandleScope handle_scope(isolate); | |
94 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
95 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
96 VerifyTrackedInNewSpace(tracker, *buf); | |
97 heap->CollectGarbage(NEW_SPACE); | |
98 VerifyTrackedInNewSpace(tracker, *buf); | |
99 heap->CollectGarbage(NEW_SPACE); | |
100 VerifyTrackedInOldSpace(tracker, *buf); | |
101 heap->CollectGarbage(OLD_SPACE); | |
102 VerifyTrackedInOldSpace(tracker, *buf); | |
103 heap->CollectGarbage(NEW_SPACE); | |
104 VerifyTrackedInOldSpace(tracker, *buf); | |
105 raw_ab = *buf; | |
106 } | |
107 heap->CollectGarbage(NEW_SPACE); | |
108 VerifyTrackedInOldSpace(tracker, raw_ab); | |
109 heap->CollectGarbage(OLD_SPACE); | |
110 VerifyUntracked(tracker, raw_ab); | |
111 } | |
112 | |
113 TEST(ArrayBuffer_IterateNotYetDiscoveredEntries) { | |
114 CcTest::InitializeVM(); | |
115 LocalContext env; | |
116 v8::Isolate* isolate = env->GetIsolate(); | |
117 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
118 Tracker* tracker = heap->array_buffer_tracker(); | |
119 | |
120 v8::HandleScope handle_scope(isolate); | |
121 Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, 100); | |
122 Handle<JSArrayBuffer> buf1 = v8::Utils::OpenHandle(*ab1); | |
123 VerifyTrackedInNewSpace(tracker, *buf1); | |
124 heap->CollectGarbage(NEW_SPACE); | |
125 heap->CollectGarbage(NEW_SPACE); | |
126 VerifyTrackedInOldSpace(tracker, *buf1); | |
127 | |
128 Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, 100); | |
129 Handle<JSArrayBuffer> buf2 = v8::Utils::OpenHandle(*ab2); | |
130 Page* interesting_page = Page::FromAddress(buf2->address()); | |
131 bool found_ab1 = false; | |
132 bool found_ab2 = false; | |
133 tracker->IterateNotYetDiscoveredEntries( | |
134 Tracker::kNewSpace, reinterpret_cast<Tracker::Key>(interesting_page), | |
135 reinterpret_cast<Tracker::Key>(interesting_page + Page::kPageSize), | |
136 [buf1, buf2, &found_ab1, &found_ab2](Tracker::Key key) { | |
137 if (key == buf1->address()) { | |
138 found_ab1 = true; | |
139 } | |
140 if (key == buf2->address()) { | |
141 found_ab2 = true; | |
142 } | |
143 return Tracker::kKeepEntry; | |
144 }); | |
145 CHECK(!found_ab1); | |
146 CHECK(found_ab2); | |
147 } | |
148 | |
149 TEST(ArrayBuffer_Compaction) { | |
150 FLAG_manual_evacuation_candidates_selection = true; | |
151 CcTest::InitializeVM(); | |
152 LocalContext env; | |
153 v8::Isolate* isolate = env->GetIsolate(); | |
154 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
155 AbandonCurrentlyFreeMemory(heap->old_space()); | |
156 Tracker* tracker = heap->array_buffer_tracker(); | |
157 | |
158 v8::HandleScope handle_scope(isolate); | |
159 Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, 100); | |
160 Handle<JSArrayBuffer> buf1 = v8::Utils::OpenHandle(*ab1); | |
161 VerifyTrackedInNewSpace(tracker, *buf1); | |
162 heap->CollectGarbage(NEW_SPACE); | |
163 heap->CollectGarbage(NEW_SPACE); | |
164 | |
165 Page* page_before_gc = Page::FromAddress(buf1->address()); | |
166 page_before_gc->SetFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); | |
167 VerifyTrackedInOldSpace(tracker, *buf1); | |
168 | |
169 heap->CollectAllGarbage(); | |
170 | |
171 Page* page_after_gc = Page::FromAddress(buf1->address()); | |
172 VerifyTrackedInOldSpace(tracker, *buf1); | |
173 | |
174 CHECK_NE(page_before_gc, page_after_gc); | |
175 } | |
176 | |
177 } // namespace internal | |
178 } // namespace v8 | |
OLD | NEW |