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 25 matching lines...) Expand all Loading... |
36 #endif | 36 #endif |
37 | 37 |
38 #include "v8.h" | 38 #include "v8.h" |
39 | 39 |
40 #include "global-handles.h" | 40 #include "global-handles.h" |
41 #include "snapshot.h" | 41 #include "snapshot.h" |
42 #include "cctest.h" | 42 #include "cctest.h" |
43 | 43 |
44 using namespace v8::internal; | 44 using namespace v8::internal; |
45 | 45 |
46 using v8::UniqueId; | |
47 | |
48 | 46 |
49 TEST(MarkingDeque) { | 47 TEST(MarkingDeque) { |
50 CcTest::InitializeVM(); | 48 CcTest::InitializeVM(); |
51 int mem_size = 20 * kPointerSize; | 49 int mem_size = 20 * kPointerSize; |
52 byte* mem = NewArray<byte>(20*kPointerSize); | 50 byte* mem = NewArray<byte>(20*kPointerSize); |
53 Address low = reinterpret_cast<Address>(mem); | 51 Address low = reinterpret_cast<Address>(mem); |
54 Address high = low + mem_size; | 52 Address high = low + mem_size; |
55 MarkingDeque s; | 53 MarkingDeque s; |
56 s.Initialize(low, high); | 54 s.Initialize(low, high); |
57 | 55 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 | 299 |
302 static int NumberOfWeakCalls = 0; | 300 static int NumberOfWeakCalls = 0; |
303 static void WeakPointerCallback(v8::Isolate* isolate, | 301 static void WeakPointerCallback(v8::Isolate* isolate, |
304 v8::Persistent<v8::Value> handle, | 302 v8::Persistent<v8::Value> handle, |
305 void* id) { | 303 void* id) { |
306 ASSERT(id == reinterpret_cast<void*>(1234)); | 304 ASSERT(id == reinterpret_cast<void*>(1234)); |
307 NumberOfWeakCalls++; | 305 NumberOfWeakCalls++; |
308 handle.Dispose(isolate); | 306 handle.Dispose(isolate); |
309 } | 307 } |
310 | 308 |
311 TEST(ObjectGroupsOldApi) { | 309 TEST(ObjectGroups) { |
312 FLAG_incremental_marking = false; | 310 FLAG_incremental_marking = false; |
313 CcTest::InitializeVM(); | 311 CcTest::InitializeVM(); |
314 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 312 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
315 | 313 |
316 NumberOfWeakCalls = 0; | 314 NumberOfWeakCalls = 0; |
317 v8::HandleScope handle_scope(CcTest::isolate()); | 315 v8::HandleScope handle_scope(CcTest::isolate()); |
318 | 316 |
319 Handle<Object> g1s1 = | 317 Handle<Object> g1s1 = |
320 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); | 318 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
321 Handle<Object> g1s2 = | 319 Handle<Object> g1s2 = |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 { | 361 { |
364 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 362 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
365 Object** g1_children[] = { g1c1.location() }; | 363 Object** g1_children[] = { g1c1.location() }; |
366 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 364 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
367 Object** g2_children[] = { g2c1.location() }; | 365 Object** g2_children[] = { g2c1.location() }; |
368 global_handles->AddObjectGroup(g1_objects, 2, NULL); | 366 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
369 global_handles->AddImplicitReferences( | 367 global_handles->AddImplicitReferences( |
370 Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); | 368 Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); |
371 global_handles->AddObjectGroup(g2_objects, 2, NULL); | 369 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
372 global_handles->AddImplicitReferences( | 370 global_handles->AddImplicitReferences( |
373 Handle<HeapObject>::cast(g2s1).location(), g2_children, 1); | 371 Handle<HeapObject>::cast(g2s2).location(), g2_children, 1); |
374 } | 372 } |
375 // Do a full GC | 373 // Do a full GC |
376 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 374 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
377 | 375 |
378 // All object should be alive. | 376 // All object should be alive. |
379 CHECK_EQ(0, NumberOfWeakCalls); | 377 CHECK_EQ(0, NumberOfWeakCalls); |
380 | 378 |
381 // Weaken the root. | 379 // Weaken the root. |
382 global_handles->MakeWeak(root.location(), | 380 global_handles->MakeWeak(root.location(), |
383 reinterpret_cast<void*>(1234), | 381 reinterpret_cast<void*>(1234), |
384 NULL, | 382 NULL, |
385 &WeakPointerCallback); | 383 &WeakPointerCallback); |
386 // But make children strong roots---all the objects (except for children) | 384 // But make children strong roots---all the objects (except for children) |
387 // should be collectable now. | 385 // should be collectable now. |
388 global_handles->ClearWeakness(g1c1.location()); | 386 global_handles->ClearWeakness(g1c1.location()); |
389 global_handles->ClearWeakness(g2c1.location()); | 387 global_handles->ClearWeakness(g2c1.location()); |
390 | 388 |
391 // Groups are deleted, rebuild groups. | 389 // Groups are deleted, rebuild groups. |
392 { | 390 { |
393 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; | 391 Object** g1_objects[] = { g1s1.location(), g1s2.location() }; |
394 Object** g1_children[] = { g1c1.location() }; | 392 Object** g1_children[] = { g1c1.location() }; |
395 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; | 393 Object** g2_objects[] = { g2s1.location(), g2s2.location() }; |
396 Object** g2_children[] = { g2c1.location() }; | 394 Object** g2_children[] = { g2c1.location() }; |
397 global_handles->AddObjectGroup(g1_objects, 2, NULL); | 395 global_handles->AddObjectGroup(g1_objects, 2, NULL); |
398 global_handles->AddImplicitReferences( | 396 global_handles->AddImplicitReferences( |
399 Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); | 397 Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); |
400 global_handles->AddObjectGroup(g2_objects, 2, NULL); | 398 global_handles->AddObjectGroup(g2_objects, 2, NULL); |
401 global_handles->AddImplicitReferences( | 399 global_handles->AddImplicitReferences( |
402 Handle<HeapObject>::cast(g2s1).location(), g2_children, 1); | 400 Handle<HeapObject>::cast(g2s2).location(), g2_children, 1); |
403 } | 401 } |
404 | 402 |
405 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 403 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
406 | 404 |
407 // All objects should be gone. 5 global handles in total. | 405 // All objects should be gone. 5 global handles in total. |
408 CHECK_EQ(5, NumberOfWeakCalls); | 406 CHECK_EQ(5, NumberOfWeakCalls); |
409 | 407 |
410 // And now make children weak again and collect them. | 408 // And now make children weak again and collect them. |
411 global_handles->MakeWeak(g1c1.location(), | 409 global_handles->MakeWeak(g1c1.location(), |
412 reinterpret_cast<void*>(1234), | 410 reinterpret_cast<void*>(1234), |
413 NULL, | 411 NULL, |
414 &WeakPointerCallback); | 412 &WeakPointerCallback); |
415 global_handles->MakeWeak(g2c1.location(), | 413 global_handles->MakeWeak(g2c1.location(), |
416 reinterpret_cast<void*>(1234), | 414 reinterpret_cast<void*>(1234), |
417 NULL, | 415 NULL, |
418 &WeakPointerCallback); | 416 &WeakPointerCallback); |
419 | 417 |
420 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 418 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
421 CHECK_EQ(7, NumberOfWeakCalls); | 419 CHECK_EQ(7, NumberOfWeakCalls); |
422 } | 420 } |
423 | 421 |
424 TEST(ObjectGroups) { | |
425 FLAG_incremental_marking = false; | |
426 CcTest::InitializeVM(); | |
427 GlobalHandles* global_handles = reinterpret_cast<v8::internal::Isolate*>( | |
428 CcTest::isolate())->global_handles(); | |
429 | |
430 NumberOfWeakCalls = 0; | |
431 v8::HandleScope handle_scope(CcTest::isolate()); | |
432 | |
433 Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | |
434 CcTest::isolate())->heap(); | |
435 Handle<Object> g1s1 = | |
436 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
437 Handle<Object> g1s2 = | |
438 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
439 Handle<Object> g1c1 = | |
440 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
441 global_handles->MakeWeak(g1s1.location(), | |
442 reinterpret_cast<void*>(1234), | |
443 NULL, | |
444 &WeakPointerCallback); | |
445 global_handles->MakeWeak(g1s2.location(), | |
446 reinterpret_cast<void*>(1234), | |
447 NULL, | |
448 &WeakPointerCallback); | |
449 global_handles->MakeWeak(g1c1.location(), | |
450 reinterpret_cast<void*>(1234), | |
451 NULL, | |
452 &WeakPointerCallback); | |
453 | |
454 Handle<Object> g2s1 = | |
455 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
456 Handle<Object> g2s2 = | |
457 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
458 Handle<Object> g2c1 = | |
459 global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked()); | |
460 global_handles->MakeWeak(g2s1.location(), | |
461 reinterpret_cast<void*>(1234), | |
462 NULL, | |
463 &WeakPointerCallback); | |
464 global_handles->MakeWeak(g2s2.location(), | |
465 reinterpret_cast<void*>(1234), | |
466 NULL, | |
467 &WeakPointerCallback); | |
468 global_handles->MakeWeak(g2c1.location(), | |
469 reinterpret_cast<void*>(1234), | |
470 NULL, | |
471 &WeakPointerCallback); | |
472 | |
473 Handle<Object> root = global_handles->Create(*g1s1); // make a root. | |
474 | |
475 // Connect group 1 and 2, make a cycle. | |
476 Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); | |
477 Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); | |
478 | |
479 { | |
480 global_handles->SetObjectGroupId(g1s1.location(), v8::UniqueId(1)); | |
481 global_handles->SetObjectGroupId(g1s2.location(), v8::UniqueId(1)); | |
482 global_handles->SetObjectGroupRepresentative( | |
483 v8::UniqueId(1), reinterpret_cast<HeapObject**>(g1s1.location())); | |
484 global_handles->AddImplicitReference(v8::UniqueId(1), g1c1.location()); | |
485 global_handles->SetObjectGroupId(g2s1.location(), v8::UniqueId(2)); | |
486 global_handles->SetObjectGroupId(g2s2.location(), v8::UniqueId(2)); | |
487 global_handles->SetObjectGroupRepresentative( | |
488 v8::UniqueId(2), reinterpret_cast<HeapObject**>(g2s1.location())); | |
489 global_handles->AddImplicitReference(v8::UniqueId(2), g2c1.location()); | |
490 } | |
491 // Do a full GC | |
492 heap->CollectGarbage(OLD_POINTER_SPACE); | |
493 | |
494 // All object should be alive. | |
495 CHECK_EQ(0, NumberOfWeakCalls); | |
496 | |
497 // Weaken the root. | |
498 global_handles->MakeWeak(root.location(), | |
499 reinterpret_cast<void*>(1234), | |
500 NULL, | |
501 &WeakPointerCallback); | |
502 // But make children strong roots---all the objects (except for children) | |
503 // should be collectable now. | |
504 global_handles->ClearWeakness(g1c1.location()); | |
505 global_handles->ClearWeakness(g2c1.location()); | |
506 | |
507 // Groups are deleted, rebuild groups. | |
508 { | |
509 global_handles->SetObjectGroupId(g1s1.location(), v8::UniqueId(1)); | |
510 global_handles->SetObjectGroupId(g1s2.location(), v8::UniqueId(1)); | |
511 global_handles->SetObjectGroupRepresentative( | |
512 v8::UniqueId(1), reinterpret_cast<HeapObject**>(g1s1.location())); | |
513 global_handles->AddImplicitReference(v8::UniqueId(1), g1c1.location()); | |
514 global_handles->SetObjectGroupId(g2s1.location(), v8::UniqueId(2)); | |
515 global_handles->SetObjectGroupId(g2s2.location(), v8::UniqueId(2)); | |
516 global_handles->SetObjectGroupRepresentative( | |
517 v8::UniqueId(2), reinterpret_cast<HeapObject**>(g2s1.location())); | |
518 global_handles->AddImplicitReference(v8::UniqueId(2), g2c1.location()); | |
519 } | |
520 | |
521 heap->CollectGarbage(OLD_POINTER_SPACE); | |
522 | |
523 // All objects should be gone. 5 global handles in total. | |
524 CHECK_EQ(5, NumberOfWeakCalls); | |
525 | |
526 // And now make children weak again and collect them. | |
527 global_handles->MakeWeak(g1c1.location(), | |
528 reinterpret_cast<void*>(1234), | |
529 NULL, | |
530 &WeakPointerCallback); | |
531 global_handles->MakeWeak(g2c1.location(), | |
532 reinterpret_cast<void*>(1234), | |
533 NULL, | |
534 &WeakPointerCallback); | |
535 | |
536 heap->CollectGarbage(OLD_POINTER_SPACE); | |
537 CHECK_EQ(7, NumberOfWeakCalls); | |
538 } | |
539 | |
540 | 422 |
541 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { | 423 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { |
542 public: | 424 public: |
543 TestRetainedObjectInfo() : has_been_disposed_(false) {} | 425 TestRetainedObjectInfo() : has_been_disposed_(false) {} |
544 | 426 |
545 bool has_been_disposed() { return has_been_disposed_; } | 427 bool has_been_disposed() { return has_been_disposed_; } |
546 | 428 |
547 virtual void Dispose() { | 429 virtual void Dispose() { |
548 ASSERT(!has_been_disposed_); | 430 ASSERT(!has_been_disposed_); |
549 has_been_disposed_ = true; | 431 has_been_disposed_ = true; |
550 } | 432 } |
551 | 433 |
552 virtual bool IsEquivalent(v8::RetainedObjectInfo* other) { | 434 virtual bool IsEquivalent(v8::RetainedObjectInfo* other) { |
553 return other == this; | 435 return other == this; |
554 } | 436 } |
555 | 437 |
556 virtual intptr_t GetHash() { return 0; } | 438 virtual intptr_t GetHash() { return 0; } |
557 | 439 |
558 virtual const char* GetLabel() { return "whatever"; } | 440 virtual const char* GetLabel() { return "whatever"; } |
559 | 441 |
560 private: | 442 private: |
561 bool has_been_disposed_; | 443 bool has_been_disposed_; |
562 }; | 444 }; |
563 | 445 |
564 | 446 |
565 TEST(EmptyObjectGroupsOldApi) { | 447 TEST(EmptyObjectGroups) { |
566 CcTest::InitializeVM(); | 448 CcTest::InitializeVM(); |
567 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 449 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
568 | 450 |
569 v8::HandleScope handle_scope(CcTest::isolate()); | 451 v8::HandleScope handle_scope(CcTest::isolate()); |
570 | 452 |
571 Handle<Object> object = | 453 Handle<Object> object = |
572 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); | 454 global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); |
573 | 455 |
574 TestRetainedObjectInfo info; | 456 TestRetainedObjectInfo info; |
575 global_handles->AddObjectGroup(NULL, 0, &info); | 457 global_handles->AddObjectGroup(NULL, 0, &info); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 if (v8::internal::Snapshot::IsEnabled()) { | 558 if (v8::internal::Snapshot::IsEnabled()) { |
677 CHECK_LE(delta, 2900 * 1024); | 559 CHECK_LE(delta, 2900 * 1024); |
678 } else { | 560 } else { |
679 CHECK_LE(delta, 3400 * 1024); | 561 CHECK_LE(delta, 3400 * 1024); |
680 } | 562 } |
681 } | 563 } |
682 } | 564 } |
683 } | 565 } |
684 | 566 |
685 #endif // __linux__ and !USE_SIMULATOR | 567 #endif // __linux__ and !USE_SIMULATOR |
OLD | NEW |