| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 (kPointerSize * 4); | 87 (kPointerSize * 4); |
| 88 Object* obj = Heap::AllocateFixedArray(array_size); | 88 Object* obj = Heap::AllocateFixedArray(array_size); |
| 89 CHECK(!obj->IsFailure()); | 89 CHECK(!obj->IsFailure()); |
| 90 | 90 |
| 91 Handle<FixedArray> array(FixedArray::cast(obj)); | 91 Handle<FixedArray> array(FixedArray::cast(obj)); |
| 92 | 92 |
| 93 // Array should be in the new space. | 93 // Array should be in the new space. |
| 94 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 94 CHECK(Heap::InSpace(*array, NEW_SPACE)); |
| 95 | 95 |
| 96 // Call the m-c collector, so array becomes an old object. | 96 // Call the m-c collector, so array becomes an old object. |
| 97 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 97 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 98 | 98 |
| 99 // Array now sits in the old space | 99 // Array now sits in the old space |
| 100 CHECK(Heap::InSpace(*array, OLD_POINTER_SPACE)); | 100 CHECK(Heap::InSpace(*array, OLD_POINTER_SPACE)); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 TEST(NoPromotion) { | 104 TEST(NoPromotion) { |
| 105 Heap::ConfigureHeap(2*256*KB, 4*MB); | 105 Heap::ConfigureHeap(2*256*KB, 4*MB); |
| 106 | 106 |
| 107 // Test the situation that some objects in new space are promoted to | 107 // Test the situation that some objects in new space are promoted to |
| 108 // the old space | 108 // the old space |
| 109 InitializeVM(); | 109 InitializeVM(); |
| 110 | 110 |
| 111 v8::HandleScope sc; | 111 v8::HandleScope sc; |
| 112 | 112 |
| 113 // Do a mark compact GC to shrink the heap. | 113 // Do a mark compact GC to shrink the heap. |
| 114 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 114 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 115 | 115 |
| 116 // Allocate a big Fixed array in the new space. | 116 // Allocate a big Fixed array in the new space. |
| 117 int size = (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / | 117 int size = (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) / |
| 118 kPointerSize; | 118 kPointerSize; |
| 119 Object* obj = Heap::AllocateFixedArray(size); | 119 Object* obj = Heap::AllocateFixedArray(size); |
| 120 | 120 |
| 121 Handle<FixedArray> array(FixedArray::cast(obj)); | 121 Handle<FixedArray> array(FixedArray::cast(obj)); |
| 122 | 122 |
| 123 // Array still stays in the new space. | 123 // Array still stays in the new space. |
| 124 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 124 CHECK(Heap::InSpace(*array, NEW_SPACE)); |
| 125 | 125 |
| 126 // Allocate objects in the old space until out of memory. | 126 // Allocate objects in the old space until out of memory. |
| 127 FixedArray* host = *array; | 127 FixedArray* host = *array; |
| 128 while (true) { | 128 while (true) { |
| 129 Object* obj = Heap::AllocateFixedArray(100, TENURED); | 129 Object* obj = Heap::AllocateFixedArray(100, TENURED); |
| 130 if (obj->IsFailure()) break; | 130 if (obj->IsFailure()) break; |
| 131 | 131 |
| 132 host->set(0, obj); | 132 host->set(0, obj); |
| 133 host = FixedArray::cast(obj); | 133 host = FixedArray::cast(obj); |
| 134 } | 134 } |
| 135 | 135 |
| 136 // Call mark compact GC, and it should pass. | 136 // Call mark compact GC, and it should pass. |
| 137 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 137 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 138 | 138 |
| 139 // array should not be promoted because the old space is full. | 139 // array should not be promoted because the old space is full. |
| 140 CHECK(Heap::InSpace(*array, NEW_SPACE)); | 140 CHECK(Heap::InSpace(*array, NEW_SPACE)); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 TEST(MarkCompactCollector) { | 144 TEST(MarkCompactCollector) { |
| 145 InitializeVM(); | 145 InitializeVM(); |
| 146 | 146 |
| 147 v8::HandleScope sc; | 147 v8::HandleScope sc; |
| 148 // call mark-compact when heap is empty | 148 // call mark-compact when heap is empty |
| 149 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 149 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 150 | 150 |
| 151 // keep allocating garbage in new space until it fails | 151 // keep allocating garbage in new space until it fails |
| 152 const int ARRAY_SIZE = 100; | 152 const int ARRAY_SIZE = 100; |
| 153 Object* array; | 153 Object* array; |
| 154 do { | 154 do { |
| 155 array = Heap::AllocateFixedArray(ARRAY_SIZE); | 155 array = Heap::AllocateFixedArray(ARRAY_SIZE); |
| 156 } while (!array->IsFailure()); | 156 } while (!array->IsFailure()); |
| 157 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 157 Heap::CollectGarbage(NEW_SPACE); |
| 158 | 158 |
| 159 array = Heap::AllocateFixedArray(ARRAY_SIZE); | 159 array = Heap::AllocateFixedArray(ARRAY_SIZE); |
| 160 CHECK(!array->IsFailure()); | 160 CHECK(!array->IsFailure()); |
| 161 | 161 |
| 162 // keep allocating maps until it fails | 162 // keep allocating maps until it fails |
| 163 Object* mapp; | 163 Object* mapp; |
| 164 do { | 164 do { |
| 165 mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 165 mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 166 } while (!mapp->IsFailure()); | 166 } while (!mapp->IsFailure()); |
| 167 CHECK(Heap::CollectGarbage(0, MAP_SPACE)); | 167 Heap::CollectGarbage(MAP_SPACE); |
| 168 mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 168 mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 169 CHECK(!mapp->IsFailure()); | 169 CHECK(!mapp->IsFailure()); |
| 170 | 170 |
| 171 // allocate a garbage | 171 // allocate a garbage |
| 172 String* func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 172 String* func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); |
| 173 SharedFunctionInfo* function_share = | 173 SharedFunctionInfo* function_share = |
| 174 SharedFunctionInfo::cast(Heap::AllocateSharedFunctionInfo(func_name)); | 174 SharedFunctionInfo::cast(Heap::AllocateSharedFunctionInfo(func_name)); |
| 175 JSFunction* function = | 175 JSFunction* function = |
| 176 JSFunction::cast(Heap::AllocateFunction(*Top::function_map(), | 176 JSFunction::cast(Heap::AllocateFunction(*Top::function_map(), |
| 177 function_share, | 177 function_share, |
| 178 Heap::undefined_value())); | 178 Heap::undefined_value())); |
| 179 Map* initial_map = | 179 Map* initial_map = |
| 180 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)); | 180 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)); |
| 181 function->set_initial_map(initial_map); | 181 function->set_initial_map(initial_map); |
| 182 Top::context()->global()->SetProperty(func_name, function, NONE); | 182 Top::context()->global()->SetProperty(func_name, function, NONE); |
| 183 | 183 |
| 184 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function)); | 184 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function)); |
| 185 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 185 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 186 | 186 |
| 187 func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 187 func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); |
| 188 CHECK(Top::context()->global()->HasLocalProperty(func_name)); | 188 CHECK(Top::context()->global()->HasLocalProperty(func_name)); |
| 189 Object* func_value = Top::context()->global()->GetProperty(func_name); | 189 Object* func_value = Top::context()->global()->GetProperty(func_name); |
| 190 CHECK(func_value->IsJSFunction()); | 190 CHECK(func_value->IsJSFunction()); |
| 191 function = JSFunction::cast(func_value); | 191 function = JSFunction::cast(func_value); |
| 192 | 192 |
| 193 obj = JSObject::cast(Heap::AllocateJSObject(function)); | 193 obj = JSObject::cast(Heap::AllocateJSObject(function)); |
| 194 String* obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); | 194 String* obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); |
| 195 Top::context()->global()->SetProperty(obj_name, obj, NONE); | 195 Top::context()->global()->SetProperty(obj_name, obj, NONE); |
| 196 String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 196 String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); |
| 197 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); | 197 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); |
| 198 | 198 |
| 199 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 199 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 200 | 200 |
| 201 obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); | 201 obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); |
| 202 CHECK(Top::context()->global()->HasLocalProperty(obj_name)); | 202 CHECK(Top::context()->global()->HasLocalProperty(obj_name)); |
| 203 CHECK(Top::context()->global()->GetProperty(obj_name)->IsJSObject()); | 203 CHECK(Top::context()->global()->GetProperty(obj_name)->IsJSObject()); |
| 204 obj = JSObject::cast(Top::context()->global()->GetProperty(obj_name)); | 204 obj = JSObject::cast(Top::context()->global()->GetProperty(obj_name)); |
| 205 prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 205 prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); |
| 206 CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23)); | 206 CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23)); |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 | 257 |
| 258 Heap::SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); | 258 Heap::SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); |
| 259 Heap::SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); | 259 Heap::SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); |
| 260 | 260 |
| 261 // Scavenge does not call GC callback functions. | 261 // Scavenge does not call GC callback functions. |
| 262 Heap::PerformScavenge(); | 262 Heap::PerformScavenge(); |
| 263 | 263 |
| 264 CHECK_EQ(0, gc_starts); | 264 CHECK_EQ(0, gc_starts); |
| 265 CHECK_EQ(gc_ends, gc_starts); | 265 CHECK_EQ(gc_ends, gc_starts); |
| 266 | 266 |
| 267 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 267 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 268 CHECK_EQ(1, gc_starts); | 268 CHECK_EQ(1, gc_starts); |
| 269 CHECK_EQ(gc_ends, gc_starts); | 269 CHECK_EQ(gc_ends, gc_starts); |
| 270 } | 270 } |
| 271 | 271 |
| 272 | 272 |
| 273 static int NumberOfWeakCalls = 0; | 273 static int NumberOfWeakCalls = 0; |
| 274 static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { | 274 static void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { |
| 275 NumberOfWeakCalls++; | 275 NumberOfWeakCalls++; |
| 276 handle.Dispose(); | 276 handle.Dispose(); |
| 277 } | 277 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); | 310 Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); |
| 311 Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); | 311 Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); |
| 312 | 312 |
| 313 { | 313 { |
| 314 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 314 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
| 315 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 315 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
| 316 GlobalHandles::AddGroup(g1_objects, 2); | 316 GlobalHandles::AddGroup(g1_objects, 2); |
| 317 GlobalHandles::AddGroup(g2_objects, 2); | 317 GlobalHandles::AddGroup(g2_objects, 2); |
| 318 } | 318 } |
| 319 // Do a full GC | 319 // Do a full GC |
| 320 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 320 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 321 | 321 |
| 322 // All object should be alive. | 322 // All object should be alive. |
| 323 CHECK_EQ(0, NumberOfWeakCalls); | 323 CHECK_EQ(0, NumberOfWeakCalls); |
| 324 | 324 |
| 325 // Weaken the root. | 325 // Weaken the root. |
| 326 GlobalHandles::MakeWeak(root.location(), | 326 GlobalHandles::MakeWeak(root.location(), |
| 327 reinterpret_cast<void*>(1234), | 327 reinterpret_cast<void*>(1234), |
| 328 &WeakPointerCallback); | 328 &WeakPointerCallback); |
| 329 | 329 |
| 330 // Groups are deleted, rebuild groups. | 330 // Groups are deleted, rebuild groups. |
| 331 { | 331 { |
| 332 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 332 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
| 333 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 333 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
| 334 GlobalHandles::AddGroup(g1_objects, 2); | 334 GlobalHandles::AddGroup(g1_objects, 2); |
| 335 GlobalHandles::AddGroup(g2_objects, 2); | 335 GlobalHandles::AddGroup(g2_objects, 2); |
| 336 } | 336 } |
| 337 | 337 |
| 338 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 338 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 339 | 339 |
| 340 // All objects should be gone. 5 global handles in total. | 340 // All objects should be gone. 5 global handles in total. |
| 341 CHECK_EQ(5, NumberOfWeakCalls); | 341 CHECK_EQ(5, NumberOfWeakCalls); |
| 342 } | 342 } |
| OLD | NEW |