OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 | 29 |
30 #include "v8.h" | 30 #include "v8.h" |
31 | 31 |
32 #include "global-handles.h" | 32 #include "global-handles.h" |
33 #include "snapshot.h" | 33 #include "snapshot.h" |
34 #include "top.h" | |
35 #include "cctest.h" | 34 #include "cctest.h" |
36 | 35 |
37 using namespace v8::internal; | 36 using namespace v8::internal; |
38 | 37 |
39 static v8::Persistent<v8::Context> env; | 38 static v8::Persistent<v8::Context> env; |
40 | 39 |
41 static void InitializeVM() { | 40 static void InitializeVM() { |
42 if (env.IsEmpty()) env = v8::Context::New(); | 41 if (env.IsEmpty()) env = v8::Context::New(); |
43 v8::HandleScope scope; | 42 v8::HandleScope scope; |
44 env->Enter(); | 43 env->Enter(); |
(...skipping 27 matching lines...) Expand all Loading... |
72 | 71 |
73 TEST(Promotion) { | 72 TEST(Promotion) { |
74 // This test requires compaction. If compaction is turned off, we | 73 // This test requires compaction. If compaction is turned off, we |
75 // skip the entire test. | 74 // skip the entire test. |
76 if (FLAG_never_compact) return; | 75 if (FLAG_never_compact) return; |
77 | 76 |
78 // Ensure that we get a compacting collection so that objects are promoted | 77 // Ensure that we get a compacting collection so that objects are promoted |
79 // from new space. | 78 // from new space. |
80 FLAG_gc_global = true; | 79 FLAG_gc_global = true; |
81 FLAG_always_compact = true; | 80 FLAG_always_compact = true; |
82 Heap::ConfigureHeap(2*256*KB, 4*MB, 4*MB); | 81 HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB); |
83 | 82 |
84 InitializeVM(); | 83 InitializeVM(); |
85 | 84 |
86 v8::HandleScope sc; | 85 v8::HandleScope sc; |
87 | 86 |
88 // Allocate a fixed array in the new space. | 87 // Allocate a fixed array in the new space. |
89 int array_size = | 88 int array_size = |
90 (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / | 89 (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / |
91 (kPointerSize * 4); | 90 (kPointerSize * 4); |
92 Object* obj = Heap::AllocateFixedArray(array_size)->ToObjectChecked(); | 91 Object* obj = HEAP->AllocateFixedArray(array_size)->ToObjectChecked(); |
93 | 92 |
94 Handle<FixedArray> array(FixedArray::cast(obj)); | 93 Handle<FixedArray> array(FixedArray::cast(obj)); |
95 | 94 |
96 // Array should be in the new space. | 95 // Array should be in the new space. |
97 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 96 CHECK(HEAP->InSpace(*array, NEW_SPACE)); |
98 | 97 |
99 // Call the m-c collector, so array becomes an old object. | 98 // Call the m-c collector, so array becomes an old object. |
100 Heap::CollectGarbage(OLD_POINTER_SPACE); | 99 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
101 | 100 |
102 // Array now sits in the old space | 101 // Array now sits in the old space |
103 CHECK(Heap::InSpace(*array, OLD_POINTER_SPACE)); | 102 CHECK(HEAP->InSpace(*array, OLD_POINTER_SPACE)); |
104 } | 103 } |
105 | 104 |
106 | 105 |
107 TEST(NoPromotion) { | 106 TEST(NoPromotion) { |
108 Heap::ConfigureHeap(2*256*KB, 4*MB, 4*MB); | 107 HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB); |
109 | 108 |
110 // Test the situation that some objects in new space are promoted to | 109 // Test the situation that some objects in new space are promoted to |
111 // the old space | 110 // the old space |
112 InitializeVM(); | 111 InitializeVM(); |
113 | 112 |
114 v8::HandleScope sc; | 113 v8::HandleScope sc; |
115 | 114 |
116 // Do a mark compact GC to shrink the heap. | 115 // Do a mark compact GC to shrink the heap. |
117 Heap::CollectGarbage(OLD_POINTER_SPACE); | 116 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
118 | 117 |
119 // Allocate a big Fixed array in the new space. | 118 // Allocate a big Fixed array in the new space. |
120 int size = (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / | 119 int size = (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / |
121 kPointerSize; | 120 kPointerSize; |
122 Object* obj = Heap::AllocateFixedArray(size)->ToObjectChecked(); | 121 Object* obj = HEAP->AllocateFixedArray(size)->ToObjectChecked(); |
123 | 122 |
124 Handle<FixedArray> array(FixedArray::cast(obj)); | 123 Handle<FixedArray> array(FixedArray::cast(obj)); |
125 | 124 |
126 // Array still stays in the new space. | 125 // Array still stays in the new space. |
127 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 126 CHECK(HEAP->InSpace(*array, NEW_SPACE)); |
128 | 127 |
129 // Allocate objects in the old space until out of memory. | 128 // Allocate objects in the old space until out of memory. |
130 FixedArray* host = *array; | 129 FixedArray* host = *array; |
131 while (true) { | 130 while (true) { |
132 Object* obj; | 131 Object* obj; |
133 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(100, TENURED); | 132 { MaybeObject* maybe_obj = HEAP->AllocateFixedArray(100, TENURED); |
134 if (!maybe_obj->ToObject(&obj)) break; | 133 if (!maybe_obj->ToObject(&obj)) break; |
135 } | 134 } |
136 | 135 |
137 host->set(0, obj); | 136 host->set(0, obj); |
138 host = FixedArray::cast(obj); | 137 host = FixedArray::cast(obj); |
139 } | 138 } |
140 | 139 |
141 // Call mark compact GC, and it should pass. | 140 // Call mark compact GC, and it should pass. |
142 Heap::CollectGarbage(OLD_POINTER_SPACE); | 141 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
143 | 142 |
144 // array should not be promoted because the old space is full. | 143 // array should not be promoted because the old space is full. |
145 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 144 CHECK(HEAP->InSpace(*array, NEW_SPACE)); |
146 } | 145 } |
147 | 146 |
148 | 147 |
149 TEST(MarkCompactCollector) { | 148 TEST(MarkCompactCollector) { |
150 InitializeVM(); | 149 InitializeVM(); |
151 | 150 |
152 v8::HandleScope sc; | 151 v8::HandleScope sc; |
153 // call mark-compact when heap is empty | 152 // call mark-compact when heap is empty |
154 Heap::CollectGarbage(OLD_POINTER_SPACE); | 153 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
155 | 154 |
156 // keep allocating garbage in new space until it fails | 155 // keep allocating garbage in new space until it fails |
157 const int ARRAY_SIZE = 100; | 156 const int ARRAY_SIZE = 100; |
158 Object* array; | 157 Object* array; |
159 MaybeObject* maybe_array; | 158 MaybeObject* maybe_array; |
160 do { | 159 do { |
161 maybe_array = Heap::AllocateFixedArray(ARRAY_SIZE); | 160 maybe_array = HEAP->AllocateFixedArray(ARRAY_SIZE); |
162 } while (maybe_array->ToObject(&array)); | 161 } while (maybe_array->ToObject(&array)); |
163 Heap::CollectGarbage(NEW_SPACE); | 162 HEAP->CollectGarbage(NEW_SPACE); |
164 | 163 |
165 array = Heap::AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked(); | 164 array = HEAP->AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked(); |
166 | 165 |
167 // keep allocating maps until it fails | 166 // keep allocating maps until it fails |
168 Object* mapp; | 167 Object* mapp; |
169 MaybeObject* maybe_mapp; | 168 MaybeObject* maybe_mapp; |
170 do { | 169 do { |
171 maybe_mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 170 maybe_mapp = HEAP->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
172 } while (maybe_mapp->ToObject(&mapp)); | 171 } while (maybe_mapp->ToObject(&mapp)); |
173 Heap::CollectGarbage(MAP_SPACE); | 172 HEAP->CollectGarbage(MAP_SPACE); |
174 mapp = Heap::AllocateMap(JS_OBJECT_TYPE, | 173 mapp = HEAP->AllocateMap(JS_OBJECT_TYPE, |
175 JSObject::kHeaderSize)->ToObjectChecked(); | 174 JSObject::kHeaderSize)->ToObjectChecked(); |
176 | 175 |
177 // allocate a garbage | 176 // allocate a garbage |
178 String* func_name = | 177 String* func_name = |
179 String::cast(Heap::LookupAsciiSymbol("theFunction")->ToObjectChecked()); | 178 String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked()); |
180 SharedFunctionInfo* function_share = SharedFunctionInfo::cast( | 179 SharedFunctionInfo* function_share = SharedFunctionInfo::cast( |
181 Heap::AllocateSharedFunctionInfo(func_name)->ToObjectChecked()); | 180 HEAP->AllocateSharedFunctionInfo(func_name)->ToObjectChecked()); |
182 JSFunction* function = JSFunction::cast( | 181 JSFunction* function = JSFunction::cast( |
183 Heap::AllocateFunction(*Top::function_map(), | 182 HEAP->AllocateFunction(*Isolate::Current()->function_map(), |
184 function_share, | 183 function_share, |
185 Heap::undefined_value())->ToObjectChecked()); | 184 HEAP->undefined_value())->ToObjectChecked()); |
186 Map* initial_map = | 185 Map* initial_map = |
187 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, | 186 Map::cast(HEAP->AllocateMap(JS_OBJECT_TYPE, |
188 JSObject::kHeaderSize)->ToObjectChecked()); | 187 JSObject::kHeaderSize)->ToObjectChecked()); |
189 function->set_initial_map(initial_map); | 188 function->set_initial_map(initial_map); |
190 Top::context()->global()->SetProperty(func_name, | 189 Isolate::Current()->context()->global()->SetProperty( |
191 function, | 190 func_name, function, NONE, kNonStrictMode)->ToObjectChecked(); |
192 NONE, | |
193 kNonStrictMode)->ToObjectChecked(); | |
194 | 191 |
195 JSObject* obj = | 192 JSObject* obj = JSObject::cast( |
196 JSObject::cast(Heap::AllocateJSObject(function)->ToObjectChecked()); | 193 HEAP->AllocateJSObject(function)->ToObjectChecked()); |
197 Heap::CollectGarbage(OLD_POINTER_SPACE); | 194 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
198 | 195 |
199 func_name = | 196 func_name = |
200 String::cast(Heap::LookupAsciiSymbol("theFunction")->ToObjectChecked()); | 197 String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked()); |
201 CHECK(Top::context()->global()->HasLocalProperty(func_name)); | 198 CHECK(Isolate::Current()->context()->global()->HasLocalProperty(func_name)); |
202 Object* func_value = | 199 Object* func_value = Isolate::Current()->context()->global()-> |
203 Top::context()->global()->GetProperty(func_name)->ToObjectChecked(); | 200 GetProperty(func_name)->ToObjectChecked(); |
204 CHECK(func_value->IsJSFunction()); | 201 CHECK(func_value->IsJSFunction()); |
205 function = JSFunction::cast(func_value); | 202 function = JSFunction::cast(func_value); |
206 | 203 |
207 obj = JSObject::cast(Heap::AllocateJSObject(function)->ToObjectChecked()); | 204 obj = JSObject::cast(HEAP->AllocateJSObject(function)->ToObjectChecked()); |
208 String* obj_name = | 205 String* obj_name = |
209 String::cast(Heap::LookupAsciiSymbol("theObject")->ToObjectChecked()); | 206 String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked()); |
210 Top::context()->global()->SetProperty(obj_name, | 207 Isolate::Current()->context()->global()->SetProperty( |
211 obj, | 208 obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked(); |
212 NONE, | |
213 kNonStrictMode)->ToObjectChecked(); | |
214 String* prop_name = | 209 String* prop_name = |
215 String::cast(Heap::LookupAsciiSymbol("theSlot")->ToObjectChecked()); | 210 String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked()); |
216 obj->SetProperty(prop_name, | 211 obj->SetProperty(prop_name, |
217 Smi::FromInt(23), | 212 Smi::FromInt(23), |
218 NONE, | 213 NONE, |
219 kNonStrictMode)->ToObjectChecked(); | 214 kNonStrictMode)->ToObjectChecked(); |
220 | 215 |
221 Heap::CollectGarbage(OLD_POINTER_SPACE); | 216 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
222 | 217 |
223 obj_name = | 218 obj_name = |
224 String::cast(Heap::LookupAsciiSymbol("theObject")->ToObjectChecked()); | 219 String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked()); |
225 CHECK(Top::context()->global()->HasLocalProperty(obj_name)); | 220 CHECK(Isolate::Current()->context()->global()->HasLocalProperty(obj_name)); |
226 CHECK(Top::context()->global()-> | 221 CHECK(Isolate::Current()->context()->global()-> |
227 GetProperty(obj_name)->ToObjectChecked()->IsJSObject()); | 222 GetProperty(obj_name)->ToObjectChecked()->IsJSObject()); |
228 obj = JSObject::cast( | 223 obj = JSObject::cast(Isolate::Current()->context()->global()-> |
229 Top::context()->global()->GetProperty(obj_name)->ToObjectChecked()); | 224 GetProperty(obj_name)->ToObjectChecked()); |
230 prop_name = | 225 prop_name = |
231 String::cast(Heap::LookupAsciiSymbol("theSlot")->ToObjectChecked()); | 226 String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked()); |
232 CHECK(obj->GetProperty(prop_name)->ToObjectChecked() == Smi::FromInt(23)); | 227 CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23)); |
233 } | 228 } |
234 | 229 |
235 | 230 |
236 static Handle<Map> CreateMap() { | 231 static Handle<Map> CreateMap() { |
237 return Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 232 return FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
238 } | 233 } |
239 | 234 |
240 | 235 |
241 TEST(MapCompact) { | 236 TEST(MapCompact) { |
242 FLAG_max_map_space_pages = 16; | 237 FLAG_max_map_space_pages = 16; |
243 InitializeVM(); | 238 InitializeVM(); |
244 | 239 |
245 { | 240 { |
246 v8::HandleScope sc; | 241 v8::HandleScope sc; |
247 // keep allocating maps while pointers are still encodable and thus | 242 // keep allocating maps while pointers are still encodable and thus |
248 // mark compact is permitted. | 243 // mark compact is permitted. |
249 Handle<JSObject> root = Factory::NewJSObjectFromMap(CreateMap()); | 244 Handle<JSObject> root = FACTORY->NewJSObjectFromMap(CreateMap()); |
250 do { | 245 do { |
251 Handle<Map> map = CreateMap(); | 246 Handle<Map> map = CreateMap(); |
252 map->set_prototype(*root); | 247 map->set_prototype(*root); |
253 root = Factory::NewJSObjectFromMap(map); | 248 root = FACTORY->NewJSObjectFromMap(map); |
254 } while (Heap::map_space()->MapPointersEncodable()); | 249 } while (HEAP->map_space()->MapPointersEncodable()); |
255 } | 250 } |
256 // Now, as we don't have any handles to just allocated maps, we should | 251 // Now, as we don't have any handles to just allocated maps, we should |
257 // be able to trigger map compaction. | 252 // be able to trigger map compaction. |
258 // To give an additional chance to fail, try to force compaction which | 253 // To give an additional chance to fail, try to force compaction which |
259 // should be impossible right now. | 254 // should be impossible right now. |
260 Heap::CollectAllGarbage(true); | 255 HEAP->CollectAllGarbage(true); |
261 // And now map pointers should be encodable again. | 256 // And now map pointers should be encodable again. |
262 CHECK(Heap::map_space()->MapPointersEncodable()); | 257 CHECK(HEAP->map_space()->MapPointersEncodable()); |
263 } | 258 } |
264 | 259 |
265 | 260 |
266 static int gc_starts = 0; | 261 static int gc_starts = 0; |
267 static int gc_ends = 0; | 262 static int gc_ends = 0; |
268 | 263 |
269 static void GCPrologueCallbackFunc() { | 264 static void GCPrologueCallbackFunc() { |
270 CHECK(gc_starts == gc_ends); | 265 CHECK(gc_starts == gc_ends); |
271 gc_starts++; | 266 gc_starts++; |
272 } | 267 } |
273 | 268 |
274 | 269 |
275 static void GCEpilogueCallbackFunc() { | 270 static void GCEpilogueCallbackFunc() { |
276 CHECK(gc_starts == gc_ends + 1); | 271 CHECK(gc_starts == gc_ends + 1); |
277 gc_ends++; | 272 gc_ends++; |
278 } | 273 } |
279 | 274 |
280 | 275 |
281 TEST(GCCallback) { | 276 TEST(GCCallback) { |
282 InitializeVM(); | 277 InitializeVM(); |
283 | 278 |
284 Heap::SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); | 279 HEAP->SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); |
285 Heap::SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); | 280 HEAP->SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); |
286 | 281 |
287 // Scavenge does not call GC callback functions. | 282 // Scavenge does not call GC callback functions. |
288 Heap::PerformScavenge(); | 283 HEAP->PerformScavenge(); |
289 | 284 |
290 CHECK_EQ(0, gc_starts); | 285 CHECK_EQ(0, gc_starts); |
291 CHECK_EQ(gc_ends, gc_starts); | 286 CHECK_EQ(gc_ends, gc_starts); |
292 | 287 |
293 Heap::CollectGarbage(OLD_POINTER_SPACE); | 288 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
294 CHECK_EQ(1, gc_starts); | 289 CHECK_EQ(1, gc_starts); |
295 CHECK_EQ(gc_ends, gc_starts); | 290 CHECK_EQ(gc_ends, gc_starts); |
296 } | 291 } |
297 | 292 |
298 | 293 |
299 static int NumberOfWeakCalls = 0; | 294 static int NumberOfWeakCalls = 0; |
300 static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { | 295 static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { |
301 ASSERT(id == reinterpret_cast<void*>(1234)); | 296 ASSERT(id == reinterpret_cast<void*>(1234)); |
302 NumberOfWeakCalls++; | 297 NumberOfWeakCalls++; |
303 handle.Dispose(); | 298 handle.Dispose(); |
304 } | 299 } |
305 | 300 |
306 TEST(ObjectGroups) { | 301 TEST(ObjectGroups) { |
| 302 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
307 InitializeVM(); | 303 InitializeVM(); |
308 | 304 |
309 NumberOfWeakCalls = 0; | 305 NumberOfWeakCalls = 0; |
310 v8::HandleScope handle_scope; | 306 v8::HandleScope handle_scope; |
311 | 307 |
312 Handle<Object> g1s1 = | 308 Handle<Object> g1s1 = |
313 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 309 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
314 Handle<Object> g1s2 = | 310 Handle<Object> g1s2 = |
315 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 311 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
316 Handle<Object> g1c1 = | 312 Handle<Object> g1c1 = |
317 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 313 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
318 GlobalHandles::MakeWeak(g1s1.location(), | 314 global_handles->MakeWeak(g1s1.location(), |
319 reinterpret_cast<void*>(1234), | 315 reinterpret_cast<void*>(1234), |
320 &WeakPointerCallback); | 316 &WeakPointerCallback); |
321 GlobalHandles::MakeWeak(g1s2.location(), | 317 global_handles->MakeWeak(g1s2.location(), |
322 reinterpret_cast<void*>(1234), | 318 reinterpret_cast<void*>(1234), |
323 &WeakPointerCallback); | 319 &WeakPointerCallback); |
324 GlobalHandles::MakeWeak(g1c1.location(), | 320 global_handles->MakeWeak(g1c1.location(), |
325 reinterpret_cast<void*>(1234), | 321 reinterpret_cast<void*>(1234), |
326 &WeakPointerCallback); | 322 &WeakPointerCallback); |
327 | 323 |
328 Handle<Object> g2s1 = | 324 Handle<Object> g2s1 = |
329 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 325 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
330 Handle<Object> g2s2 = | 326 Handle<Object> g2s2 = |
331 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 327 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
332 Handle<Object> g2c1 = | 328 Handle<Object> g2c1 = |
333 GlobalHandles::Create(Heap::AllocateFixedArray(1)->ToObjectChecked()); | 329 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
334 GlobalHandles::MakeWeak(g2s1.location(), | 330 global_handles->MakeWeak(g2s1.location(), |
335 reinterpret_cast<void*>(1234), | 331 reinterpret_cast<void*>(1234), |
336 &WeakPointerCallback); | 332 &WeakPointerCallback); |
337 GlobalHandles::MakeWeak(g2s2.location(), | 333 global_handles->MakeWeak(g2s2.location(), |
338 reinterpret_cast<void*>(1234), | 334 reinterpret_cast<void*>(1234), |
339 &WeakPointerCallback); | 335 &WeakPointerCallback); |
340 GlobalHandles::MakeWeak(g2c1.location(), | 336 global_handles->MakeWeak(g2c1.location(), |
341 reinterpret_cast<void*>(1234), | 337 reinterpret_cast<void*>(1234), |
342 &WeakPointerCallback); | 338 &WeakPointerCallback); |
343 | 339 |
344 Handle<Object> root = GlobalHandles::Create(*g1s1); // make a root. | 340 Handle<Object> root = global_handles->Create(*g1s1); // make a root. |
345 | 341 |
346 // Connect group 1 and 2, make a cycle. | 342 // Connect group 1 and 2, make a cycle. |
347 Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); | 343 Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); |
348 Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); | 344 Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); |
349 | 345 |
350 { | 346 { |
351 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 347 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
352 Object** g1_children[] = { g1c1.location() }; | 348 Object** g1_children[] = { g1c1.location() }; |
353 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 349 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
354 Object** g2_children[] = { g2c1.location() }; | 350 Object** g2_children[] = { g2c1.location() }; |
355 GlobalHandles::AddObjectGroup(g1_objects, 2, NULL); | 351 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
356 GlobalHandles::AddImplicitReferences(HeapObject::cast(*g1s1), | 352 global_handles->AddImplicitReferences(HeapObject::cast(*g1s1), |
357 g1_children, 1); | 353 g1_children, 1); |
358 GlobalHandles::AddObjectGroup(g2_objects, 2, NULL); | 354 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
359 GlobalHandles::AddImplicitReferences(HeapObject::cast(*g2s2), | 355 global_handles->AddImplicitReferences(HeapObject::cast(*g2s2), |
360 g2_children, 1); | 356 g2_children, 1); |
361 } | 357 } |
362 // Do a full GC | 358 // Do a full GC |
363 Heap::CollectGarbage(OLD_POINTER_SPACE); | 359 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
364 | 360 |
365 // All object should be alive. | 361 // All object should be alive. |
366 CHECK_EQ(0, NumberOfWeakCalls); | 362 CHECK_EQ(0, NumberOfWeakCalls); |
367 | 363 |
368 // Weaken the root. | 364 // Weaken the root. |
369 GlobalHandles::MakeWeak(root.location(), | 365 global_handles->MakeWeak(root.location(), |
370 reinterpret_cast<void*>(1234), | 366 reinterpret_cast<void*>(1234), |
371 &WeakPointerCallback); | 367 &WeakPointerCallback); |
372 // But make children strong roots---all the objects (except for children) | 368 // But make children strong roots---all the objects (except for children) |
373 // should be collectable now. | 369 // should be collectable now. |
374 GlobalHandles::ClearWeakness(g1c1.location()); | 370 global_handles->ClearWeakness(g1c1.location()); |
375 GlobalHandles::ClearWeakness(g2c1.location()); | 371 global_handles->ClearWeakness(g2c1.location()); |
376 | 372 |
377 // Groups are deleted, rebuild groups. | 373 // Groups are deleted, rebuild groups. |
378 { | 374 { |
379 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 375 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
380 Object** g1_children[] = { g1c1.location() }; | 376 Object** g1_children[] = { g1c1.location() }; |
381 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 377 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
382 Object** g2_children[] = { g2c1.location() }; | 378 Object** g2_children[] = { g2c1.location() }; |
383 GlobalHandles::AddObjectGroup(g1_objects, 2, NULL); | 379 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
384 GlobalHandles::AddImplicitReferences(HeapObject::cast(*g1s1), | 380 global_handles->AddImplicitReferences(HeapObject::cast(*g1s1), |
385 g1_children, 1); | 381 g1_children, 1); |
386 GlobalHandles::AddObjectGroup(g2_objects, 2, NULL); | 382 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
387 GlobalHandles::AddImplicitReferences(HeapObject::cast(*g2s2), | 383 global_handles->AddImplicitReferences(HeapObject::cast(*g2s2), |
388 g2_children, 1); | 384 g2_children, 1); |
389 } | 385 } |
390 | 386 |
391 Heap::CollectGarbage(OLD_POINTER_SPACE); | 387 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
392 | 388 |
393 // All objects should be gone. 5 global handles in total. | 389 // All objects should be gone. 5 global handles in total. |
394 CHECK_EQ(5, NumberOfWeakCalls); | 390 CHECK_EQ(5, NumberOfWeakCalls); |
395 | 391 |
396 // And now make children weak again and collect them. | 392 // And now make children weak again and collect them. |
397 GlobalHandles::MakeWeak(g1c1.location(), | 393 global_handles->MakeWeak(g1c1.location(), |
398 reinterpret_cast<void*>(1234), | 394 reinterpret_cast<void*>(1234), |
399 &WeakPointerCallback); | 395 &WeakPointerCallback); |
400 GlobalHandles::MakeWeak(g2c1.location(), | 396 global_handles->MakeWeak(g2c1.location(), |
401 reinterpret_cast<void*>(1234), | 397 reinterpret_cast<void*>(1234), |
402 &WeakPointerCallback); | 398 &WeakPointerCallback); |
403 | 399 |
404 Heap::CollectGarbage(OLD_POINTER_SPACE); | 400 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
405 CHECK_EQ(7, NumberOfWeakCalls); | 401 CHECK_EQ(7, NumberOfWeakCalls); |
406 } | 402 } |
OLD | NEW |