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 | 2 |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "execution.h" | 7 #include "execution.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
10 #include "global-handles.h" | 10 #include "global-handles.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 170 |
171 CheckFindCodeObject(); | 171 CheckFindCodeObject(); |
172 } | 172 } |
173 | 173 |
174 | 174 |
175 TEST(Tagging) { | 175 TEST(Tagging) { |
176 InitializeVM(); | 176 InitializeVM(); |
177 int request = 24; | 177 int request = 24; |
178 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); | 178 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); |
179 CHECK(Smi::FromInt(42)->IsSmi()); | 179 CHECK(Smi::FromInt(42)->IsSmi()); |
180 CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure()); | 180 CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure()); |
181 CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested()); | |
182 CHECK_EQ(NEW_SPACE, | 181 CHECK_EQ(NEW_SPACE, |
183 Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space()); | 182 Failure::RetryAfterGC(NEW_SPACE)->allocation_space()); |
184 CHECK_EQ(OLD_POINTER_SPACE, | 183 CHECK_EQ(OLD_POINTER_SPACE, |
185 Failure::RetryAfterGC(request, | 184 Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space()); |
186 OLD_POINTER_SPACE)->allocation_space()); | |
187 CHECK(Failure::Exception()->IsFailure()); | 185 CHECK(Failure::Exception()->IsFailure()); |
188 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); | 186 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); |
189 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); | 187 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); |
190 } | 188 } |
191 | 189 |
192 | 190 |
193 TEST(GarbageCollection) { | 191 TEST(GarbageCollection) { |
194 InitializeVM(); | 192 InitializeVM(); |
195 | 193 |
196 v8::HandleScope sc; | 194 v8::HandleScope sc; |
197 // Check GC. | 195 // Check GC. |
198 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); | 196 Heap::CollectGarbage(NEW_SPACE); |
199 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | |
200 | 197 |
201 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); | 198 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
202 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); | 199 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
203 Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx"); | 200 Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx"); |
204 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); | 201 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); |
205 | 202 |
206 { | 203 { |
207 v8::HandleScope inner_scope; | 204 v8::HandleScope inner_scope; |
208 // Allocate a function and keep it in global object's property. | 205 // Allocate a function and keep it in global object's property. |
209 Handle<JSFunction> function = | 206 Handle<JSFunction> function = |
210 Factory::NewFunction(name, Factory::undefined_value()); | 207 Factory::NewFunction(name, Factory::undefined_value()); |
211 Handle<Map> initial_map = | 208 Handle<Map> initial_map = |
212 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 209 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
213 function->set_initial_map(*initial_map); | 210 function->set_initial_map(*initial_map); |
214 Top::context()->global()->SetProperty(*name, *function, NONE); | 211 Top::context()->global()->SetProperty(*name, *function, NONE); |
215 // Allocate an object. Unrooted after leaving the scope. | 212 // Allocate an object. Unrooted after leaving the scope. |
216 Handle<JSObject> obj = Factory::NewJSObject(function); | 213 Handle<JSObject> obj = Factory::NewJSObject(function); |
217 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 214 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
218 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); | 215 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); |
219 | 216 |
220 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 217 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
221 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); | 218 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); |
222 } | 219 } |
223 | 220 |
224 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 221 Heap::CollectGarbage(NEW_SPACE); |
225 | 222 |
226 // Function should be alive. | 223 // Function should be alive. |
227 CHECK(Top::context()->global()->HasLocalProperty(*name)); | 224 CHECK(Top::context()->global()->HasLocalProperty(*name)); |
228 // Check function is retained. | 225 // Check function is retained. |
229 Object* func_value = Top::context()->global()->GetProperty(*name); | 226 Object* func_value = Top::context()->global()->GetProperty(*name); |
230 CHECK(func_value->IsJSFunction()); | 227 CHECK(func_value->IsJSFunction()); |
231 Handle<JSFunction> function(JSFunction::cast(func_value)); | 228 Handle<JSFunction> function(JSFunction::cast(func_value)); |
232 | 229 |
233 { | 230 { |
234 HandleScope inner_scope; | 231 HandleScope inner_scope; |
235 // Allocate another object, make it reachable from global. | 232 // Allocate another object, make it reachable from global. |
236 Handle<JSObject> obj = Factory::NewJSObject(function); | 233 Handle<JSObject> obj = Factory::NewJSObject(function); |
237 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); | 234 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); |
238 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 235 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
239 } | 236 } |
240 | 237 |
241 // After gc, it should survive. | 238 // After gc, it should survive. |
242 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 239 Heap::CollectGarbage(NEW_SPACE); |
243 | 240 |
244 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); | 241 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); |
245 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); | 242 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); |
246 JSObject* obj = | 243 JSObject* obj = |
247 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); | 244 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); |
248 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 245 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
249 } | 246 } |
250 | 247 |
251 | 248 |
252 static void VerifyStringAllocation(const char* string) { | 249 static void VerifyStringAllocation(const char* string) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); | 291 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
295 Handle<Object> u = Factory::NewNumber(1.12344); | 292 Handle<Object> u = Factory::NewNumber(1.12344); |
296 | 293 |
297 h1 = GlobalHandles::Create(*i); | 294 h1 = GlobalHandles::Create(*i); |
298 h2 = GlobalHandles::Create(*u); | 295 h2 = GlobalHandles::Create(*u); |
299 h3 = GlobalHandles::Create(*i); | 296 h3 = GlobalHandles::Create(*i); |
300 h4 = GlobalHandles::Create(*u); | 297 h4 = GlobalHandles::Create(*u); |
301 } | 298 } |
302 | 299 |
303 // after gc, it should survive | 300 // after gc, it should survive |
304 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 301 Heap::CollectGarbage(NEW_SPACE); |
305 | 302 |
306 CHECK((*h1)->IsString()); | 303 CHECK((*h1)->IsString()); |
307 CHECK((*h2)->IsHeapNumber()); | 304 CHECK((*h2)->IsHeapNumber()); |
308 CHECK((*h3)->IsString()); | 305 CHECK((*h3)->IsString()); |
309 CHECK((*h4)->IsHeapNumber()); | 306 CHECK((*h4)->IsHeapNumber()); |
310 | 307 |
311 CHECK_EQ(*h3, *h1); | 308 CHECK_EQ(*h3, *h1); |
312 GlobalHandles::Destroy(h1.location()); | 309 GlobalHandles::Destroy(h1.location()); |
313 GlobalHandles::Destroy(h3.location()); | 310 GlobalHandles::Destroy(h3.location()); |
314 | 311 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 { | 372 { |
376 HandleScope scope; | 373 HandleScope scope; |
377 | 374 |
378 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); | 375 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
379 Handle<Object> u = Factory::NewNumber(1.12344); | 376 Handle<Object> u = Factory::NewNumber(1.12344); |
380 | 377 |
381 h1 = GlobalHandles::Create(*i); | 378 h1 = GlobalHandles::Create(*i); |
382 h2 = GlobalHandles::Create(*u); | 379 h2 = GlobalHandles::Create(*u); |
383 } | 380 } |
384 | 381 |
385 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 382 Heap::CollectGarbage(OLD_POINTER_SPACE); |
386 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 383 Heap::CollectGarbage(NEW_SPACE); |
387 // Make sure the object is promoted. | 384 // Make sure the object is promoted. |
388 | 385 |
389 GlobalHandles::MakeWeak(h2.location(), | 386 GlobalHandles::MakeWeak(h2.location(), |
390 reinterpret_cast<void*>(1234), | 387 reinterpret_cast<void*>(1234), |
391 &TestWeakGlobalHandleCallback); | 388 &TestWeakGlobalHandleCallback); |
392 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 389 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
393 CHECK(!GlobalHandles::IsNearDeath(h2.location())); | 390 CHECK(!GlobalHandles::IsNearDeath(h2.location())); |
394 | 391 |
395 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 392 Heap::CollectGarbage(OLD_POINTER_SPACE); |
396 | 393 |
397 CHECK((*h1)->IsString()); | 394 CHECK((*h1)->IsString()); |
398 | 395 |
399 CHECK(WeakPointerCleared); | 396 CHECK(WeakPointerCleared); |
400 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 397 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
401 | 398 |
402 GlobalHandles::Destroy(h1.location()); | 399 GlobalHandles::Destroy(h1.location()); |
403 } | 400 } |
404 | 401 |
405 TEST(DeleteWeakGlobalHandle) { | 402 TEST(DeleteWeakGlobalHandle) { |
(...skipping 13 matching lines...) Expand all Loading... |
419 GlobalHandles::MakeWeak(h.location(), | 416 GlobalHandles::MakeWeak(h.location(), |
420 reinterpret_cast<void*>(1234), | 417 reinterpret_cast<void*>(1234), |
421 &TestWeakGlobalHandleCallback); | 418 &TestWeakGlobalHandleCallback); |
422 | 419 |
423 // Scanvenge does not recognize weak reference. | 420 // Scanvenge does not recognize weak reference. |
424 Heap::PerformScavenge(); | 421 Heap::PerformScavenge(); |
425 | 422 |
426 CHECK(!WeakPointerCleared); | 423 CHECK(!WeakPointerCleared); |
427 | 424 |
428 // Mark-compact treats weak reference properly. | 425 // Mark-compact treats weak reference properly. |
429 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 426 Heap::CollectGarbage(OLD_POINTER_SPACE); |
430 | 427 |
431 CHECK(WeakPointerCleared); | 428 CHECK(WeakPointerCleared); |
432 } | 429 } |
433 | 430 |
434 static const char* not_so_random_string_table[] = { | 431 static const char* not_so_random_string_table[] = { |
435 "abstract", | 432 "abstract", |
436 "boolean", | 433 "boolean", |
437 "break", | 434 "break", |
438 "byte", | 435 "byte", |
439 "case", | 436 "case", |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); | 804 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); |
808 | 805 |
809 CHECK_EQ(objs_count, next_objs_index); | 806 CHECK_EQ(objs_count, next_objs_index); |
810 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); | 807 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); |
811 } | 808 } |
812 | 809 |
813 | 810 |
814 TEST(LargeObjectSpaceContains) { | 811 TEST(LargeObjectSpaceContains) { |
815 InitializeVM(); | 812 InitializeVM(); |
816 | 813 |
817 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); | 814 Heap::CollectGarbage(NEW_SPACE); |
818 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | |
819 | 815 |
820 Address current_top = Heap::new_space()->top(); | 816 Address current_top = Heap::new_space()->top(); |
821 Page* page = Page::FromAddress(current_top); | 817 Page* page = Page::FromAddress(current_top); |
822 Address current_page = page->address(); | 818 Address current_page = page->address(); |
823 Address next_page = current_page + Page::kPageSize; | 819 Address next_page = current_page + Page::kPageSize; |
824 int bytes_to_page = static_cast<int>(next_page - current_top); | 820 int bytes_to_page = static_cast<int>(next_page - current_top); |
825 if (bytes_to_page <= FixedArray::kHeaderSize) { | 821 if (bytes_to_page <= FixedArray::kHeaderSize) { |
826 // Alas, need to cross another page to be able to | 822 // Alas, need to cross another page to be able to |
827 // put desired value. | 823 // put desired value. |
828 next_page += Page::kPageSize; | 824 next_page += Page::kPageSize; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 Heap::CollectAllGarbage(true); | 990 Heap::CollectAllGarbage(true); |
995 | 991 |
996 // foo should no longer be in the compilation cache | 992 // foo should no longer be in the compilation cache |
997 CHECK(!function->shared()->is_compiled()); | 993 CHECK(!function->shared()->is_compiled()); |
998 CHECK(!function->is_compiled()); | 994 CHECK(!function->is_compiled()); |
999 // Call foo to get it recompiled. | 995 // Call foo to get it recompiled. |
1000 CompileRun("foo()"); | 996 CompileRun("foo()"); |
1001 CHECK(function->shared()->is_compiled()); | 997 CHECK(function->shared()->is_compiled()); |
1002 CHECK(function->is_compiled()); | 998 CHECK(function->is_compiled()); |
1003 } | 999 } |
OLD | NEW |