OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 v8::HandleScope sc(CcTest::isolate()); | 82 v8::HandleScope sc(CcTest::isolate()); |
83 Heap* heap = isolate->heap(); | 83 Heap* heap = isolate->heap(); |
84 | 84 |
85 heap::SealCurrentObjects(heap); | 85 heap::SealCurrentObjects(heap); |
86 | 86 |
87 int array_length = heap::FixedArrayLenFromSize(kMaxRegularHeapObjectSize); | 87 int array_length = heap::FixedArrayLenFromSize(kMaxRegularHeapObjectSize); |
88 Handle<FixedArray> array = isolate->factory()->NewFixedArray(array_length); | 88 Handle<FixedArray> array = isolate->factory()->NewFixedArray(array_length); |
89 | 89 |
90 // Array should be in the new space. | 90 // Array should be in the new space. |
91 CHECK(heap->InSpace(*array, NEW_SPACE)); | 91 CHECK(heap->InSpace(*array, NEW_SPACE)); |
92 heap->CollectAllGarbage(); | 92 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
93 heap->CollectAllGarbage(); | 93 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
94 CHECK(heap->InSpace(*array, OLD_SPACE)); | 94 CHECK(heap->InSpace(*array, OLD_SPACE)); |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 HEAP_TEST(NoPromotion) { | 98 HEAP_TEST(NoPromotion) { |
99 // Page promotion allows pages to be moved to old space even in the case of | 99 // Page promotion allows pages to be moved to old space even in the case of |
100 // OOM scenarios. | 100 // OOM scenarios. |
101 FLAG_page_promotion = false; | 101 FLAG_page_promotion = false; |
102 | 102 |
103 CcTest::InitializeVM(); | 103 CcTest::InitializeVM(); |
104 Isolate* isolate = CcTest::i_isolate(); | 104 Isolate* isolate = CcTest::i_isolate(); |
105 { | 105 { |
106 v8::HandleScope sc(CcTest::isolate()); | 106 v8::HandleScope sc(CcTest::isolate()); |
107 Heap* heap = isolate->heap(); | 107 Heap* heap = isolate->heap(); |
108 | 108 |
109 heap::SealCurrentObjects(heap); | 109 heap::SealCurrentObjects(heap); |
110 | 110 |
111 int array_length = heap::FixedArrayLenFromSize(kMaxRegularHeapObjectSize); | 111 int array_length = heap::FixedArrayLenFromSize(kMaxRegularHeapObjectSize); |
112 Handle<FixedArray> array = isolate->factory()->NewFixedArray(array_length); | 112 Handle<FixedArray> array = isolate->factory()->NewFixedArray(array_length); |
113 | 113 |
114 heap->set_force_oom(true); | 114 heap->set_force_oom(true); |
115 // Array should be in the new space. | 115 // Array should be in the new space. |
116 CHECK(heap->InSpace(*array, NEW_SPACE)); | 116 CHECK(heap->InSpace(*array, NEW_SPACE)); |
117 heap->CollectAllGarbage(); | 117 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
118 heap->CollectAllGarbage(); | 118 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
119 CHECK(heap->InSpace(*array, NEW_SPACE)); | 119 CHECK(heap->InSpace(*array, NEW_SPACE)); |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 HEAP_TEST(MarkCompactCollector) { | 123 HEAP_TEST(MarkCompactCollector) { |
124 FLAG_incremental_marking = false; | 124 FLAG_incremental_marking = false; |
125 FLAG_retain_maps_for_n_gc = 0; | 125 FLAG_retain_maps_for_n_gc = 0; |
126 CcTest::InitializeVM(); | 126 CcTest::InitializeVM(); |
127 Isolate* isolate = CcTest::i_isolate(); | 127 Isolate* isolate = CcTest::i_isolate(); |
128 Heap* heap = CcTest::heap(); | 128 Heap* heap = CcTest::heap(); |
129 Factory* factory = isolate->factory(); | 129 Factory* factory = isolate->factory(); |
130 | 130 |
131 v8::HandleScope sc(CcTest::isolate()); | 131 v8::HandleScope sc(CcTest::isolate()); |
132 Handle<JSGlobalObject> global(isolate->context()->global_object()); | 132 Handle<JSGlobalObject> global(isolate->context()->global_object()); |
133 | 133 |
134 // call mark-compact when heap is empty | 134 // call mark-compact when heap is empty |
135 heap->CollectGarbage(OLD_SPACE, "trigger 1"); | 135 CcTest::CollectGarbage(OLD_SPACE); |
136 | 136 |
137 // keep allocating garbage in new space until it fails | 137 // keep allocating garbage in new space until it fails |
138 const int arraysize = 100; | 138 const int arraysize = 100; |
139 AllocationResult allocation; | 139 AllocationResult allocation; |
140 do { | 140 do { |
141 allocation = heap->AllocateFixedArray(arraysize); | 141 allocation = heap->AllocateFixedArray(arraysize); |
142 } while (!allocation.IsRetry()); | 142 } while (!allocation.IsRetry()); |
143 heap->CollectGarbage(NEW_SPACE, "trigger 2"); | 143 CcTest::CollectGarbage(NEW_SPACE); |
144 heap->AllocateFixedArray(arraysize).ToObjectChecked(); | 144 heap->AllocateFixedArray(arraysize).ToObjectChecked(); |
145 | 145 |
146 // keep allocating maps until it fails | 146 // keep allocating maps until it fails |
147 do { | 147 do { |
148 allocation = heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 148 allocation = heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
149 } while (!allocation.IsRetry()); | 149 } while (!allocation.IsRetry()); |
150 heap->CollectGarbage(MAP_SPACE, "trigger 3"); | 150 CcTest::CollectGarbage(MAP_SPACE); |
151 heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize).ToObjectChecked(); | 151 heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize).ToObjectChecked(); |
152 | 152 |
153 { HandleScope scope(isolate); | 153 { HandleScope scope(isolate); |
154 // allocate a garbage | 154 // allocate a garbage |
155 Handle<String> func_name = factory->InternalizeUtf8String("theFunction"); | 155 Handle<String> func_name = factory->InternalizeUtf8String("theFunction"); |
156 Handle<JSFunction> function = factory->NewFunction(func_name); | 156 Handle<JSFunction> function = factory->NewFunction(func_name); |
157 JSReceiver::SetProperty(global, func_name, function, SLOPPY).Check(); | 157 JSReceiver::SetProperty(global, func_name, function, SLOPPY).Check(); |
158 | 158 |
159 factory->NewJSObject(function); | 159 factory->NewJSObject(function); |
160 } | 160 } |
161 | 161 |
162 heap->CollectGarbage(OLD_SPACE, "trigger 4"); | 162 CcTest::CollectGarbage(OLD_SPACE); |
163 | 163 |
164 { HandleScope scope(isolate); | 164 { HandleScope scope(isolate); |
165 Handle<String> func_name = factory->InternalizeUtf8String("theFunction"); | 165 Handle<String> func_name = factory->InternalizeUtf8String("theFunction"); |
166 CHECK(Just(true) == JSReceiver::HasOwnProperty(global, func_name)); | 166 CHECK(Just(true) == JSReceiver::HasOwnProperty(global, func_name)); |
167 Handle<Object> func_value = | 167 Handle<Object> func_value = |
168 Object::GetProperty(global, func_name).ToHandleChecked(); | 168 Object::GetProperty(global, func_name).ToHandleChecked(); |
169 CHECK(func_value->IsJSFunction()); | 169 CHECK(func_value->IsJSFunction()); |
170 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); | 170 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); |
171 Handle<JSObject> obj = factory->NewJSObject(function); | 171 Handle<JSObject> obj = factory->NewJSObject(function); |
172 | 172 |
173 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); | 173 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); |
174 JSReceiver::SetProperty(global, obj_name, obj, SLOPPY).Check(); | 174 JSReceiver::SetProperty(global, obj_name, obj, SLOPPY).Check(); |
175 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); | 175 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); |
176 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); | 176 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
177 JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check(); | 177 JSReceiver::SetProperty(obj, prop_name, twenty_three, SLOPPY).Check(); |
178 } | 178 } |
179 | 179 |
180 heap->CollectGarbage(OLD_SPACE, "trigger 5"); | 180 CcTest::CollectGarbage(OLD_SPACE); |
181 | 181 |
182 { HandleScope scope(isolate); | 182 { HandleScope scope(isolate); |
183 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); | 183 Handle<String> obj_name = factory->InternalizeUtf8String("theObject"); |
184 CHECK(Just(true) == JSReceiver::HasOwnProperty(global, obj_name)); | 184 CHECK(Just(true) == JSReceiver::HasOwnProperty(global, obj_name)); |
185 Handle<Object> object = | 185 Handle<Object> object = |
186 Object::GetProperty(global, obj_name).ToHandleChecked(); | 186 Object::GetProperty(global, obj_name).ToHandleChecked(); |
187 CHECK(object->IsJSObject()); | 187 CHECK(object->IsJSObject()); |
188 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); | 188 Handle<String> prop_name = factory->InternalizeUtf8String("theSlot"); |
189 CHECK_EQ(*Object::GetProperty(object, prop_name).ToHandleChecked(), | 189 CHECK_EQ(*Object::GetProperty(object, prop_name).ToHandleChecked(), |
190 Smi::FromInt(23)); | 190 Smi::FromInt(23)); |
(...skipping 22 matching lines...) Expand all Loading... |
213 do { | 213 do { |
214 Handle<Map> map = CreateMap(); | 214 Handle<Map> map = CreateMap(); |
215 map->set_prototype(*root); | 215 map->set_prototype(*root); |
216 root = factory->NewJSObjectFromMap(map); | 216 root = factory->NewJSObjectFromMap(map); |
217 } while (CcTest::heap()->map_space()->MapPointersEncodable()); | 217 } while (CcTest::heap()->map_space()->MapPointersEncodable()); |
218 } | 218 } |
219 // Now, as we don't have any handles to just allocated maps, we should | 219 // Now, as we don't have any handles to just allocated maps, we should |
220 // be able to trigger map compaction. | 220 // be able to trigger map compaction. |
221 // To give an additional chance to fail, try to force compaction which | 221 // To give an additional chance to fail, try to force compaction which |
222 // should be impossible right now. | 222 // should be impossible right now. |
223 CcTest::heap()->CollectAllGarbage(Heap::kForceCompactionMask); | 223 CcTest::CollectAllGarbage(Heap::kForceCompactionMask); |
224 // And now map pointers should be encodable again. | 224 // And now map pointers should be encodable again. |
225 CHECK(CcTest::heap()->map_space()->MapPointersEncodable()); | 225 CHECK(CcTest::heap()->map_space()->MapPointersEncodable()); |
226 } | 226 } |
227 #endif | 227 #endif |
228 | 228 |
229 | 229 |
230 static int NumberOfWeakCalls = 0; | 230 static int NumberOfWeakCalls = 0; |
231 static void WeakPointerCallback(const v8::WeakCallbackInfo<void>& data) { | 231 static void WeakPointerCallback(const v8::WeakCallbackInfo<void>& data) { |
232 std::pair<v8::Persistent<v8::Value>*, int>* p = | 232 std::pair<v8::Persistent<v8::Value>*, int>* p = |
233 reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( | 233 reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 294 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
295 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 295 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
296 global_handles->AddObjectGroup(g1_objects, 2, NULL); | 296 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
297 global_handles->SetReference(Handle<HeapObject>::cast(g1s1).location(), | 297 global_handles->SetReference(Handle<HeapObject>::cast(g1s1).location(), |
298 g1c1.location()); | 298 g1c1.location()); |
299 global_handles->AddObjectGroup(g2_objects, 2, NULL); | 299 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
300 global_handles->SetReference(Handle<HeapObject>::cast(g2s1).location(), | 300 global_handles->SetReference(Handle<HeapObject>::cast(g2s1).location(), |
301 g2c1.location()); | 301 g2c1.location()); |
302 } | 302 } |
303 // Do a full GC | 303 // Do a full GC |
304 heap->CollectGarbage(OLD_SPACE); | 304 CcTest::CollectGarbage(OLD_SPACE); |
305 | 305 |
306 // All object should be alive. | 306 // All object should be alive. |
307 CHECK_EQ(0, NumberOfWeakCalls); | 307 CHECK_EQ(0, NumberOfWeakCalls); |
308 | 308 |
309 // Weaken the root. | 309 // Weaken the root. |
310 std::pair<Handle<Object>*, int> root_and_id(&root, 1234); | 310 std::pair<Handle<Object>*, int> root_and_id(&root, 1234); |
311 GlobalHandles::MakeWeak( | 311 GlobalHandles::MakeWeak( |
312 root.location(), reinterpret_cast<void*>(&root_and_id), | 312 root.location(), reinterpret_cast<void*>(&root_and_id), |
313 &WeakPointerCallback, v8::WeakCallbackType::kParameter); | 313 &WeakPointerCallback, v8::WeakCallbackType::kParameter); |
314 // But make children strong roots---all the objects (except for children) | 314 // But make children strong roots---all the objects (except for children) |
315 // should be collectable now. | 315 // should be collectable now. |
316 global_handles->ClearWeakness(g1c1.location()); | 316 global_handles->ClearWeakness(g1c1.location()); |
317 global_handles->ClearWeakness(g2c1.location()); | 317 global_handles->ClearWeakness(g2c1.location()); |
318 | 318 |
319 // Groups are deleted, rebuild groups. | 319 // Groups are deleted, rebuild groups. |
320 { | 320 { |
321 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 321 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
322 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 322 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
323 global_handles->AddObjectGroup(g1_objects, 2, NULL); | 323 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
324 global_handles->SetReference(Handle<HeapObject>::cast(g1s1).location(), | 324 global_handles->SetReference(Handle<HeapObject>::cast(g1s1).location(), |
325 g1c1.location()); | 325 g1c1.location()); |
326 global_handles->AddObjectGroup(g2_objects, 2, NULL); | 326 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
327 global_handles->SetReference(Handle<HeapObject>::cast(g2s1).location(), | 327 global_handles->SetReference(Handle<HeapObject>::cast(g2s1).location(), |
328 g2c1.location()); | 328 g2c1.location()); |
329 } | 329 } |
330 | 330 |
331 heap->CollectGarbage(OLD_SPACE); | 331 CcTest::CollectGarbage(OLD_SPACE); |
332 | 332 |
333 // All objects should be gone. 5 global handles in total. | 333 // All objects should be gone. 5 global handles in total. |
334 CHECK_EQ(5, NumberOfWeakCalls); | 334 CHECK_EQ(5, NumberOfWeakCalls); |
335 | 335 |
336 // And now make children weak again and collect them. | 336 // And now make children weak again and collect them. |
337 GlobalHandles::MakeWeak( | 337 GlobalHandles::MakeWeak( |
338 g1c1.location(), reinterpret_cast<void*>(&g1c1_and_id), | 338 g1c1.location(), reinterpret_cast<void*>(&g1c1_and_id), |
339 &WeakPointerCallback, v8::WeakCallbackType::kParameter); | 339 &WeakPointerCallback, v8::WeakCallbackType::kParameter); |
340 GlobalHandles::MakeWeak( | 340 GlobalHandles::MakeWeak( |
341 g2c1.location(), reinterpret_cast<void*>(&g2c1_and_id), | 341 g2c1.location(), reinterpret_cast<void*>(&g2c1_and_id), |
342 &WeakPointerCallback, v8::WeakCallbackType::kParameter); | 342 &WeakPointerCallback, v8::WeakCallbackType::kParameter); |
343 | 343 |
344 heap->CollectGarbage(OLD_SPACE); | 344 CcTest::CollectGarbage(OLD_SPACE); |
345 CHECK_EQ(7, NumberOfWeakCalls); | 345 CHECK_EQ(7, NumberOfWeakCalls); |
346 } | 346 } |
347 | 347 |
348 | 348 |
349 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { | 349 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { |
350 public: | 350 public: |
351 TestRetainedObjectInfo() : has_been_disposed_(false) {} | 351 TestRetainedObjectInfo() : has_been_disposed_(false) {} |
352 | 352 |
353 bool has_been_disposed() { return has_been_disposed_; } | 353 bool has_been_disposed() { return has_been_disposed_; } |
354 | 354 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 | 479 |
480 | 480 |
481 TEST(RegressJoinThreadsOnIsolateDeinit) { | 481 TEST(RegressJoinThreadsOnIsolateDeinit) { |
482 intptr_t size_limit = ShortLivingIsolate() * 2; | 482 intptr_t size_limit = ShortLivingIsolate() * 2; |
483 for (int i = 0; i < 10; i++) { | 483 for (int i = 0; i < 10; i++) { |
484 CHECK_GT(size_limit, ShortLivingIsolate()); | 484 CHECK_GT(size_limit, ShortLivingIsolate()); |
485 } | 485 } |
486 } | 486 } |
487 | 487 |
488 #endif // __linux__ and !USE_SIMULATOR | 488 #endif // __linux__ and !USE_SIMULATOR |
OLD | NEW |