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 |