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-inl.h" | |
6 #include "src/heap/array-buffer-tracker.h" | |
7 #include "test/cctest/cctest.h" | |
8 #include "test/cctest/heap/heap-utils.h" | |
9 | |
10 namespace { | |
11 | |
12 typedef i::LocalArrayBufferTracker LocalTracker; | |
13 | |
14 void VerifyTrackedInNewSpace(i::JSArrayBuffer* buf) { | |
15 CHECK(i::Page::FromAddress(buf->address())->InNewSpace()); | |
16 CHECK(i::Page::FromAddress(buf->address())->local_tracker()->IsTracked(buf)); | |
17 } | |
18 | |
19 void VerifyTrackedInOldSpace(i::JSArrayBuffer* buf) { | |
20 CHECK(!i::Page::FromAddress(buf->address())->InNewSpace()); | |
21 CHECK(i::Page::FromAddress(buf->address())->local_tracker()->IsTracked(buf)); | |
22 } | |
23 | |
24 void VerifyUntracked(i::JSArrayBuffer* buf) { | |
25 CHECK(!i::Page::FromAddress(buf->address())->local_tracker()->IsTracked(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 | |
42 JSArrayBuffer* raw_ab = nullptr; | |
43 { | |
44 v8::HandleScope handle_scope(isolate); | |
45 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
46 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
47 VerifyTrackedInNewSpace(*buf); | |
48 heap::GcAndSweep(heap, OLD_SPACE); | |
49 VerifyTrackedInNewSpace(*buf); | |
50 heap::GcAndSweep(heap, OLD_SPACE); | |
51 VerifyTrackedInOldSpace(*buf); | |
52 raw_ab = *buf; | |
53 } | |
54 // 2 GCs are needed because we promote to old space as live, meaining that | |
55 // we will survive one GC. | |
56 heap::GcAndSweep(heap, OLD_SPACE); | |
57 heap::GcAndSweep(heap, OLD_SPACE); | |
58 VerifyUntracked(raw_ab); | |
59 } | |
60 | |
61 TEST(ArrayBuffer_OnlyScavenge) { | |
62 CcTest::InitializeVM(); | |
63 LocalContext env; | |
64 v8::Isolate* isolate = env->GetIsolate(); | |
65 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
66 | |
67 JSArrayBuffer* raw_ab = nullptr; | |
68 { | |
69 v8::HandleScope handle_scope(isolate); | |
70 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
71 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
72 VerifyTrackedInNewSpace(*buf); | |
73 heap::GcAndSweep(heap, NEW_SPACE); | |
74 VerifyTrackedInNewSpace(*buf); | |
75 heap::GcAndSweep(heap, NEW_SPACE); | |
76 VerifyTrackedInOldSpace(*buf); | |
77 heap::GcAndSweep(heap, NEW_SPACE); | |
78 VerifyTrackedInOldSpace(*buf); | |
79 raw_ab = *buf; | |
80 } | |
81 // 2 GCs are needed because we promote to old space as live, meaning that | |
82 // we will survive one GC. | |
83 heap::GcAndSweep(heap, OLD_SPACE); | |
84 heap::GcAndSweep(heap, OLD_SPACE); | |
85 VerifyUntracked(raw_ab); | |
86 } | |
87 | |
88 TEST(ArrayBuffer_ScavengeAndMC) { | |
89 CcTest::InitializeVM(); | |
90 LocalContext env; | |
91 v8::Isolate* isolate = env->GetIsolate(); | |
92 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
93 | |
94 JSArrayBuffer* raw_ab = nullptr; | |
95 { | |
96 v8::HandleScope handle_scope(isolate); | |
97 Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 100); | |
98 Handle<JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab); | |
99 VerifyTrackedInNewSpace(*buf); | |
100 heap::GcAndSweep(heap, NEW_SPACE); | |
101 VerifyTrackedInNewSpace(*buf); | |
102 heap::GcAndSweep(heap, NEW_SPACE); | |
103 VerifyTrackedInOldSpace(*buf); | |
104 heap::GcAndSweep(heap, OLD_SPACE); | |
105 VerifyTrackedInOldSpace(*buf); | |
106 heap::GcAndSweep(heap, NEW_SPACE); | |
107 VerifyTrackedInOldSpace(*buf); | |
108 raw_ab = *buf; | |
109 } | |
110 // 2 GCs are needed because we promote to old space as live, meaning that | |
111 // we will survive one GC. | |
112 heap::GcAndSweep(heap, OLD_SPACE); | |
113 heap::GcAndSweep(heap, OLD_SPACE); | |
114 VerifyUntracked(raw_ab); | |
115 } | |
116 | |
117 TEST(ArrayBuffer_Compaction) { | |
118 FLAG_manual_evacuation_candidates_selection = true; | |
119 CcTest::InitializeVM(); | |
120 LocalContext env; | |
121 v8::Isolate* isolate = env->GetIsolate(); | |
122 Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); | |
123 heap::AbandonCurrentlyFreeMemory(heap->old_space()); | |
124 | |
125 v8::HandleScope handle_scope(isolate); | |
126 Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, 100); | |
127 Handle<JSArrayBuffer> buf1 = v8::Utils::OpenHandle(*ab1); | |
128 VerifyTrackedInNewSpace(*buf1); | |
129 heap::GcAndSweep(heap, NEW_SPACE); | |
130 heap::GcAndSweep(heap, NEW_SPACE); | |
131 | |
132 Page* page_before_gc = Page::FromAddress(buf1->address()); | |
133 page_before_gc->SetFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); | |
134 VerifyTrackedInOldSpace(*buf1); | |
135 | |
136 heap->CollectAllGarbage(); | |
137 | |
138 Page* page_after_gc = Page::FromAddress(buf1->address()); | |
139 VerifyTrackedInOldSpace(*buf1); | |
140 | |
141 CHECK_NE(page_before_gc, page_after_gc); | |
142 } | |
143 | |
144 } // namespace internal | |
145 } // namespace v8 | |
OLD | NEW |