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