Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: test/cctest/test-api.cc

Issue 101523002: Remove deprecated Persistent::MakeWeak usage from V8 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/d8.cc ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3427 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 int id() { return id_; } 3438 int id() { return id_; }
3439 void increment() { number_of_weak_calls_++; } 3439 void increment() { number_of_weak_calls_++; }
3440 int NumberOfWeakCalls() { return number_of_weak_calls_; } 3440 int NumberOfWeakCalls() { return number_of_weak_calls_; }
3441 private: 3441 private:
3442 int id_; 3442 int id_;
3443 int number_of_weak_calls_; 3443 int number_of_weak_calls_;
3444 }; 3444 };
3445 3445
3446 3446
3447 template<typename T> 3447 template<typename T>
3448 static void WeakPointerCallback(v8::Isolate* isolate, 3448 struct WeakCallCounterAndPersistent {
3449 Persistent<T>* handle, 3449 explicit WeakCallCounterAndPersistent(WeakCallCounter* counter)
3450 WeakCallCounter* counter) { 3450 : counter(counter) {}
3451 CHECK_EQ(1234, counter->id()); 3451 WeakCallCounter* counter;
3452 counter->increment(); 3452 v8::Persistent<T> handle;
3453 handle->Reset(); 3453 };
3454
3455
3456 template <typename T>
3457 static void WeakPointerCallback(
3458 const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T> >& data) {
3459 CHECK_EQ(1234, data.GetParameter()->counter->id());
3460 data.GetParameter()->counter->increment();
3461 data.GetParameter()->handle.Reset();
3454 } 3462 }
3455 3463
3456 3464
3457 template<typename T> 3465 template<typename T>
3458 static UniqueId MakeUniqueId(const Persistent<T>& p) { 3466 static UniqueId MakeUniqueId(const Persistent<T>& p) {
3459 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); 3467 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
3460 } 3468 }
3461 3469
3462 3470
3463 THREADED_TEST(ApiObjectGroups) { 3471 THREADED_TEST(ApiObjectGroups) {
3464 LocalContext env; 3472 LocalContext env;
3465 v8::Isolate* iso = env->GetIsolate(); 3473 v8::Isolate* iso = env->GetIsolate();
3466 HandleScope scope(iso); 3474 HandleScope scope(iso);
3467 3475
3468 Persistent<Value> g1s1; 3476 WeakCallCounter counter(1234);
3469 Persistent<Value> g1s2;
3470 Persistent<Value> g1c1;
3471 Persistent<Value> g2s1;
3472 Persistent<Value> g2s2;
3473 Persistent<Value> g2c1;
3474 3477
3475 WeakCallCounter counter(1234); 3478 WeakCallCounterAndPersistent<Value> g1s1(&counter);
3479 WeakCallCounterAndPersistent<Value> g1s2(&counter);
3480 WeakCallCounterAndPersistent<Value> g1c1(&counter);
3481 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3482 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3483 WeakCallCounterAndPersistent<Value> g2c1(&counter);
3476 3484
3477 { 3485 {
3478 HandleScope scope(iso); 3486 HandleScope scope(iso);
3479 g1s1.Reset(iso, Object::New()); 3487 g1s1.handle.Reset(iso, Object::New());
3480 g1s2.Reset(iso, Object::New()); 3488 g1s2.handle.Reset(iso, Object::New());
3481 g1c1.Reset(iso, Object::New()); 3489 g1c1.handle.Reset(iso, Object::New());
3482 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3490 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
3483 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3491 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
3484 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3492 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
3485 3493
3486 g2s1.Reset(iso, Object::New()); 3494 g2s1.handle.Reset(iso, Object::New());
3487 g2s2.Reset(iso, Object::New()); 3495 g2s2.handle.Reset(iso, Object::New());
3488 g2c1.Reset(iso, Object::New()); 3496 g2c1.handle.Reset(iso, Object::New());
3489 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3497 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
3490 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3498 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
3491 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3499 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
3492 } 3500 }
3493 3501
3494 Persistent<Value> root(iso, g1s1); // make a root. 3502 WeakCallCounterAndPersistent<Value> root(&counter);
3503 root.handle.Reset(iso, g1s1.handle); // make a root.
3495 3504
3496 // Connect group 1 and 2, make a cycle. 3505 // Connect group 1 and 2, make a cycle.
3497 { 3506 {
3498 HandleScope scope(iso); 3507 HandleScope scope(iso);
3499 CHECK(Local<Object>::New(iso, g1s2.As<Object>())-> 3508 CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())->
3500 Set(0, Local<Value>::New(iso, g2s2))); 3509 Set(0, Local<Value>::New(iso, g2s2.handle)));
3501 CHECK(Local<Object>::New(iso, g2s1.As<Object>())-> 3510 CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())->
3502 Set(0, Local<Value>::New(iso, g1s1))); 3511 Set(0, Local<Value>::New(iso, g1s1.handle)));
3503 } 3512 }
3504 3513
3505 { 3514 {
3506 UniqueId id1 = MakeUniqueId(g1s1); 3515 UniqueId id1 = MakeUniqueId(g1s1.handle);
3507 UniqueId id2 = MakeUniqueId(g2s2); 3516 UniqueId id2 = MakeUniqueId(g2s2.handle);
3508 iso->SetObjectGroupId(g1s1, id1); 3517 iso->SetObjectGroupId(g1s1.handle, id1);
3509 iso->SetObjectGroupId(g1s2, id1); 3518 iso->SetObjectGroupId(g1s2.handle, id1);
3510 iso->SetReferenceFromGroup(id1, g1c1); 3519 iso->SetReferenceFromGroup(id1, g1c1.handle);
3511 iso->SetObjectGroupId(g2s1, id2); 3520 iso->SetObjectGroupId(g2s1.handle, id2);
3512 iso->SetObjectGroupId(g2s2, id2); 3521 iso->SetObjectGroupId(g2s2.handle, id2);
3513 iso->SetReferenceFromGroup(id2, g2c1); 3522 iso->SetReferenceFromGroup(id2, g2c1.handle);
3514 } 3523 }
3515 // Do a single full GC, ensure incremental marking is stopped. 3524 // Do a single full GC, ensure incremental marking is stopped.
3516 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3525 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3517 iso)->heap(); 3526 iso)->heap();
3518 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3527 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3519 3528
3520 // All object should be alive. 3529 // All object should be alive.
3521 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3530 CHECK_EQ(0, counter.NumberOfWeakCalls());
3522 3531
3523 // Weaken the root. 3532 // Weaken the root.
3524 root.MakeWeak(&counter, &WeakPointerCallback); 3533 root.handle.SetWeak(&root, &WeakPointerCallback);
3525 // But make children strong roots---all the objects (except for children) 3534 // But make children strong roots---all the objects (except for children)
3526 // should be collectable now. 3535 // should be collectable now.
3527 g1c1.ClearWeak(); 3536 g1c1.handle.ClearWeak();
3528 g2c1.ClearWeak(); 3537 g2c1.handle.ClearWeak();
3529 3538
3530 // Groups are deleted, rebuild groups. 3539 // Groups are deleted, rebuild groups.
3531 { 3540 {
3532 UniqueId id1 = MakeUniqueId(g1s1); 3541 UniqueId id1 = MakeUniqueId(g1s1.handle);
3533 UniqueId id2 = MakeUniqueId(g2s2); 3542 UniqueId id2 = MakeUniqueId(g2s2.handle);
3534 iso->SetObjectGroupId(g1s1, id1); 3543 iso->SetObjectGroupId(g1s1.handle, id1);
3535 iso->SetObjectGroupId(g1s2, id1); 3544 iso->SetObjectGroupId(g1s2.handle, id1);
3536 iso->SetReferenceFromGroup(id1, g1c1); 3545 iso->SetReferenceFromGroup(id1, g1c1.handle);
3537 iso->SetObjectGroupId(g2s1, id2); 3546 iso->SetObjectGroupId(g2s1.handle, id2);
3538 iso->SetObjectGroupId(g2s2, id2); 3547 iso->SetObjectGroupId(g2s2.handle, id2);
3539 iso->SetReferenceFromGroup(id2, g2c1); 3548 iso->SetReferenceFromGroup(id2, g2c1.handle);
3540 } 3549 }
3541 3550
3542 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3551 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3543 3552
3544 // All objects should be gone. 5 global handles in total. 3553 // All objects should be gone. 5 global handles in total.
3545 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3554 CHECK_EQ(5, counter.NumberOfWeakCalls());
3546 3555
3547 // And now make children weak again and collect them. 3556 // And now make children weak again and collect them.
3548 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3557 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
3549 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3558 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
3550 3559
3551 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3560 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3552 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3561 CHECK_EQ(7, counter.NumberOfWeakCalls());
3553 } 3562 }
3554 3563
3555 3564
3556 THREADED_TEST(ApiObjectGroupsForSubtypes) { 3565 THREADED_TEST(ApiObjectGroupsForSubtypes) {
3557 LocalContext env; 3566 LocalContext env;
3558 v8::Isolate* iso = env->GetIsolate(); 3567 v8::Isolate* iso = env->GetIsolate();
3559 HandleScope scope(iso); 3568 HandleScope scope(iso);
3560 3569
3561 Persistent<Object> g1s1; 3570 WeakCallCounter counter(1234);
3562 Persistent<String> g1s2;
3563 Persistent<String> g1c1;
3564 Persistent<Object> g2s1;
3565 Persistent<String> g2s2;
3566 Persistent<String> g2c1;
3567 3571
3568 WeakCallCounter counter(1234); 3572 WeakCallCounterAndPersistent<Object> g1s1(&counter);
3573 WeakCallCounterAndPersistent<String> g1s2(&counter);
3574 WeakCallCounterAndPersistent<String> g1c1(&counter);
3575 WeakCallCounterAndPersistent<Object> g2s1(&counter);
3576 WeakCallCounterAndPersistent<String> g2s2(&counter);
3577 WeakCallCounterAndPersistent<String> g2c1(&counter);
3569 3578
3570 { 3579 {
3571 HandleScope scope(iso); 3580 HandleScope scope(iso);
3572 g1s1.Reset(iso, Object::New()); 3581 g1s1.handle.Reset(iso, Object::New());
3573 g1s2.Reset(iso, String::NewFromUtf8(iso, "foo1")); 3582 g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1"));
3574 g1c1.Reset(iso, String::NewFromUtf8(iso, "foo2")); 3583 g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2"));
3575 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3584 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
3576 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3585 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
3577 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3586 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
3578 3587
3579 g2s1.Reset(iso, Object::New()); 3588 g2s1.handle.Reset(iso, Object::New());
3580 g2s2.Reset(iso, String::NewFromUtf8(iso, "foo3")); 3589 g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3"));
3581 g2c1.Reset(iso, String::NewFromUtf8(iso, "foo4")); 3590 g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4"));
3582 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3591 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
3583 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3592 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
3584 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3593 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
3585 } 3594 }
3586 3595
3587 Persistent<Value> root(iso, g1s1); // make a root. 3596 WeakCallCounterAndPersistent<Value> root(&counter);
3597 root.handle.Reset(iso, g1s1.handle); // make a root.
3588 3598
3589 // Connect group 1 and 2, make a cycle. 3599 // Connect group 1 and 2, make a cycle.
3590 { 3600 {
3591 HandleScope scope(iso); 3601 HandleScope scope(iso);
3592 CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); 3602 CHECK(Local<Object>::New(iso, g1s1.handle)
3593 CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1))); 3603 ->Set(0, Local<Object>::New(iso, g2s1.handle)));
3604 CHECK(Local<Object>::New(iso, g2s1.handle)
3605 ->Set(0, Local<Object>::New(iso, g1s1.handle)));
3594 } 3606 }
3595 3607
3596 { 3608 {
3597 UniqueId id1 = MakeUniqueId(g1s1); 3609 UniqueId id1 = MakeUniqueId(g1s1.handle);
3598 UniqueId id2 = MakeUniqueId(g2s2); 3610 UniqueId id2 = MakeUniqueId(g2s2.handle);
3599 iso->SetObjectGroupId(g1s1, id1); 3611 iso->SetObjectGroupId(g1s1.handle, id1);
3600 iso->SetObjectGroupId(g1s2, id1); 3612 iso->SetObjectGroupId(g1s2.handle, id1);
3601 iso->SetReference(g1s1, g1c1); 3613 iso->SetReference(g1s1.handle, g1c1.handle);
3602 iso->SetObjectGroupId(g2s1, id2); 3614 iso->SetObjectGroupId(g2s1.handle, id2);
3603 iso->SetObjectGroupId(g2s2, id2); 3615 iso->SetObjectGroupId(g2s2.handle, id2);
3604 iso->SetReferenceFromGroup(id2, g2c1); 3616 iso->SetReferenceFromGroup(id2, g2c1.handle);
3605 } 3617 }
3606 // Do a single full GC, ensure incremental marking is stopped. 3618 // Do a single full GC, ensure incremental marking is stopped.
3607 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3619 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3608 iso)->heap(); 3620 iso)->heap();
3609 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3621 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3610 3622
3611 // All object should be alive. 3623 // All object should be alive.
3612 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3624 CHECK_EQ(0, counter.NumberOfWeakCalls());
3613 3625
3614 // Weaken the root. 3626 // Weaken the root.
3615 root.MakeWeak(&counter, &WeakPointerCallback); 3627 root.handle.SetWeak(&root, &WeakPointerCallback);
3616 // But make children strong roots---all the objects (except for children) 3628 // But make children strong roots---all the objects (except for children)
3617 // should be collectable now. 3629 // should be collectable now.
3618 g1c1.ClearWeak(); 3630 g1c1.handle.ClearWeak();
3619 g2c1.ClearWeak(); 3631 g2c1.handle.ClearWeak();
3620 3632
3621 // Groups are deleted, rebuild groups. 3633 // Groups are deleted, rebuild groups.
3622 { 3634 {
3623 UniqueId id1 = MakeUniqueId(g1s1); 3635 UniqueId id1 = MakeUniqueId(g1s1.handle);
3624 UniqueId id2 = MakeUniqueId(g2s2); 3636 UniqueId id2 = MakeUniqueId(g2s2.handle);
3625 iso->SetObjectGroupId(g1s1, id1); 3637 iso->SetObjectGroupId(g1s1.handle, id1);
3626 iso->SetObjectGroupId(g1s2, id1); 3638 iso->SetObjectGroupId(g1s2.handle, id1);
3627 iso->SetReference(g1s1, g1c1); 3639 iso->SetReference(g1s1.handle, g1c1.handle);
3628 iso->SetObjectGroupId(g2s1, id2); 3640 iso->SetObjectGroupId(g2s1.handle, id2);
3629 iso->SetObjectGroupId(g2s2, id2); 3641 iso->SetObjectGroupId(g2s2.handle, id2);
3630 iso->SetReferenceFromGroup(id2, g2c1); 3642 iso->SetReferenceFromGroup(id2, g2c1.handle);
3631 } 3643 }
3632 3644
3633 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3645 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3634 3646
3635 // All objects should be gone. 5 global handles in total. 3647 // All objects should be gone. 5 global handles in total.
3636 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3648 CHECK_EQ(5, counter.NumberOfWeakCalls());
3637 3649
3638 // And now make children weak again and collect them. 3650 // And now make children weak again and collect them.
3639 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3651 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback);
3640 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3652 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback);
3641 3653
3642 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3654 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3643 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3655 CHECK_EQ(7, counter.NumberOfWeakCalls());
3644 } 3656 }
3645 3657
3646 3658
3647 THREADED_TEST(ApiObjectGroupsCycle) { 3659 THREADED_TEST(ApiObjectGroupsCycle) {
3648 LocalContext env; 3660 LocalContext env;
3649 v8::Isolate* iso = env->GetIsolate(); 3661 v8::Isolate* iso = env->GetIsolate();
3650 HandleScope scope(iso); 3662 HandleScope scope(iso);
3651 3663
3652 WeakCallCounter counter(1234); 3664 WeakCallCounter counter(1234);
3653 3665
3654 Persistent<Value> g1s1; 3666 WeakCallCounterAndPersistent<Value> g1s1(&counter);
3655 Persistent<Value> g1s2; 3667 WeakCallCounterAndPersistent<Value> g1s2(&counter);
3656 Persistent<Value> g2s1; 3668 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3657 Persistent<Value> g2s2; 3669 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3658 Persistent<Value> g3s1; 3670 WeakCallCounterAndPersistent<Value> g3s1(&counter);
3659 Persistent<Value> g3s2; 3671 WeakCallCounterAndPersistent<Value> g3s2(&counter);
3660 Persistent<Value> g4s1; 3672 WeakCallCounterAndPersistent<Value> g4s1(&counter);
3661 Persistent<Value> g4s2; 3673 WeakCallCounterAndPersistent<Value> g4s2(&counter);
3662 3674
3663 { 3675 {
3664 HandleScope scope(iso); 3676 HandleScope scope(iso);
3665 g1s1.Reset(iso, Object::New()); 3677 g1s1.handle.Reset(iso, Object::New());
3666 g1s2.Reset(iso, Object::New()); 3678 g1s2.handle.Reset(iso, Object::New());
3667 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3679 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
3668 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3680 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
3669 CHECK(g1s1.IsWeak()); 3681 CHECK(g1s1.handle.IsWeak());
3670 CHECK(g1s2.IsWeak()); 3682 CHECK(g1s2.handle.IsWeak());
3671 3683
3672 g2s1.Reset(iso, Object::New()); 3684 g2s1.handle.Reset(iso, Object::New());
3673 g2s2.Reset(iso, Object::New()); 3685 g2s2.handle.Reset(iso, Object::New());
3674 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3686 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
3675 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3687 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
3676 CHECK(g2s1.IsWeak()); 3688 CHECK(g2s1.handle.IsWeak());
3677 CHECK(g2s2.IsWeak()); 3689 CHECK(g2s2.handle.IsWeak());
3678 3690
3679 g3s1.Reset(iso, Object::New()); 3691 g3s1.handle.Reset(iso, Object::New());
3680 g3s2.Reset(iso, Object::New()); 3692 g3s2.handle.Reset(iso, Object::New());
3681 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3693 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback);
3682 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3694 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback);
3683 CHECK(g3s1.IsWeak()); 3695 CHECK(g3s1.handle.IsWeak());
3684 CHECK(g3s2.IsWeak()); 3696 CHECK(g3s2.handle.IsWeak());
3685 3697
3686 g4s1.Reset(iso, Object::New()); 3698 g4s1.handle.Reset(iso, Object::New());
3687 g4s2.Reset(iso, Object::New()); 3699 g4s2.handle.Reset(iso, Object::New());
3688 g4s1.MakeWeak(&counter, &WeakPointerCallback); 3700 g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback);
3689 g4s2.MakeWeak(&counter, &WeakPointerCallback); 3701 g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback);
3690 CHECK(g4s1.IsWeak()); 3702 CHECK(g4s1.handle.IsWeak());
3691 CHECK(g4s2.IsWeak()); 3703 CHECK(g4s2.handle.IsWeak());
3692 } 3704 }
3693 3705
3694 Persistent<Value> root(iso, g1s1); // make a root. 3706 WeakCallCounterAndPersistent<Value> root(&counter);
3707 root.handle.Reset(iso, g1s1.handle); // make a root.
3695 3708
3696 // Connect groups. We're building the following cycle: 3709 // Connect groups. We're building the following cycle:
3697 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3710 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3698 // groups. 3711 // groups.
3699 { 3712 {
3700 UniqueId id1 = MakeUniqueId(g1s1); 3713 UniqueId id1 = MakeUniqueId(g1s1.handle);
3701 UniqueId id2 = MakeUniqueId(g2s1); 3714 UniqueId id2 = MakeUniqueId(g2s1.handle);
3702 UniqueId id3 = MakeUniqueId(g3s1); 3715 UniqueId id3 = MakeUniqueId(g3s1.handle);
3703 UniqueId id4 = MakeUniqueId(g4s1); 3716 UniqueId id4 = MakeUniqueId(g4s1.handle);
3704 iso->SetObjectGroupId(g1s1, id1); 3717 iso->SetObjectGroupId(g1s1.handle, id1);
3705 iso->SetObjectGroupId(g1s2, id1); 3718 iso->SetObjectGroupId(g1s2.handle, id1);
3706 iso->SetReferenceFromGroup(id1, g2s1); 3719 iso->SetReferenceFromGroup(id1, g2s1.handle);
3707 iso->SetObjectGroupId(g2s1, id2); 3720 iso->SetObjectGroupId(g2s1.handle, id2);
3708 iso->SetObjectGroupId(g2s2, id2); 3721 iso->SetObjectGroupId(g2s2.handle, id2);
3709 iso->SetReferenceFromGroup(id2, g3s1); 3722 iso->SetReferenceFromGroup(id2, g3s1.handle);
3710 iso->SetObjectGroupId(g3s1, id3); 3723 iso->SetObjectGroupId(g3s1.handle, id3);
3711 iso->SetObjectGroupId(g3s2, id3); 3724 iso->SetObjectGroupId(g3s2.handle, id3);
3712 iso->SetReferenceFromGroup(id3, g4s1); 3725 iso->SetReferenceFromGroup(id3, g4s1.handle);
3713 iso->SetObjectGroupId(g4s1, id4); 3726 iso->SetObjectGroupId(g4s1.handle, id4);
3714 iso->SetObjectGroupId(g4s2, id4); 3727 iso->SetObjectGroupId(g4s2.handle, id4);
3715 iso->SetReferenceFromGroup(id4, g1s1); 3728 iso->SetReferenceFromGroup(id4, g1s1.handle);
3716 } 3729 }
3717 // Do a single full GC 3730 // Do a single full GC
3718 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3731 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3719 iso)->heap(); 3732 iso)->heap();
3720 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3733 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3721 3734
3722 // All object should be alive. 3735 // All object should be alive.
3723 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3736 CHECK_EQ(0, counter.NumberOfWeakCalls());
3724 3737
3725 // Weaken the root. 3738 // Weaken the root.
3726 root.MakeWeak(&counter, &WeakPointerCallback); 3739 root.handle.SetWeak(&root, &WeakPointerCallback);
3727 3740
3728 // Groups are deleted, rebuild groups. 3741 // Groups are deleted, rebuild groups.
3729 { 3742 {
3730 UniqueId id1 = MakeUniqueId(g1s1); 3743 UniqueId id1 = MakeUniqueId(g1s1.handle);
3731 UniqueId id2 = MakeUniqueId(g2s1); 3744 UniqueId id2 = MakeUniqueId(g2s1.handle);
3732 UniqueId id3 = MakeUniqueId(g3s1); 3745 UniqueId id3 = MakeUniqueId(g3s1.handle);
3733 UniqueId id4 = MakeUniqueId(g4s1); 3746 UniqueId id4 = MakeUniqueId(g4s1.handle);
3734 iso->SetObjectGroupId(g1s1, id1); 3747 iso->SetObjectGroupId(g1s1.handle, id1);
3735 iso->SetObjectGroupId(g1s2, id1); 3748 iso->SetObjectGroupId(g1s2.handle, id1);
3736 iso->SetReferenceFromGroup(id1, g2s1); 3749 iso->SetReferenceFromGroup(id1, g2s1.handle);
3737 iso->SetObjectGroupId(g2s1, id2); 3750 iso->SetObjectGroupId(g2s1.handle, id2);
3738 iso->SetObjectGroupId(g2s2, id2); 3751 iso->SetObjectGroupId(g2s2.handle, id2);
3739 iso->SetReferenceFromGroup(id2, g3s1); 3752 iso->SetReferenceFromGroup(id2, g3s1.handle);
3740 iso->SetObjectGroupId(g3s1, id3); 3753 iso->SetObjectGroupId(g3s1.handle, id3);
3741 iso->SetObjectGroupId(g3s2, id3); 3754 iso->SetObjectGroupId(g3s2.handle, id3);
3742 iso->SetReferenceFromGroup(id3, g4s1); 3755 iso->SetReferenceFromGroup(id3, g4s1.handle);
3743 iso->SetObjectGroupId(g4s1, id4); 3756 iso->SetObjectGroupId(g4s1.handle, id4);
3744 iso->SetObjectGroupId(g4s2, id4); 3757 iso->SetObjectGroupId(g4s2.handle, id4);
3745 iso->SetReferenceFromGroup(id4, g1s1); 3758 iso->SetReferenceFromGroup(id4, g1s1.handle);
3746 } 3759 }
3747 3760
3748 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3761 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3749 3762
3750 // All objects should be gone. 9 global handles in total. 3763 // All objects should be gone. 9 global handles in total.
3751 CHECK_EQ(9, counter.NumberOfWeakCalls()); 3764 CHECK_EQ(9, counter.NumberOfWeakCalls());
3752 } 3765 }
3753 3766
3754 3767
3755 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures 3768 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures
3756 // on the buildbots, so was made non-threaded for the time being. 3769 // on the buildbots, so was made non-threaded for the time being.
3757 TEST(ApiObjectGroupsCycleForScavenger) { 3770 TEST(ApiObjectGroupsCycleForScavenger) {
3758 i::FLAG_stress_compaction = false; 3771 i::FLAG_stress_compaction = false;
3759 i::FLAG_gc_global = false; 3772 i::FLAG_gc_global = false;
3760 LocalContext env; 3773 LocalContext env;
3761 v8::Isolate* iso = env->GetIsolate(); 3774 v8::Isolate* iso = env->GetIsolate();
3762 HandleScope scope(iso); 3775 HandleScope scope(iso);
3763 3776
3764 WeakCallCounter counter(1234); 3777 WeakCallCounter counter(1234);
3765 3778
3766 Persistent<Value> g1s1; 3779 WeakCallCounterAndPersistent<Value> g1s1(&counter);
3767 Persistent<Value> g1s2; 3780 WeakCallCounterAndPersistent<Value> g1s2(&counter);
3768 Persistent<Value> g2s1; 3781 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3769 Persistent<Value> g2s2; 3782 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3770 Persistent<Value> g3s1; 3783 WeakCallCounterAndPersistent<Value> g3s1(&counter);
3771 Persistent<Value> g3s2; 3784 WeakCallCounterAndPersistent<Value> g3s2(&counter);
3772 3785
3773 { 3786 {
3774 HandleScope scope(iso); 3787 HandleScope scope(iso);
3775 g1s1.Reset(iso, Object::New()); 3788 g1s1.handle.Reset(iso, Object::New());
3776 g1s2.Reset(iso, Object::New()); 3789 g1s2.handle.Reset(iso, Object::New());
3777 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3790 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback);
3778 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3791 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback);
3779 3792
3780 g2s1.Reset(iso, Object::New()); 3793 g2s1.handle.Reset(iso, Object::New());
3781 g2s2.Reset(iso, Object::New()); 3794 g2s2.handle.Reset(iso, Object::New());
3782 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3795 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback);
3783 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3796 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback);
3784 3797
3785 g3s1.Reset(iso, Object::New()); 3798 g3s1.handle.Reset(iso, Object::New());
3786 g3s2.Reset(iso, Object::New()); 3799 g3s2.handle.Reset(iso, Object::New());
3787 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3800 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback);
3788 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3801 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback);
3789 } 3802 }
3790 3803
3791 // Make a root. 3804 // Make a root.
3792 Persistent<Value> root(iso, g1s1); 3805 WeakCallCounterAndPersistent<Value> root(&counter);
3793 root.MarkPartiallyDependent(); 3806 root.handle.Reset(iso, g1s1.handle);
3807 root.handle.MarkPartiallyDependent();
3794 3808
3795 // Connect groups. We're building the following cycle: 3809 // Connect groups. We're building the following cycle:
3796 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3810 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3797 // groups. 3811 // groups.
3798 { 3812 {
3799 HandleScope handle_scope(iso); 3813 HandleScope handle_scope(iso);
3800 g1s1.MarkPartiallyDependent(); 3814 g1s1.handle.MarkPartiallyDependent();
3801 g1s2.MarkPartiallyDependent(); 3815 g1s2.handle.MarkPartiallyDependent();
3802 g2s1.MarkPartiallyDependent(); 3816 g2s1.handle.MarkPartiallyDependent();
3803 g2s2.MarkPartiallyDependent(); 3817 g2s2.handle.MarkPartiallyDependent();
3804 g3s1.MarkPartiallyDependent(); 3818 g3s1.handle.MarkPartiallyDependent();
3805 g3s2.MarkPartiallyDependent(); 3819 g3s2.handle.MarkPartiallyDependent();
3806 iso->SetObjectGroupId(g1s1, UniqueId(1)); 3820 iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
3807 iso->SetObjectGroupId(g1s2, UniqueId(1)); 3821 iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
3808 Local<Object>::New(iso, g1s1.As<Object>())->Set( 3822 Local<Object>::New(iso, g1s1.handle.As<Object>())->Set(
3809 v8_str("x"), Local<Value>::New(iso, g2s1)); 3823 v8_str("x"), Local<Value>::New(iso, g2s1.handle));
3810 iso->SetObjectGroupId(g2s1, UniqueId(2)); 3824 iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
3811 iso->SetObjectGroupId(g2s2, UniqueId(2)); 3825 iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
3812 Local<Object>::New(iso, g2s1.As<Object>())->Set( 3826 Local<Object>::New(iso, g2s1.handle.As<Object>())->Set(
3813 v8_str("x"), Local<Value>::New(iso, g3s1)); 3827 v8_str("x"), Local<Value>::New(iso, g3s1.handle));
3814 iso->SetObjectGroupId(g3s1, UniqueId(3)); 3828 iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
3815 iso->SetObjectGroupId(g3s2, UniqueId(3)); 3829 iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
3816 Local<Object>::New(iso, g3s1.As<Object>())->Set( 3830 Local<Object>::New(iso, g3s1.handle.As<Object>())->Set(
3817 v8_str("x"), Local<Value>::New(iso, g1s1)); 3831 v8_str("x"), Local<Value>::New(iso, g1s1.handle));
3818 } 3832 }
3819 3833
3820 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3834 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3821 iso)->heap(); 3835 iso)->heap();
3822 heap->CollectGarbage(i::NEW_SPACE); 3836 heap->CollectGarbage(i::NEW_SPACE);
3823 3837
3824 // All objects should be alive. 3838 // All objects should be alive.
3825 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3839 CHECK_EQ(0, counter.NumberOfWeakCalls());
3826 3840
3827 // Weaken the root. 3841 // Weaken the root.
3828 root.MakeWeak(&counter, &WeakPointerCallback); 3842 root.handle.SetWeak(&root, &WeakPointerCallback);
3829 root.MarkPartiallyDependent(); 3843 root.handle.MarkPartiallyDependent();
3830 3844
3831 // Groups are deleted, rebuild groups. 3845 // Groups are deleted, rebuild groups.
3832 { 3846 {
3833 HandleScope handle_scope(iso); 3847 HandleScope handle_scope(iso);
3834 g1s1.MarkPartiallyDependent(); 3848 g1s1.handle.MarkPartiallyDependent();
3835 g1s2.MarkPartiallyDependent(); 3849 g1s2.handle.MarkPartiallyDependent();
3836 g2s1.MarkPartiallyDependent(); 3850 g2s1.handle.MarkPartiallyDependent();
3837 g2s2.MarkPartiallyDependent(); 3851 g2s2.handle.MarkPartiallyDependent();
3838 g3s1.MarkPartiallyDependent(); 3852 g3s1.handle.MarkPartiallyDependent();
3839 g3s2.MarkPartiallyDependent(); 3853 g3s2.handle.MarkPartiallyDependent();
3840 iso->SetObjectGroupId(g1s1, UniqueId(1)); 3854 iso->SetObjectGroupId(g1s1.handle, UniqueId(1));
3841 iso->SetObjectGroupId(g1s2, UniqueId(1)); 3855 iso->SetObjectGroupId(g1s2.handle, UniqueId(1));
3842 Local<Object>::New(iso, g1s1.As<Object>())->Set( 3856 Local<Object>::New(iso, g1s1.handle.As<Object>())->Set(
3843 v8_str("x"), Local<Value>::New(iso, g2s1)); 3857 v8_str("x"), Local<Value>::New(iso, g2s1.handle));
3844 iso->SetObjectGroupId(g2s1, UniqueId(2)); 3858 iso->SetObjectGroupId(g2s1.handle, UniqueId(2));
3845 iso->SetObjectGroupId(g2s2, UniqueId(2)); 3859 iso->SetObjectGroupId(g2s2.handle, UniqueId(2));
3846 Local<Object>::New(iso, g2s1.As<Object>())->Set( 3860 Local<Object>::New(iso, g2s1.handle.As<Object>())->Set(
3847 v8_str("x"), Local<Value>::New(iso, g3s1)); 3861 v8_str("x"), Local<Value>::New(iso, g3s1.handle));
3848 iso->SetObjectGroupId(g3s1, UniqueId(3)); 3862 iso->SetObjectGroupId(g3s1.handle, UniqueId(3));
3849 iso->SetObjectGroupId(g3s2, UniqueId(3)); 3863 iso->SetObjectGroupId(g3s2.handle, UniqueId(3));
3850 Local<Object>::New(iso, g3s1.As<Object>())->Set( 3864 Local<Object>::New(iso, g3s1.handle.As<Object>())->Set(
3851 v8_str("x"), Local<Value>::New(iso, g1s1)); 3865 v8_str("x"), Local<Value>::New(iso, g1s1.handle));
3852 } 3866 }
3853 3867
3854 heap->CollectGarbage(i::NEW_SPACE); 3868 heap->CollectGarbage(i::NEW_SPACE);
3855 3869
3856 // All objects should be gone. 7 global handles in total. 3870 // All objects should be gone. 7 global handles in total.
3857 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3871 CHECK_EQ(7, counter.NumberOfWeakCalls());
3858 } 3872 }
3859 3873
3860 3874
3861 THREADED_TEST(ScriptException) { 3875 THREADED_TEST(ScriptException) {
(...skipping 3078 matching lines...) Expand 10 before | Expand all | Expand 10 after
6940 LocalContext context; 6954 LocalContext context;
6941 v8::HandleScope scope(context->GetIsolate()); 6955 v8::HandleScope scope(context->GetIsolate());
6942 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); 6956 v8::V8::AddMessageListener(MissingScriptInfoMessageListener);
6943 Script::Compile(v8_str("throw Error()"))->Run(); 6957 Script::Compile(v8_str("throw Error()"))->Run();
6944 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); 6958 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener);
6945 } 6959 }
6946 6960
6947 6961
6948 int global_index = 0; 6962 int global_index = 0;
6949 6963
6964 template<typename T>
6950 class Snorkel { 6965 class Snorkel {
6951 public: 6966 public:
6952 Snorkel() { index_ = global_index++; } 6967 explicit Snorkel(v8::Persistent<T>* handle) : handle_(handle) {
6968 index_ = global_index++;
6969 }
6970 v8::Persistent<T>* handle_;
6953 int index_; 6971 int index_;
6954 }; 6972 };
6955 6973
6956 class Whammy { 6974 class Whammy {
6957 public: 6975 public:
6958 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } 6976 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
6959 ~Whammy() { script_.Reset(); } 6977 ~Whammy() { script_.Reset(); }
6960 v8::Handle<Script> getScript() { 6978 v8::Handle<Script> getScript() {
6961 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); 6979 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
6962 return Local<Script>::New(isolate_, script_); 6980 return Local<Script>::New(isolate_, script_);
6963 } 6981 }
6964 6982
6965 public: 6983 public:
6966 static const int kObjectCount = 256; 6984 static const int kObjectCount = 256;
6967 int cursor_; 6985 int cursor_;
6968 v8::Isolate* isolate_; 6986 v8::Isolate* isolate_;
6969 v8::Persistent<v8::Object> objects_[kObjectCount]; 6987 v8::Persistent<v8::Object> objects_[kObjectCount];
6970 v8::Persistent<Script> script_; 6988 v8::Persistent<Script> script_;
6971 }; 6989 };
6972 6990
6973 static void HandleWeakReference(v8::Isolate* isolate, 6991 static void HandleWeakReference(
6974 v8::Persistent<v8::Value>* obj, 6992 const v8::WeakCallbackData<v8::Value, Snorkel<v8::Value> >& data) {
6975 Snorkel* snorkel) { 6993 data.GetParameter()->handle_->ClearWeak();
6976 delete snorkel; 6994 delete data.GetParameter();
6977 obj->ClearWeak();
6978 } 6995 }
6979 6996
6980 void WhammyPropertyGetter(Local<String> name, 6997 void WhammyPropertyGetter(Local<String> name,
6981 const v8::PropertyCallbackInfo<v8::Value>& info) { 6998 const v8::PropertyCallbackInfo<v8::Value>& info) {
6982 Whammy* whammy = 6999 Whammy* whammy =
6983 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); 7000 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
6984 7001
6985 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; 7002 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
6986 7003
6987 v8::Handle<v8::Object> obj = v8::Object::New(); 7004 v8::Handle<v8::Object> obj = v8::Object::New();
6988 if (!prev.IsEmpty()) { 7005 if (!prev.IsEmpty()) {
6989 v8::Local<v8::Object>::New(info.GetIsolate(), prev) 7006 v8::Local<v8::Object>::New(info.GetIsolate(), prev)
6990 ->Set(v8_str("next"), obj); 7007 ->Set(v8_str("next"), obj);
6991 prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference); 7008 prev.SetWeak<Value, Snorkel<Value> >(new Snorkel<Value>(&prev.As<Value>()),
7009 &HandleWeakReference);
6992 } 7010 }
6993 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); 7011 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj);
6994 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; 7012 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount;
6995 info.GetReturnValue().Set(whammy->getScript()->Run()); 7013 info.GetReturnValue().Set(whammy->getScript()->Run());
6996 } 7014 }
6997 7015
6998 7016
6999 THREADED_TEST(WeakReference) { 7017 THREADED_TEST(WeakReference) {
7000 v8::HandleScope handle_scope(CcTest::isolate()); 7018 v8::HandleScope handle_scope(CcTest::isolate());
7001 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); 7019 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New();
(...skipping 17 matching lines...) Expand all
7019 " last = obj;" 7037 " last = obj;"
7020 "}" 7038 "}"
7021 "gc();" 7039 "gc();"
7022 "4"; 7040 "4";
7023 v8::Handle<Value> result = CompileRun(code); 7041 v8::Handle<Value> result = CompileRun(code);
7024 CHECK_EQ(4.0, result->NumberValue()); 7042 CHECK_EQ(4.0, result->NumberValue());
7025 delete whammy; 7043 delete whammy;
7026 } 7044 }
7027 7045
7028 7046
7029 static void DisposeAndSetFlag(v8::Isolate* isolate, 7047 struct FlagAndPersistent {
7030 v8::Persistent<v8::Object>* obj, 7048 bool flag;
7031 bool* data) { 7049 v8::Persistent<v8::Object> handle;
7032 obj->Reset(); 7050 };
7033 *(data) = true; 7051
7052
7053 static void DisposeAndSetFlag(
7054 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
7055 data.GetParameter()->handle.Reset();
7056 data.GetParameter()->flag = true;
7034 } 7057 }
7035 7058
7036 7059
7037 THREADED_TEST(IndependentWeakHandle) { 7060 THREADED_TEST(IndependentWeakHandle) {
7038 v8::Isolate* iso = CcTest::isolate(); 7061 v8::Isolate* iso = CcTest::isolate();
7039 v8::HandleScope scope(iso); 7062 v8::HandleScope scope(iso);
7040 v8::Handle<Context> context = Context::New(iso); 7063 v8::Handle<Context> context = Context::New(iso);
7041 Context::Scope context_scope(context); 7064 Context::Scope context_scope(context);
7042 7065
7043 v8::Persistent<v8::Object> object_a, object_b; 7066 FlagAndPersistent object_a, object_b;
7044 7067
7045 { 7068 {
7046 v8::HandleScope handle_scope(iso); 7069 v8::HandleScope handle_scope(iso);
7047 object_a.Reset(iso, v8::Object::New()); 7070 object_a.handle.Reset(iso, v8::Object::New());
7048 object_b.Reset(iso, v8::Object::New()); 7071 object_b.handle.Reset(iso, v8::Object::New());
7049 } 7072 }
7050 7073
7051 bool object_a_disposed = false; 7074 object_a.flag = false;
7052 bool object_b_disposed = false; 7075 object_b.flag = false;
7053 object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); 7076 object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag);
7054 object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag); 7077 object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag);
7055 CHECK(!object_b.IsIndependent()); 7078 CHECK(!object_b.handle.IsIndependent());
7056 object_a.MarkIndependent(); 7079 object_a.handle.MarkIndependent();
7057 object_b.MarkIndependent(); 7080 object_b.handle.MarkIndependent();
7058 CHECK(object_b.IsIndependent()); 7081 CHECK(object_b.handle.IsIndependent());
7059 CcTest::heap()->PerformScavenge(); 7082 CcTest::heap()->PerformScavenge();
7060 CHECK(object_a_disposed); 7083 CHECK(object_a.flag);
7061 CHECK(object_b_disposed); 7084 CHECK(object_b.flag);
7062 } 7085 }
7063 7086
7064 7087
7065 static void InvokeScavenge() { 7088 static void InvokeScavenge() {
7066 CcTest::heap()->PerformScavenge(); 7089 CcTest::heap()->PerformScavenge();
7067 } 7090 }
7068 7091
7069 7092
7070 static void InvokeMarkSweep() { 7093 static void InvokeMarkSweep() {
7071 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 7094 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
7072 } 7095 }
7073 7096
7074 7097
7075 static void ForceScavenge(v8::Isolate* isolate, 7098 static void ForceScavenge(
7076 v8::Persistent<v8::Object>* obj, 7099 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
7077 bool* data) { 7100 data.GetParameter()->handle.Reset();
7078 obj->Reset(); 7101 data.GetParameter()->flag = true;
7079 *(data) = true;
7080 InvokeScavenge(); 7102 InvokeScavenge();
7081 } 7103 }
7082 7104
7083 7105
7084 static void ForceMarkSweep(v8::Isolate* isolate, 7106 static void ForceMarkSweep(
7085 v8::Persistent<v8::Object>* obj, 7107 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
7086 bool* data) { 7108 data.GetParameter()->handle.Reset();
7087 obj->Reset(); 7109 data.GetParameter()->flag = true;
7088 *(data) = true;
7089 InvokeMarkSweep(); 7110 InvokeMarkSweep();
7090 } 7111 }
7091 7112
7092 7113
7093 THREADED_TEST(GCFromWeakCallbacks) { 7114 THREADED_TEST(GCFromWeakCallbacks) {
7094 v8::Isolate* isolate = CcTest::isolate(); 7115 v8::Isolate* isolate = CcTest::isolate();
7095 v8::HandleScope scope(isolate); 7116 v8::HandleScope scope(isolate);
7096 v8::Handle<Context> context = Context::New(isolate); 7117 v8::Handle<Context> context = Context::New(isolate);
7097 Context::Scope context_scope(context); 7118 Context::Scope context_scope(context);
7098 7119
7099 static const int kNumberOfGCTypes = 2; 7120 static const int kNumberOfGCTypes = 2;
7100 typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback; 7121 typedef v8::WeakCallbackData<v8::Object, FlagAndPersistent>::Callback
7122 Callback;
7101 Callback gc_forcing_callback[kNumberOfGCTypes] = 7123 Callback gc_forcing_callback[kNumberOfGCTypes] =
7102 {&ForceScavenge, &ForceMarkSweep}; 7124 {&ForceScavenge, &ForceMarkSweep};
7103 7125
7104 typedef void (*GCInvoker)(); 7126 typedef void (*GCInvoker)();
7105 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; 7127 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep};
7106 7128
7107 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { 7129 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
7108 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { 7130 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
7109 v8::Persistent<v8::Object> object; 7131 FlagAndPersistent object;
7110 { 7132 {
7111 v8::HandleScope handle_scope(isolate); 7133 v8::HandleScope handle_scope(isolate);
7112 object.Reset(isolate, v8::Object::New()); 7134 object.handle.Reset(isolate, v8::Object::New());
7113 } 7135 }
7114 bool disposed = false; 7136 object.flag = false;
7115 object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); 7137 object.handle.SetWeak(&object, gc_forcing_callback[inner_gc]);
7116 object.MarkIndependent(); 7138 object.handle.MarkIndependent();
7117 invoke_gc[outer_gc](); 7139 invoke_gc[outer_gc]();
7118 CHECK(disposed); 7140 CHECK(object.flag);
7119 } 7141 }
7120 } 7142 }
7121 } 7143 }
7122 7144
7123 7145
7124 static void RevivingCallback(v8::Isolate* isolate, 7146 static void RevivingCallback(
7125 v8::Persistent<v8::Object>* obj, 7147 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
7126 bool* data) { 7148 data.GetParameter()->handle.ClearWeak();
7127 obj->ClearWeak(); 7149 data.GetParameter()->flag = true;
7128 *(data) = true;
7129 } 7150 }
7130 7151
7131 7152
7132 THREADED_TEST(IndependentHandleRevival) { 7153 THREADED_TEST(IndependentHandleRevival) {
7133 v8::Isolate* isolate = CcTest::isolate(); 7154 v8::Isolate* isolate = CcTest::isolate();
7134 v8::HandleScope scope(isolate); 7155 v8::HandleScope scope(isolate);
7135 v8::Handle<Context> context = Context::New(isolate); 7156 v8::Handle<Context> context = Context::New(isolate);
7136 Context::Scope context_scope(context); 7157 Context::Scope context_scope(context);
7137 7158
7138 v8::Persistent<v8::Object> object; 7159 FlagAndPersistent object;
7139 { 7160 {
7140 v8::HandleScope handle_scope(isolate); 7161 v8::HandleScope handle_scope(isolate);
7141 v8::Local<v8::Object> o = v8::Object::New(); 7162 v8::Local<v8::Object> o = v8::Object::New();
7142 object.Reset(isolate, o); 7163 object.handle.Reset(isolate, o);
7143 o->Set(v8_str("x"), v8::Integer::New(1)); 7164 o->Set(v8_str("x"), v8::Integer::New(1));
7144 v8::Local<String> y_str = v8_str("y"); 7165 v8::Local<String> y_str = v8_str("y");
7145 o->Set(y_str, y_str); 7166 o->Set(y_str, y_str);
7146 } 7167 }
7147 bool revived = false; 7168 object.flag = false;
7148 object.MakeWeak(&revived, &RevivingCallback); 7169 object.handle.SetWeak(&object, &RevivingCallback);
7149 object.MarkIndependent(); 7170 object.handle.MarkIndependent();
7150 CcTest::heap()->PerformScavenge(); 7171 CcTest::heap()->PerformScavenge();
7151 CHECK(revived); 7172 CHECK(object.flag);
7152 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 7173 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
7153 { 7174 {
7154 v8::HandleScope handle_scope(isolate); 7175 v8::HandleScope handle_scope(isolate);
7155 v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object); 7176 v8::Local<v8::Object> o =
7177 v8::Local<v8::Object>::New(isolate, object.handle);
7156 v8::Local<String> y_str = v8_str("y"); 7178 v8::Local<String> y_str = v8_str("y");
7157 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x"))); 7179 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x")));
7158 CHECK(o->Get(y_str)->Equals(y_str)); 7180 CHECK(o->Get(y_str)->Equals(y_str));
7159 } 7181 }
7160 } 7182 }
7161 7183
7162 7184
7163 v8::Handle<Function> args_fun; 7185 v8::Handle<Function> args_fun;
7164 7186
7165 7187
(...skipping 5933 matching lines...) Expand 10 before | Expand all | Expand 10 after
13099 reinterpret_cast<i::Isolate*>(isolate)->heap()-> 13121 reinterpret_cast<i::Isolate*>(isolate)->heap()->
13100 CollectAllGarbage(i::Heap::kNoGCFlags); 13122 CollectAllGarbage(i::Heap::kNoGCFlags);
13101 // Verify disposed. 13123 // Verify disposed.
13102 CHECK_EQ(initial_handles, globals->global_handles_count()); 13124 CHECK_EQ(initial_handles, globals->global_handles_count());
13103 } 13125 }
13104 13126
13105 13127
13106 v8::Persistent<v8::Object> some_object; 13128 v8::Persistent<v8::Object> some_object;
13107 v8::Persistent<v8::Object> bad_handle; 13129 v8::Persistent<v8::Object> bad_handle;
13108 13130
13109 void NewPersistentHandleCallback(v8::Isolate* isolate, 13131 void NewPersistentHandleCallback(
13110 v8::Persistent<v8::Value>* handle, 13132 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13111 void*) { 13133 v8::HandleScope scope(data.GetIsolate());
13112 v8::HandleScope scope(isolate); 13134 bad_handle.Reset(data.GetIsolate(), some_object);
13113 bad_handle.Reset(isolate, some_object); 13135 data.GetParameter()->Reset();
13114 handle->Reset();
13115 } 13136 }
13116 13137
13117 13138
13118 THREADED_TEST(NewPersistentHandleFromWeakCallback) { 13139 THREADED_TEST(NewPersistentHandleFromWeakCallback) {
13119 LocalContext context; 13140 LocalContext context;
13120 v8::Isolate* isolate = context->GetIsolate(); 13141 v8::Isolate* isolate = context->GetIsolate();
13121 13142
13122 v8::Persistent<v8::Object> handle1, handle2; 13143 v8::Persistent<v8::Object> handle1, handle2;
13123 { 13144 {
13124 v8::HandleScope scope(isolate); 13145 v8::HandleScope scope(isolate);
13125 some_object.Reset(isolate, v8::Object::New()); 13146 some_object.Reset(isolate, v8::Object::New());
13126 handle1.Reset(isolate, v8::Object::New()); 13147 handle1.Reset(isolate, v8::Object::New());
13127 handle2.Reset(isolate, v8::Object::New()); 13148 handle2.Reset(isolate, v8::Object::New());
13128 } 13149 }
13129 // Note: order is implementation dependent alas: currently 13150 // Note: order is implementation dependent alas: currently
13130 // global handle nodes are processed by PostGarbageCollectionProcessing 13151 // global handle nodes are processed by PostGarbageCollectionProcessing
13131 // in reverse allocation order, so if second allocated handle is deleted, 13152 // in reverse allocation order, so if second allocated handle is deleted,
13132 // weak callback of the first handle would be able to 'reallocate' it. 13153 // weak callback of the first handle would be able to 'reallocate' it.
13133 handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback); 13154 handle1.SetWeak(&handle1, NewPersistentHandleCallback);
13134 handle2.Reset(); 13155 handle2.Reset();
13135 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13156 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13136 } 13157 }
13137 13158
13138 13159
13139 v8::Persistent<v8::Object> to_be_disposed; 13160 v8::Persistent<v8::Object> to_be_disposed;
13140 13161
13141 void DisposeAndForceGcCallback(v8::Isolate* isolate, 13162 void DisposeAndForceGcCallback(
13142 v8::Persistent<v8::Value>* handle, 13163 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13143 void*) {
13144 to_be_disposed.Reset(); 13164 to_be_disposed.Reset();
13145 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13165 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13146 handle->Reset(); 13166 data.GetParameter()->Reset();
13147 } 13167 }
13148 13168
13149 13169
13150 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { 13170 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
13151 LocalContext context; 13171 LocalContext context;
13152 v8::Isolate* isolate = context->GetIsolate(); 13172 v8::Isolate* isolate = context->GetIsolate();
13153 13173
13154 v8::Persistent<v8::Object> handle1, handle2; 13174 v8::Persistent<v8::Object> handle1, handle2;
13155 { 13175 {
13156 v8::HandleScope scope(isolate); 13176 v8::HandleScope scope(isolate);
13157 handle1.Reset(isolate, v8::Object::New()); 13177 handle1.Reset(isolate, v8::Object::New());
13158 handle2.Reset(isolate, v8::Object::New()); 13178 handle2.Reset(isolate, v8::Object::New());
13159 } 13179 }
13160 handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback); 13180 handle1.SetWeak(&handle1, DisposeAndForceGcCallback);
13161 to_be_disposed.Reset(isolate, handle2); 13181 to_be_disposed.Reset(isolate, handle2);
13162 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13182 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13163 } 13183 }
13164 13184
13165 void DisposingCallback(v8::Isolate* isolate, 13185 void DisposingCallback(
13166 v8::Persistent<v8::Value>* handle, 13186 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13167 void*) { 13187 data.GetParameter()->Reset();
13168 handle->Reset();
13169 } 13188 }
13170 13189
13171 void HandleCreatingCallback(v8::Isolate* isolate, 13190 void HandleCreatingCallback(
13172 v8::Persistent<v8::Value>* handle, 13191 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13173 void*) { 13192 v8::HandleScope scope(data.GetIsolate());
13174 v8::HandleScope scope(isolate); 13193 v8::Persistent<v8::Object>(data.GetIsolate(), v8::Object::New());
13175 v8::Persistent<v8::Object>(isolate, v8::Object::New()); 13194 data.GetParameter()->Reset();
13176 handle->Reset();
13177 } 13195 }
13178 13196
13179 13197
13180 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { 13198 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
13181 LocalContext context; 13199 LocalContext context;
13182 v8::Isolate* isolate = context->GetIsolate(); 13200 v8::Isolate* isolate = context->GetIsolate();
13183 13201
13184 v8::Persistent<v8::Object> handle1, handle2, handle3; 13202 v8::Persistent<v8::Object> handle1, handle2, handle3;
13185 { 13203 {
13186 v8::HandleScope scope(isolate); 13204 v8::HandleScope scope(isolate);
13187 handle3.Reset(isolate, v8::Object::New()); 13205 handle3.Reset(isolate, v8::Object::New());
13188 handle2.Reset(isolate, v8::Object::New()); 13206 handle2.Reset(isolate, v8::Object::New());
13189 handle1.Reset(isolate, v8::Object::New()); 13207 handle1.Reset(isolate, v8::Object::New());
13190 } 13208 }
13191 handle2.MakeWeak<v8::Value, void>(NULL, DisposingCallback); 13209 handle2.SetWeak(&handle2, DisposingCallback);
13192 handle3.MakeWeak<v8::Value, void>(NULL, HandleCreatingCallback); 13210 handle3.SetWeak(&handle3, HandleCreatingCallback);
13193 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13211 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13194 } 13212 }
13195 13213
13196 13214
13197 THREADED_TEST(CheckForCrossContextObjectLiterals) { 13215 THREADED_TEST(CheckForCrossContextObjectLiterals) {
13198 v8::V8::Initialize(); 13216 v8::V8::Initialize();
13199 13217
13200 const int nof = 2; 13218 const int nof = 2;
13201 const char* sources[nof] = { 13219 const char* sources[nof] = {
13202 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", 13220 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }",
(...skipping 7651 matching lines...) Expand 10 before | Expand all | Expand 10 after
20854 } 20872 }
20855 for (int i = 0; i < runs; i++) { 20873 for (int i = 0; i < runs; i++) {
20856 Local<String> expected; 20874 Local<String> expected;
20857 if (i != 0) { 20875 if (i != 0) {
20858 CHECK_EQ(v8_str("escape value"), values[i]); 20876 CHECK_EQ(v8_str("escape value"), values[i]);
20859 } else { 20877 } else {
20860 CHECK(values[i].IsEmpty()); 20878 CHECK(values[i].IsEmpty());
20861 } 20879 }
20862 } 20880 }
20863 } 20881 }
OLDNEW
« no previous file with comments | « src/d8.cc ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698