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

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

Issue 98993002: Remove internal uses of deprecated MakeWeak. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. More stuff. 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
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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <climits> 28 #include <climits>
29 #include <csignal> 29 #include <csignal>
30 #include <string> 30 #include <string>
31 #include <map> 31 #include <map>
32 #include <utility>
Michael Starzinger 2013/12/02 15:34:10 nit: Can we alpha-sort the system includes block?
Sven Panne 2013/12/02 17:30:53 Done.
32 33
33 #include "v8.h" 34 #include "v8.h"
34 35
35 #if V8_OS_POSIX 36 #if V8_OS_POSIX
36 #include <unistd.h> // NOLINT 37 #include <unistd.h> // NOLINT
37 #endif 38 #endif
38 39
39 #include "api.h" 40 #include "api.h"
40 #include "arguments.h" 41 #include "arguments.h"
41 #include "cctest.h" 42 #include "cctest.h"
42 #include "compilation-cache.h" 43 #include "compilation-cache.h"
43 #include "cpu-profiler.h" 44 #include "cpu-profiler.h"
44 #include "execution.h" 45 #include "execution.h"
45 #include "isolate.h" 46 #include "isolate.h"
46 #include "objects.h" 47 #include "objects.h"
47 #include "parser.h" 48 #include "parser.h"
48 #include "platform.h" 49 #include "platform.h"
49 #include "snapshot.h" 50 #include "snapshot.h"
50 #include "unicode-inl.h" 51 #include "unicode-inl.h"
51 #include "utils.h" 52 #include "utils.h"
52 #include "vm-state.h" 53 #include "vm-state.h"
53 54
54 static const bool kLogThreading = false; 55 static const bool kLogThreading = false;
55 56
57 using std::pair;
58
56 using ::v8::Boolean; 59 using ::v8::Boolean;
57 using ::v8::BooleanObject; 60 using ::v8::BooleanObject;
58 using ::v8::Context; 61 using ::v8::Context;
59 using ::v8::Extension; 62 using ::v8::Extension;
60 using ::v8::Function; 63 using ::v8::Function;
61 using ::v8::FunctionTemplate; 64 using ::v8::FunctionTemplate;
62 using ::v8::Handle; 65 using ::v8::Handle;
63 using ::v8::HandleScope; 66 using ::v8::HandleScope;
64 using ::v8::Local; 67 using ::v8::Local;
65 using ::v8::Message; 68 using ::v8::Message;
(...skipping 3372 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 int id() { return id_; } 3441 int id() { return id_; }
3439 void increment() { number_of_weak_calls_++; } 3442 void increment() { number_of_weak_calls_++; }
3440 int NumberOfWeakCalls() { return number_of_weak_calls_; } 3443 int NumberOfWeakCalls() { return number_of_weak_calls_; }
3441 private: 3444 private:
3442 int id_; 3445 int id_;
3443 int number_of_weak_calls_; 3446 int number_of_weak_calls_;
3444 }; 3447 };
3445 3448
3446 3449
3447 template<typename T> 3450 template<typename T>
3448 static void WeakPointerCallback(v8::Isolate* isolate, 3451 static void WeakPointerCallback(
3449 Persistent<T>* handle, 3452 const v8::WeakCallbackData<T, std::pair<v8::Persistent<T>*,
3450 WeakCallCounter* counter) { 3453 WeakCallCounter*> >& data) {
3451 CHECK_EQ(1234, counter->id()); 3454 CHECK_EQ(1234, data.GetParameter()->second->id());
3452 counter->increment(); 3455 data.GetParameter()->second->increment();
3453 handle->Reset(); 3456 data.GetParameter()->first->Reset();
3454 } 3457 }
3455 3458
3456 3459
3457 template<typename T> 3460 template<typename T>
3458 static UniqueId MakeUniqueId(const Persistent<T>& p) { 3461 static UniqueId MakeUniqueId(const Persistent<T>& p) {
3459 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); 3462 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
3460 } 3463 }
3461 3464
3462 3465
3463 THREADED_TEST(ApiObjectGroups) { 3466 THREADED_TEST(ApiObjectGroups) {
3464 LocalContext env; 3467 LocalContext env;
3465 v8::Isolate* iso = env->GetIsolate(); 3468 v8::Isolate* iso = env->GetIsolate();
3466 HandleScope scope(iso); 3469 HandleScope scope(iso);
3467 3470
3468 Persistent<Value> g1s1; 3471 Persistent<Value> g1s1;
3469 Persistent<Value> g1s2; 3472 Persistent<Value> g1s2;
3470 Persistent<Value> g1c1; 3473 Persistent<Value> g1c1;
3471 Persistent<Value> g2s1; 3474 Persistent<Value> g2s1;
3472 Persistent<Value> g2s2; 3475 Persistent<Value> g2s2;
3473 Persistent<Value> g2c1; 3476 Persistent<Value> g2c1;
3474 3477
3475 WeakCallCounter counter(1234); 3478 WeakCallCounter counter(1234);
3476 3479
3480 pair<Persistent<Value>*, WeakCallCounter*> g1s1p(&g1s1, &counter);
3481 pair<Persistent<Value>*, WeakCallCounter*> g1s2p(&g1s2, &counter);
3482 pair<Persistent<Value>*, WeakCallCounter*> g1c1p(&g1c1, &counter);
3483 pair<Persistent<Value>*, WeakCallCounter*> g2s1p(&g2s1, &counter);
3484 pair<Persistent<Value>*, WeakCallCounter*> g2s2p(&g2s2, &counter);
3485 pair<Persistent<Value>*, WeakCallCounter*> g2c1p(&g2c1, &counter);
3486
3477 { 3487 {
3478 HandleScope scope(iso); 3488 HandleScope scope(iso);
3479 g1s1.Reset(iso, Object::New()); 3489 g1s1.Reset(iso, Object::New());
3480 g1s2.Reset(iso, Object::New()); 3490 g1s2.Reset(iso, Object::New());
3481 g1c1.Reset(iso, Object::New()); 3491 g1c1.Reset(iso, Object::New());
3482 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3492 g1s1.SetWeak(&g1s1p, &WeakPointerCallback);
3483 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3493 g1s2.SetWeak(&g1s2p, &WeakPointerCallback);
3484 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3494 g1c1.SetWeak(&g1c1p, &WeakPointerCallback);
3485 3495
3486 g2s1.Reset(iso, Object::New()); 3496 g2s1.Reset(iso, Object::New());
3487 g2s2.Reset(iso, Object::New()); 3497 g2s2.Reset(iso, Object::New());
3488 g2c1.Reset(iso, Object::New()); 3498 g2c1.Reset(iso, Object::New());
3489 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3499 g2s1.SetWeak(&g2s1p, &WeakPointerCallback);
3490 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3500 g2s2.SetWeak(&g2s2p, &WeakPointerCallback);
3491 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3501 g2c1.SetWeak(&g2c1p, &WeakPointerCallback);
3492 } 3502 }
3493 3503
3494 Persistent<Value> root(iso, g1s1); // make a root. 3504 Persistent<Value> root(iso, g1s1); // make a root.
3505 pair<Persistent<Value>*, WeakCallCounter*> rootp(&root, &counter);
3495 3506
3496 // Connect group 1 and 2, make a cycle. 3507 // Connect group 1 and 2, make a cycle.
3497 { 3508 {
3498 HandleScope scope(iso); 3509 HandleScope scope(iso);
3499 CHECK(Local<Object>::New(iso, g1s2.As<Object>())-> 3510 CHECK(Local<Object>::New(iso, g1s2.As<Object>())->
3500 Set(0, Local<Value>::New(iso, g2s2))); 3511 Set(0, Local<Value>::New(iso, g2s2)));
3501 CHECK(Local<Object>::New(iso, g2s1.As<Object>())-> 3512 CHECK(Local<Object>::New(iso, g2s1.As<Object>())->
3502 Set(0, Local<Value>::New(iso, g1s1))); 3513 Set(0, Local<Value>::New(iso, g1s1)));
3503 } 3514 }
3504 3515
3505 { 3516 {
3506 UniqueId id1 = MakeUniqueId(g1s1); 3517 UniqueId id1 = MakeUniqueId(g1s1);
3507 UniqueId id2 = MakeUniqueId(g2s2); 3518 UniqueId id2 = MakeUniqueId(g2s2);
3508 iso->SetObjectGroupId(g1s1, id1); 3519 iso->SetObjectGroupId(g1s1, id1);
3509 iso->SetObjectGroupId(g1s2, id1); 3520 iso->SetObjectGroupId(g1s2, id1);
3510 iso->SetReferenceFromGroup(id1, g1c1); 3521 iso->SetReferenceFromGroup(id1, g1c1);
3511 iso->SetObjectGroupId(g2s1, id2); 3522 iso->SetObjectGroupId(g2s1, id2);
3512 iso->SetObjectGroupId(g2s2, id2); 3523 iso->SetObjectGroupId(g2s2, id2);
3513 iso->SetReferenceFromGroup(id2, g2c1); 3524 iso->SetReferenceFromGroup(id2, g2c1);
3514 } 3525 }
3515 // Do a single full GC, ensure incremental marking is stopped. 3526 // Do a single full GC, ensure incremental marking is stopped.
3516 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3527 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3517 iso)->heap(); 3528 iso)->heap();
3518 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3529 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3519 3530
3520 // All object should be alive. 3531 // All object should be alive.
3521 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3532 CHECK_EQ(0, counter.NumberOfWeakCalls());
3522 3533
3523 // Weaken the root. 3534 // Weaken the root.
3524 root.MakeWeak(&counter, &WeakPointerCallback); 3535 root.SetWeak(&rootp, &WeakPointerCallback);
3525 // But make children strong roots---all the objects (except for children) 3536 // But make children strong roots---all the objects (except for children)
3526 // should be collectable now. 3537 // should be collectable now.
3527 g1c1.ClearWeak(); 3538 g1c1.ClearWeak();
3528 g2c1.ClearWeak(); 3539 g2c1.ClearWeak();
3529 3540
3530 // Groups are deleted, rebuild groups. 3541 // Groups are deleted, rebuild groups.
3531 { 3542 {
3532 UniqueId id1 = MakeUniqueId(g1s1); 3543 UniqueId id1 = MakeUniqueId(g1s1);
3533 UniqueId id2 = MakeUniqueId(g2s2); 3544 UniqueId id2 = MakeUniqueId(g2s2);
3534 iso->SetObjectGroupId(g1s1, id1); 3545 iso->SetObjectGroupId(g1s1, id1);
3535 iso->SetObjectGroupId(g1s2, id1); 3546 iso->SetObjectGroupId(g1s2, id1);
3536 iso->SetReferenceFromGroup(id1, g1c1); 3547 iso->SetReferenceFromGroup(id1, g1c1);
3537 iso->SetObjectGroupId(g2s1, id2); 3548 iso->SetObjectGroupId(g2s1, id2);
3538 iso->SetObjectGroupId(g2s2, id2); 3549 iso->SetObjectGroupId(g2s2, id2);
3539 iso->SetReferenceFromGroup(id2, g2c1); 3550 iso->SetReferenceFromGroup(id2, g2c1);
3540 } 3551 }
3541 3552
3542 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3553 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3543 3554
3544 // All objects should be gone. 5 global handles in total. 3555 // All objects should be gone. 5 global handles in total.
3545 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3556 CHECK_EQ(5, counter.NumberOfWeakCalls());
3546 3557
3547 // And now make children weak again and collect them. 3558 // And now make children weak again and collect them.
3548 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3559 g1c1.SetWeak(&g1c1p, &WeakPointerCallback);
3549 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3560 g2c1.SetWeak(&g2c1p, &WeakPointerCallback);
3550 3561
3551 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3562 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3552 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3563 CHECK_EQ(7, counter.NumberOfWeakCalls());
3553 } 3564 }
3554 3565
3555 3566
3556 THREADED_TEST(ApiObjectGroupsForSubtypes) { 3567 THREADED_TEST(ApiObjectGroupsForSubtypes) {
3557 LocalContext env; 3568 LocalContext env;
3558 v8::Isolate* iso = env->GetIsolate(); 3569 v8::Isolate* iso = env->GetIsolate();
3559 HandleScope scope(iso); 3570 HandleScope scope(iso);
3560 3571
3561 Persistent<Object> g1s1; 3572 Persistent<Object> g1s1;
3562 Persistent<String> g1s2; 3573 Persistent<String> g1s2;
3563 Persistent<String> g1c1; 3574 Persistent<String> g1c1;
3564 Persistent<Object> g2s1; 3575 Persistent<Object> g2s1;
3565 Persistent<String> g2s2; 3576 Persistent<String> g2s2;
3566 Persistent<String> g2c1; 3577 Persistent<String> g2c1;
3567 3578
3568 WeakCallCounter counter(1234); 3579 WeakCallCounter counter(1234);
3569 3580
3581 pair<Persistent<Object>*, WeakCallCounter*> g1s1p(&g1s1, &counter);
3582 pair<Persistent<String>*, WeakCallCounter*> g1s2p(&g1s2, &counter);
3583 pair<Persistent<String>*, WeakCallCounter*> g1c1p(&g1c1, &counter);
3584 pair<Persistent<Object>*, WeakCallCounter*> g2s1p(&g2s1, &counter);
3585 pair<Persistent<String>*, WeakCallCounter*> g2s2p(&g2s2, &counter);
3586 pair<Persistent<String>*, WeakCallCounter*> g2c1p(&g2c1, &counter);
3587
3570 { 3588 {
3571 HandleScope scope(iso); 3589 HandleScope scope(iso);
3572 g1s1.Reset(iso, Object::New()); 3590 g1s1.Reset(iso, Object::New());
3573 g1s2.Reset(iso, String::NewFromUtf8(iso, "foo1")); 3591 g1s2.Reset(iso, String::NewFromUtf8(iso, "foo1"));
3574 g1c1.Reset(iso, String::NewFromUtf8(iso, "foo2")); 3592 g1c1.Reset(iso, String::NewFromUtf8(iso, "foo2"));
3575 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3593 g1s1.SetWeak(&g1s1p, &WeakPointerCallback);
3576 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3594 g1s2.SetWeak(&g1s2p, &WeakPointerCallback);
3577 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3595 g1c1.SetWeak(&g1c1p, &WeakPointerCallback);
3578 3596
3579 g2s1.Reset(iso, Object::New()); 3597 g2s1.Reset(iso, Object::New());
3580 g2s2.Reset(iso, String::NewFromUtf8(iso, "foo3")); 3598 g2s2.Reset(iso, String::NewFromUtf8(iso, "foo3"));
3581 g2c1.Reset(iso, String::NewFromUtf8(iso, "foo4")); 3599 g2c1.Reset(iso, String::NewFromUtf8(iso, "foo4"));
3582 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3600 g2s1.SetWeak(&g2s1p, &WeakPointerCallback);
3583 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3601 g2s2.SetWeak(&g2s2p, &WeakPointerCallback);
3584 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3602 g2c1.SetWeak(&g2c1p, &WeakPointerCallback);
3585 } 3603 }
3586 3604
3587 Persistent<Value> root(iso, g1s1); // make a root. 3605 Persistent<Value> root(iso, g1s1); // make a root.
3606 pair<Persistent<Value>*, WeakCallCounter*> rootp(&root, &counter);
3588 3607
3589 // Connect group 1 and 2, make a cycle. 3608 // Connect group 1 and 2, make a cycle.
3590 { 3609 {
3591 HandleScope scope(iso); 3610 HandleScope scope(iso);
3592 CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); 3611 CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1)));
3593 CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1))); 3612 CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1)));
3594 } 3613 }
3595 3614
3596 { 3615 {
3597 UniqueId id1 = MakeUniqueId(g1s1); 3616 UniqueId id1 = MakeUniqueId(g1s1);
3598 UniqueId id2 = MakeUniqueId(g2s2); 3617 UniqueId id2 = MakeUniqueId(g2s2);
3599 iso->SetObjectGroupId(g1s1, id1); 3618 iso->SetObjectGroupId(g1s1, id1);
3600 iso->SetObjectGroupId(g1s2, id1); 3619 iso->SetObjectGroupId(g1s2, id1);
3601 iso->SetReference(g1s1, g1c1); 3620 iso->SetReference(g1s1, g1c1);
3602 iso->SetObjectGroupId(g2s1, id2); 3621 iso->SetObjectGroupId(g2s1, id2);
3603 iso->SetObjectGroupId(g2s2, id2); 3622 iso->SetObjectGroupId(g2s2, id2);
3604 iso->SetReferenceFromGroup(id2, g2c1); 3623 iso->SetReferenceFromGroup(id2, g2c1);
3605 } 3624 }
3606 // Do a single full GC, ensure incremental marking is stopped. 3625 // Do a single full GC, ensure incremental marking is stopped.
3607 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3626 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3608 iso)->heap(); 3627 iso)->heap();
3609 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3628 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3610 3629
3611 // All object should be alive. 3630 // All object should be alive.
3612 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3631 CHECK_EQ(0, counter.NumberOfWeakCalls());
3613 3632
3614 // Weaken the root. 3633 // Weaken the root.
3615 root.MakeWeak(&counter, &WeakPointerCallback); 3634 root.SetWeak(&rootp, &WeakPointerCallback);
3616 // But make children strong roots---all the objects (except for children) 3635 // But make children strong roots---all the objects (except for children)
3617 // should be collectable now. 3636 // should be collectable now.
3618 g1c1.ClearWeak(); 3637 g1c1.ClearWeak();
3619 g2c1.ClearWeak(); 3638 g2c1.ClearWeak();
3620 3639
3621 // Groups are deleted, rebuild groups. 3640 // Groups are deleted, rebuild groups.
3622 { 3641 {
3623 UniqueId id1 = MakeUniqueId(g1s1); 3642 UniqueId id1 = MakeUniqueId(g1s1);
3624 UniqueId id2 = MakeUniqueId(g2s2); 3643 UniqueId id2 = MakeUniqueId(g2s2);
3625 iso->SetObjectGroupId(g1s1, id1); 3644 iso->SetObjectGroupId(g1s1, id1);
3626 iso->SetObjectGroupId(g1s2, id1); 3645 iso->SetObjectGroupId(g1s2, id1);
3627 iso->SetReference(g1s1, g1c1); 3646 iso->SetReference(g1s1, g1c1);
3628 iso->SetObjectGroupId(g2s1, id2); 3647 iso->SetObjectGroupId(g2s1, id2);
3629 iso->SetObjectGroupId(g2s2, id2); 3648 iso->SetObjectGroupId(g2s2, id2);
3630 iso->SetReferenceFromGroup(id2, g2c1); 3649 iso->SetReferenceFromGroup(id2, g2c1);
3631 } 3650 }
3632 3651
3633 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3652 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3634 3653
3635 // All objects should be gone. 5 global handles in total. 3654 // All objects should be gone. 5 global handles in total.
3636 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3655 CHECK_EQ(5, counter.NumberOfWeakCalls());
3637 3656
3638 // And now make children weak again and collect them. 3657 // And now make children weak again and collect them.
3639 g1c1.MakeWeak(&counter, &WeakPointerCallback); 3658 g1c1.SetWeak(&g1c1p, &WeakPointerCallback);
3640 g2c1.MakeWeak(&counter, &WeakPointerCallback); 3659 g2c1.SetWeak(&g2c1p, &WeakPointerCallback);
3641 3660
3642 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3661 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3643 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3662 CHECK_EQ(7, counter.NumberOfWeakCalls());
3644 } 3663 }
3645 3664
3646 3665
3647 THREADED_TEST(ApiObjectGroupsCycle) { 3666 THREADED_TEST(ApiObjectGroupsCycle) {
3648 LocalContext env; 3667 LocalContext env;
3649 v8::Isolate* iso = env->GetIsolate(); 3668 v8::Isolate* iso = env->GetIsolate();
3650 HandleScope scope(iso); 3669 HandleScope scope(iso);
3651 3670
3652 WeakCallCounter counter(1234); 3671 WeakCallCounter counter(1234);
3653 3672
3654 Persistent<Value> g1s1; 3673 Persistent<Value> g1s1;
3655 Persistent<Value> g1s2; 3674 Persistent<Value> g1s2;
3656 Persistent<Value> g2s1; 3675 Persistent<Value> g2s1;
3657 Persistent<Value> g2s2; 3676 Persistent<Value> g2s2;
3658 Persistent<Value> g3s1; 3677 Persistent<Value> g3s1;
3659 Persistent<Value> g3s2; 3678 Persistent<Value> g3s2;
3660 Persistent<Value> g4s1; 3679 Persistent<Value> g4s1;
3661 Persistent<Value> g4s2; 3680 Persistent<Value> g4s2;
3662 3681
3682 pair<Persistent<Value>*, WeakCallCounter*> g1s1p(&g1s1, &counter);
3683 pair<Persistent<Value>*, WeakCallCounter*> g1s2p(&g1s2, &counter);
3684 pair<Persistent<Value>*, WeakCallCounter*> g2s1p(&g2s1, &counter);
3685 pair<Persistent<Value>*, WeakCallCounter*> g2s2p(&g2s2, &counter);
3686 pair<Persistent<Value>*, WeakCallCounter*> g3s1p(&g3s1, &counter);
3687 pair<Persistent<Value>*, WeakCallCounter*> g3s2p(&g3s2, &counter);
3688 pair<Persistent<Value>*, WeakCallCounter*> g4s1p(&g4s1, &counter);
3689 pair<Persistent<Value>*, WeakCallCounter*> g4s2p(&g4s2, &counter);
3690
3663 { 3691 {
3664 HandleScope scope(iso); 3692 HandleScope scope(iso);
3665 g1s1.Reset(iso, Object::New()); 3693 g1s1.Reset(iso, Object::New());
3666 g1s2.Reset(iso, Object::New()); 3694 g1s2.Reset(iso, Object::New());
3667 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3695 g1s1.SetWeak(&g1s1p, &WeakPointerCallback);
3668 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3696 g1s2.SetWeak(&g1s2p, &WeakPointerCallback);
3669 CHECK(g1s1.IsWeak()); 3697 CHECK(g1s1.IsWeak());
3670 CHECK(g1s2.IsWeak()); 3698 CHECK(g1s2.IsWeak());
3671 3699
3672 g2s1.Reset(iso, Object::New()); 3700 g2s1.Reset(iso, Object::New());
3673 g2s2.Reset(iso, Object::New()); 3701 g2s2.Reset(iso, Object::New());
3674 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3702 g2s1.SetWeak(&g2s1p, &WeakPointerCallback);
3675 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3703 g2s2.SetWeak(&g2s2p, &WeakPointerCallback);
3676 CHECK(g2s1.IsWeak()); 3704 CHECK(g2s1.IsWeak());
3677 CHECK(g2s2.IsWeak()); 3705 CHECK(g2s2.IsWeak());
3678 3706
3679 g3s1.Reset(iso, Object::New()); 3707 g3s1.Reset(iso, Object::New());
3680 g3s2.Reset(iso, Object::New()); 3708 g3s2.Reset(iso, Object::New());
3681 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3709 g3s1.SetWeak(&g3s1p, &WeakPointerCallback);
3682 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3710 g3s2.SetWeak(&g3s2p, &WeakPointerCallback);
3683 CHECK(g3s1.IsWeak()); 3711 CHECK(g3s1.IsWeak());
3684 CHECK(g3s2.IsWeak()); 3712 CHECK(g3s2.IsWeak());
3685 3713
3686 g4s1.Reset(iso, Object::New()); 3714 g4s1.Reset(iso, Object::New());
3687 g4s2.Reset(iso, Object::New()); 3715 g4s2.Reset(iso, Object::New());
3688 g4s1.MakeWeak(&counter, &WeakPointerCallback); 3716 g4s1.SetWeak(&g4s1p, &WeakPointerCallback);
3689 g4s2.MakeWeak(&counter, &WeakPointerCallback); 3717 g4s2.SetWeak(&g4s2p, &WeakPointerCallback);
3690 CHECK(g4s1.IsWeak()); 3718 CHECK(g4s1.IsWeak());
3691 CHECK(g4s2.IsWeak()); 3719 CHECK(g4s2.IsWeak());
3692 } 3720 }
3693 3721
3694 Persistent<Value> root(iso, g1s1); // make a root. 3722 Persistent<Value> root(iso, g1s1); // make a root.
3723 pair<Persistent<Value>*, WeakCallCounter*> rootp(&root, &counter);
3695 3724
3696 // Connect groups. We're building the following cycle: 3725 // Connect groups. We're building the following cycle:
3697 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3726 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3698 // groups. 3727 // groups.
3699 { 3728 {
3700 UniqueId id1 = MakeUniqueId(g1s1); 3729 UniqueId id1 = MakeUniqueId(g1s1);
3701 UniqueId id2 = MakeUniqueId(g2s1); 3730 UniqueId id2 = MakeUniqueId(g2s1);
3702 UniqueId id3 = MakeUniqueId(g3s1); 3731 UniqueId id3 = MakeUniqueId(g3s1);
3703 UniqueId id4 = MakeUniqueId(g4s1); 3732 UniqueId id4 = MakeUniqueId(g4s1);
3704 iso->SetObjectGroupId(g1s1, id1); 3733 iso->SetObjectGroupId(g1s1, id1);
(...skipping 11 matching lines...) Expand all
3716 } 3745 }
3717 // Do a single full GC 3746 // Do a single full GC
3718 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3747 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3719 iso)->heap(); 3748 iso)->heap();
3720 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 3749 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
3721 3750
3722 // All object should be alive. 3751 // All object should be alive.
3723 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3752 CHECK_EQ(0, counter.NumberOfWeakCalls());
3724 3753
3725 // Weaken the root. 3754 // Weaken the root.
3726 root.MakeWeak(&counter, &WeakPointerCallback); 3755 root.SetWeak(&rootp, &WeakPointerCallback);
3727 3756
3728 // Groups are deleted, rebuild groups. 3757 // Groups are deleted, rebuild groups.
3729 { 3758 {
3730 UniqueId id1 = MakeUniqueId(g1s1); 3759 UniqueId id1 = MakeUniqueId(g1s1);
3731 UniqueId id2 = MakeUniqueId(g2s1); 3760 UniqueId id2 = MakeUniqueId(g2s1);
3732 UniqueId id3 = MakeUniqueId(g3s1); 3761 UniqueId id3 = MakeUniqueId(g3s1);
3733 UniqueId id4 = MakeUniqueId(g4s1); 3762 UniqueId id4 = MakeUniqueId(g4s1);
3734 iso->SetObjectGroupId(g1s1, id1); 3763 iso->SetObjectGroupId(g1s1, id1);
3735 iso->SetObjectGroupId(g1s2, id1); 3764 iso->SetObjectGroupId(g1s2, id1);
3736 iso->SetReferenceFromGroup(id1, g2s1); 3765 iso->SetReferenceFromGroup(id1, g2s1);
(...skipping 26 matching lines...) Expand all
3763 3792
3764 WeakCallCounter counter(1234); 3793 WeakCallCounter counter(1234);
3765 3794
3766 Persistent<Value> g1s1; 3795 Persistent<Value> g1s1;
3767 Persistent<Value> g1s2; 3796 Persistent<Value> g1s2;
3768 Persistent<Value> g2s1; 3797 Persistent<Value> g2s1;
3769 Persistent<Value> g2s2; 3798 Persistent<Value> g2s2;
3770 Persistent<Value> g3s1; 3799 Persistent<Value> g3s1;
3771 Persistent<Value> g3s2; 3800 Persistent<Value> g3s2;
3772 3801
3802 pair<Persistent<Value>*, WeakCallCounter*> g1s1p(&g1s1, &counter);
3803 pair<Persistent<Value>*, WeakCallCounter*> g1s2p(&g1s2, &counter);
3804 pair<Persistent<Value>*, WeakCallCounter*> g2s1p(&g2s1, &counter);
3805 pair<Persistent<Value>*, WeakCallCounter*> g2s2p(&g2s2, &counter);
3806 pair<Persistent<Value>*, WeakCallCounter*> g3s1p(&g3s1, &counter);
3807 pair<Persistent<Value>*, WeakCallCounter*> g3s2p(&g3s2, &counter);
3808
3773 { 3809 {
3774 HandleScope scope(iso); 3810 HandleScope scope(iso);
3775 g1s1.Reset(iso, Object::New()); 3811 g1s1.Reset(iso, Object::New());
3776 g1s2.Reset(iso, Object::New()); 3812 g1s2.Reset(iso, Object::New());
3777 g1s1.MakeWeak(&counter, &WeakPointerCallback); 3813 g1s1.SetWeak(&g1s1p, &WeakPointerCallback);
3778 g1s2.MakeWeak(&counter, &WeakPointerCallback); 3814 g1s2.SetWeak(&g1s2p, &WeakPointerCallback);
3779 3815
3780 g2s1.Reset(iso, Object::New()); 3816 g2s1.Reset(iso, Object::New());
3781 g2s2.Reset(iso, Object::New()); 3817 g2s2.Reset(iso, Object::New());
3782 g2s1.MakeWeak(&counter, &WeakPointerCallback); 3818 g2s1.SetWeak(&g2s1p, &WeakPointerCallback);
3783 g2s2.MakeWeak(&counter, &WeakPointerCallback); 3819 g2s2.SetWeak(&g2s2p, &WeakPointerCallback);
3784 3820
3785 g3s1.Reset(iso, Object::New()); 3821 g3s1.Reset(iso, Object::New());
3786 g3s2.Reset(iso, Object::New()); 3822 g3s2.Reset(iso, Object::New());
3787 g3s1.MakeWeak(&counter, &WeakPointerCallback); 3823 g3s1.SetWeak(&g3s1p, &WeakPointerCallback);
3788 g3s2.MakeWeak(&counter, &WeakPointerCallback); 3824 g3s2.SetWeak(&g3s2p, &WeakPointerCallback);
3789 } 3825 }
3790 3826
3791 // Make a root. 3827 // Make a root.
3792 Persistent<Value> root(iso, g1s1); 3828 Persistent<Value> root(iso, g1s1);
3829 pair<Persistent<Value>*, WeakCallCounter*> rootp(&root, &counter);
3793 root.MarkPartiallyDependent(); 3830 root.MarkPartiallyDependent();
3794 3831
3795 // Connect groups. We're building the following cycle: 3832 // Connect groups. We're building the following cycle:
3796 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3833 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3797 // groups. 3834 // groups.
3798 { 3835 {
3799 HandleScope handle_scope(iso); 3836 HandleScope handle_scope(iso);
3800 g1s1.MarkPartiallyDependent(); 3837 g1s1.MarkPartiallyDependent();
3801 g1s2.MarkPartiallyDependent(); 3838 g1s2.MarkPartiallyDependent();
3802 g2s1.MarkPartiallyDependent(); 3839 g2s1.MarkPartiallyDependent();
(...skipping 15 matching lines...) Expand all
3818 } 3855 }
3819 3856
3820 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( 3857 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
3821 iso)->heap(); 3858 iso)->heap();
3822 heap->CollectGarbage(i::NEW_SPACE); 3859 heap->CollectGarbage(i::NEW_SPACE);
3823 3860
3824 // All objects should be alive. 3861 // All objects should be alive.
3825 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3862 CHECK_EQ(0, counter.NumberOfWeakCalls());
3826 3863
3827 // Weaken the root. 3864 // Weaken the root.
3828 root.MakeWeak(&counter, &WeakPointerCallback); 3865 root.SetWeak(&rootp, &WeakPointerCallback);
3829 root.MarkPartiallyDependent(); 3866 root.MarkPartiallyDependent();
3830 3867
3831 // Groups are deleted, rebuild groups. 3868 // Groups are deleted, rebuild groups.
3832 { 3869 {
3833 HandleScope handle_scope(iso); 3870 HandleScope handle_scope(iso);
3834 g1s1.MarkPartiallyDependent(); 3871 g1s1.MarkPartiallyDependent();
3835 g1s2.MarkPartiallyDependent(); 3872 g1s2.MarkPartiallyDependent();
3836 g2s1.MarkPartiallyDependent(); 3873 g2s1.MarkPartiallyDependent();
3837 g2s2.MarkPartiallyDependent(); 3874 g2s2.MarkPartiallyDependent();
3838 g3s1.MarkPartiallyDependent(); 3875 g3s1.MarkPartiallyDependent();
(...skipping 3103 matching lines...) Expand 10 before | Expand all | Expand 10 after
6942 v8::V8::AddMessageListener(MissingScriptInfoMessageListener); 6979 v8::V8::AddMessageListener(MissingScriptInfoMessageListener);
6943 Script::Compile(v8_str("throw Error()"))->Run(); 6980 Script::Compile(v8_str("throw Error()"))->Run();
6944 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); 6981 v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener);
6945 } 6982 }
6946 6983
6947 6984
6948 int global_index = 0; 6985 int global_index = 0;
6949 6986
6950 class Snorkel { 6987 class Snorkel {
6951 public: 6988 public:
6952 Snorkel() { index_ = global_index++; } 6989 explicit Snorkel(v8::Persistent<v8::Object>* prev)
6990 : prev_(prev), index_(global_index++) { }
6991 v8::Persistent<v8::Object>* prev_;
6953 int index_; 6992 int index_;
6954 }; 6993 };
6955 6994
6956 class Whammy { 6995 class Whammy {
6957 public: 6996 public:
6958 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { } 6997 explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
6959 ~Whammy() { script_.Reset(); } 6998 ~Whammy() { script_.Reset(); }
6960 v8::Handle<Script> getScript() { 6999 v8::Handle<Script> getScript() {
6961 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo")); 7000 if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
6962 return Local<Script>::New(isolate_, script_); 7001 return Local<Script>::New(isolate_, script_);
6963 } 7002 }
6964 7003
6965 public: 7004 public:
6966 static const int kObjectCount = 256; 7005 static const int kObjectCount = 256;
6967 int cursor_; 7006 int cursor_;
6968 v8::Isolate* isolate_; 7007 v8::Isolate* isolate_;
6969 v8::Persistent<v8::Object> objects_[kObjectCount]; 7008 v8::Persistent<v8::Object> objects_[kObjectCount];
6970 v8::Persistent<Script> script_; 7009 v8::Persistent<Script> script_;
6971 }; 7010 };
6972 7011
6973 static void HandleWeakReference(v8::Isolate* isolate, 7012 static void HandleWeakReference(
6974 v8::Persistent<v8::Value>* obj, 7013 const v8::WeakCallbackData<v8::Object, Snorkel>& data) {
6975 Snorkel* snorkel) { 7014 data.GetParameter()->prev_->ClearWeak();
6976 delete snorkel; 7015 delete data.GetParameter();
6977 obj->ClearWeak();
6978 } 7016 }
6979 7017
6980 void WhammyPropertyGetter(Local<String> name, 7018 void WhammyPropertyGetter(Local<String> name,
6981 const v8::PropertyCallbackInfo<v8::Value>& info) { 7019 const v8::PropertyCallbackInfo<v8::Value>& info) {
6982 Whammy* whammy = 7020 Whammy* whammy =
6983 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); 7021 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
6984 7022
6985 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_]; 7023 v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
6986 7024
6987 v8::Handle<v8::Object> obj = v8::Object::New(); 7025 v8::Handle<v8::Object> obj = v8::Object::New();
6988 if (!prev.IsEmpty()) { 7026 if (!prev.IsEmpty()) {
6989 v8::Local<v8::Object>::New(info.GetIsolate(), prev) 7027 v8::Local<v8::Object>::New(info.GetIsolate(), prev)
6990 ->Set(v8_str("next"), obj); 7028 ->Set(v8_str("next"), obj);
6991 prev.MakeWeak<Value, Snorkel>(new Snorkel(), &HandleWeakReference); 7029 prev.SetWeak(new Snorkel(&prev), &HandleWeakReference);
6992 } 7030 }
6993 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj); 7031 whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj);
6994 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; 7032 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount;
6995 info.GetReturnValue().Set(whammy->getScript()->Run()); 7033 info.GetReturnValue().Set(whammy->getScript()->Run());
6996 } 7034 }
6997 7035
6998 7036
6999 THREADED_TEST(WeakReference) { 7037 THREADED_TEST(WeakReference) {
7000 v8::HandleScope handle_scope(CcTest::isolate()); 7038 v8::HandleScope handle_scope(CcTest::isolate());
7001 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); 7039 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New();
(...skipping 17 matching lines...) Expand all
7019 " last = obj;" 7057 " last = obj;"
7020 "}" 7058 "}"
7021 "gc();" 7059 "gc();"
7022 "4"; 7060 "4";
7023 v8::Handle<Value> result = CompileRun(code); 7061 v8::Handle<Value> result = CompileRun(code);
7024 CHECK_EQ(4.0, result->NumberValue()); 7062 CHECK_EQ(4.0, result->NumberValue());
7025 delete whammy; 7063 delete whammy;
7026 } 7064 }
7027 7065
7028 7066
7029 static void DisposeAndSetFlag(v8::Isolate* isolate, 7067 static void DisposeAndSetFlag(
7030 v8::Persistent<v8::Object>* obj, 7068 const v8::WeakCallbackData<v8::Object,
7031 bool* data) { 7069 pair<v8::Persistent<v8::Object>*,
7032 obj->Reset(); 7070 bool> >& data) {
7033 *(data) = true; 7071 data.GetParameter()->first->Reset();
7072 data.GetParameter()->second = true;
7034 } 7073 }
7035 7074
7036 7075
7037 THREADED_TEST(IndependentWeakHandle) { 7076 THREADED_TEST(IndependentWeakHandle) {
7038 v8::Isolate* iso = CcTest::isolate(); 7077 v8::Isolate* iso = CcTest::isolate();
7039 v8::HandleScope scope(iso); 7078 v8::HandleScope scope(iso);
7040 v8::Handle<Context> context = Context::New(iso); 7079 v8::Handle<Context> context = Context::New(iso);
7041 Context::Scope context_scope(context); 7080 Context::Scope context_scope(context);
7042 7081
7043 v8::Persistent<v8::Object> object_a, object_b; 7082 v8::Persistent<v8::Object> object_a, object_b;
7044 7083
7045 { 7084 {
7046 v8::HandleScope handle_scope(iso); 7085 v8::HandleScope handle_scope(iso);
7047 object_a.Reset(iso, v8::Object::New()); 7086 object_a.Reset(iso, v8::Object::New());
7048 object_b.Reset(iso, v8::Object::New()); 7087 object_b.Reset(iso, v8::Object::New());
7049 } 7088 }
7050 7089
7051 bool object_a_disposed = false; 7090 pair<v8::Persistent<v8::Object>*, bool> object_a_pair(&object_a, false);
7052 bool object_b_disposed = false; 7091 pair<v8::Persistent<v8::Object>*, bool> object_b_pair(&object_b, false);
7053 object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag); 7092 object_a.SetWeak(&object_a_pair, &DisposeAndSetFlag);
7054 object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag); 7093 object_b.SetWeak(&object_b_pair, &DisposeAndSetFlag);
7055 CHECK(!object_b.IsIndependent()); 7094 CHECK(!object_b.IsIndependent());
7056 object_a.MarkIndependent(); 7095 object_a.MarkIndependent();
7057 object_b.MarkIndependent(); 7096 object_b.MarkIndependent();
7058 CHECK(object_b.IsIndependent()); 7097 CHECK(object_b.IsIndependent());
7059 CcTest::heap()->PerformScavenge(); 7098 CcTest::heap()->PerformScavenge();
7060 CHECK(object_a_disposed); 7099 CHECK(object_a_pair.second);
7061 CHECK(object_b_disposed); 7100 CHECK(object_b_pair.second);
7062 } 7101 }
7063 7102
7064 7103
7065 static void InvokeScavenge() { 7104 static void InvokeScavenge() {
7066 CcTest::heap()->PerformScavenge(); 7105 CcTest::heap()->PerformScavenge();
7067 } 7106 }
7068 7107
7069 7108
7070 static void InvokeMarkSweep() { 7109 static void InvokeMarkSweep() {
7071 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 7110 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
7072 } 7111 }
7073 7112
7074 7113
7075 static void ForceScavenge(v8::Isolate* isolate, 7114 static void ForceScavenge(
7076 v8::Persistent<v8::Object>* obj, 7115 const v8::WeakCallbackData<v8::Object,
7077 bool* data) { 7116 pair<v8::Persistent<v8::Object>*,
7078 obj->Reset(); 7117 bool> >& data) {
7079 *(data) = true; 7118 data.GetParameter()->first->Reset();
7119 data.GetParameter()->second = true;
7080 InvokeScavenge(); 7120 InvokeScavenge();
7081 } 7121 }
7082 7122
7083 7123
7084 static void ForceMarkSweep(v8::Isolate* isolate, 7124 static void ForceMarkSweep(
7085 v8::Persistent<v8::Object>* obj, 7125 const v8::WeakCallbackData<v8::Object,
7086 bool* data) { 7126 pair<v8::Persistent<v8::Object>*,
7087 obj->Reset(); 7127 bool> >& data) {
7088 *(data) = true; 7128 data.GetParameter()->first->Reset();
7129 data.GetParameter()->second = true;
7089 InvokeMarkSweep(); 7130 InvokeMarkSweep();
7090 } 7131 }
7091 7132
7092 7133
7093 THREADED_TEST(GCFromWeakCallbacks) { 7134 THREADED_TEST(GCFromWeakCallbacks) {
7094 v8::Isolate* isolate = CcTest::isolate(); 7135 v8::Isolate* isolate = CcTest::isolate();
7095 v8::HandleScope scope(isolate); 7136 v8::HandleScope scope(isolate);
7096 v8::Handle<Context> context = Context::New(isolate); 7137 v8::Handle<Context> context = Context::New(isolate);
7097 Context::Scope context_scope(context); 7138 Context::Scope context_scope(context);
7098 7139
7099 static const int kNumberOfGCTypes = 2; 7140 static const int kNumberOfGCTypes = 2;
7100 typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback; 7141 typedef v8::WeakCallbackData<v8::Object,
7142 pair<v8::Persistent<v8::Object>*,
7143 bool> >::Callback Callback;
7101 Callback gc_forcing_callback[kNumberOfGCTypes] = 7144 Callback gc_forcing_callback[kNumberOfGCTypes] =
7102 {&ForceScavenge, &ForceMarkSweep}; 7145 {&ForceScavenge, &ForceMarkSweep};
7103 7146
7104 typedef void (*GCInvoker)(); 7147 typedef void (*GCInvoker)();
7105 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; 7148 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep};
7106 7149
7107 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { 7150 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
7108 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { 7151 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
7109 v8::Persistent<v8::Object> object; 7152 v8::Persistent<v8::Object> object;
7110 { 7153 {
7111 v8::HandleScope handle_scope(isolate); 7154 v8::HandleScope handle_scope(isolate);
7112 object.Reset(isolate, v8::Object::New()); 7155 object.Reset(isolate, v8::Object::New());
7113 } 7156 }
7114 bool disposed = false; 7157 pair<v8::Persistent<v8::Object>*, bool> object_pair(&object, false);
7115 object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]); 7158 object.SetWeak(&object_pair, gc_forcing_callback[inner_gc]);
7116 object.MarkIndependent(); 7159 object.MarkIndependent();
7117 invoke_gc[outer_gc](); 7160 invoke_gc[outer_gc]();
7118 CHECK(disposed); 7161 CHECK(object_pair.second);
7119 } 7162 }
7120 } 7163 }
7121 } 7164 }
7122 7165
7123 7166
7124 static void RevivingCallback(v8::Isolate* isolate, 7167 static void RevivingCallback(
7125 v8::Persistent<v8::Object>* obj, 7168 const v8::WeakCallbackData<v8::Object,
7126 bool* data) { 7169 std::pair<v8::Persistent<Object>*,
7127 obj->ClearWeak(); 7170 bool> >& data) {
7128 *(data) = true; 7171 data.GetParameter()->first->ClearWeak();
7172 data.GetParameter()->second = true;
7129 } 7173 }
7130 7174
7131 7175
7132 THREADED_TEST(IndependentHandleRevival) { 7176 THREADED_TEST(IndependentHandleRevival) {
7133 v8::Isolate* isolate = CcTest::isolate(); 7177 v8::Isolate* isolate = CcTest::isolate();
7134 v8::HandleScope scope(isolate); 7178 v8::HandleScope scope(isolate);
7135 v8::Handle<Context> context = Context::New(isolate); 7179 v8::Handle<Context> context = Context::New(isolate);
7136 Context::Scope context_scope(context); 7180 Context::Scope context_scope(context);
7137 7181
7138 v8::Persistent<v8::Object> object; 7182 v8::Persistent<v8::Object> object;
7139 { 7183 {
7140 v8::HandleScope handle_scope(isolate); 7184 v8::HandleScope handle_scope(isolate);
7141 v8::Local<v8::Object> o = v8::Object::New(); 7185 v8::Local<v8::Object> o = v8::Object::New();
7142 object.Reset(isolate, o); 7186 object.Reset(isolate, o);
7143 o->Set(v8_str("x"), v8::Integer::New(1)); 7187 o->Set(v8_str("x"), v8::Integer::New(1));
7144 v8::Local<String> y_str = v8_str("y"); 7188 v8::Local<String> y_str = v8_str("y");
7145 o->Set(y_str, y_str); 7189 o->Set(y_str, y_str);
7146 } 7190 }
7147 bool revived = false; 7191 pair<v8::Persistent<v8::Object>*, bool> revived(&object, false);
7148 object.MakeWeak(&revived, &RevivingCallback); 7192 object.SetWeak(&revived, &RevivingCallback);
7149 object.MarkIndependent(); 7193 object.MarkIndependent();
7150 CcTest::heap()->PerformScavenge(); 7194 CcTest::heap()->PerformScavenge();
7151 CHECK(revived); 7195 CHECK(revived.second);
7152 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 7196 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
7153 { 7197 {
7154 v8::HandleScope handle_scope(isolate); 7198 v8::HandleScope handle_scope(isolate);
7155 v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object); 7199 v8::Local<v8::Object> o = v8::Local<v8::Object>::New(isolate, object);
7156 v8::Local<String> y_str = v8_str("y"); 7200 v8::Local<String> y_str = v8_str("y");
7157 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x"))); 7201 CHECK_EQ(v8::Integer::New(1), o->Get(v8_str("x")));
7158 CHECK(o->Get(y_str)->Equals(y_str)); 7202 CHECK(o->Get(y_str)->Equals(y_str));
7159 } 7203 }
7160 } 7204 }
7161 7205
(...skipping 5937 matching lines...) Expand 10 before | Expand all | Expand 10 after
13099 reinterpret_cast<i::Isolate*>(isolate)->heap()-> 13143 reinterpret_cast<i::Isolate*>(isolate)->heap()->
13100 CollectAllGarbage(i::Heap::kNoGCFlags); 13144 CollectAllGarbage(i::Heap::kNoGCFlags);
13101 // Verify disposed. 13145 // Verify disposed.
13102 CHECK_EQ(initial_handles, globals->global_handles_count()); 13146 CHECK_EQ(initial_handles, globals->global_handles_count());
13103 } 13147 }
13104 13148
13105 13149
13106 v8::Persistent<v8::Object> some_object; 13150 v8::Persistent<v8::Object> some_object;
13107 v8::Persistent<v8::Object> bad_handle; 13151 v8::Persistent<v8::Object> bad_handle;
13108 13152
13109 void NewPersistentHandleCallback(v8::Isolate* isolate, 13153 void NewPersistentHandleCallback(
13110 v8::Persistent<v8::Value>* handle, 13154 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13111 void*) { 13155 v8::HandleScope scope(data.GetIsolate());
13112 v8::HandleScope scope(isolate); 13156 bad_handle.Reset(data.GetIsolate(), some_object);
13113 bad_handle.Reset(isolate, some_object); 13157 data.GetParameter()->Reset();
13114 handle->Reset();
13115 } 13158 }
13116 13159
13117 13160
13118 THREADED_TEST(NewPersistentHandleFromWeakCallback) { 13161 THREADED_TEST(NewPersistentHandleFromWeakCallback) {
13119 LocalContext context; 13162 LocalContext context;
13120 v8::Isolate* isolate = context->GetIsolate(); 13163 v8::Isolate* isolate = context->GetIsolate();
13121 13164
13122 v8::Persistent<v8::Object> handle1, handle2; 13165 v8::Persistent<v8::Object> handle1, handle2;
13123 { 13166 {
13124 v8::HandleScope scope(isolate); 13167 v8::HandleScope scope(isolate);
13125 some_object.Reset(isolate, v8::Object::New()); 13168 some_object.Reset(isolate, v8::Object::New());
13126 handle1.Reset(isolate, v8::Object::New()); 13169 handle1.Reset(isolate, v8::Object::New());
13127 handle2.Reset(isolate, v8::Object::New()); 13170 handle2.Reset(isolate, v8::Object::New());
13128 } 13171 }
13129 // Note: order is implementation dependent alas: currently 13172 // Note: order is implementation dependent alas: currently
13130 // global handle nodes are processed by PostGarbageCollectionProcessing 13173 // global handle nodes are processed by PostGarbageCollectionProcessing
13131 // in reverse allocation order, so if second allocated handle is deleted, 13174 // in reverse allocation order, so if second allocated handle is deleted,
13132 // weak callback of the first handle would be able to 'reallocate' it. 13175 // weak callback of the first handle would be able to 'reallocate' it.
13133 handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback); 13176 handle1.SetWeak(&handle1, NewPersistentHandleCallback);
13134 handle2.Reset(); 13177 handle2.Reset();
13135 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13178 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13136 } 13179 }
13137 13180
13138 13181
13139 v8::Persistent<v8::Object> to_be_disposed; 13182 v8::Persistent<v8::Object> to_be_disposed;
13140 13183
13141 void DisposeAndForceGcCallback(v8::Isolate* isolate, 13184 void DisposeAndForceGcCallback(
13142 v8::Persistent<v8::Value>* handle, 13185 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13143 void*) {
13144 to_be_disposed.Reset(); 13186 to_be_disposed.Reset();
13145 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13187 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13146 handle->Reset(); 13188 data.GetParameter()->Reset();
13147 } 13189 }
13148 13190
13149 13191
13150 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { 13192 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
13151 LocalContext context; 13193 LocalContext context;
13152 v8::Isolate* isolate = context->GetIsolate(); 13194 v8::Isolate* isolate = context->GetIsolate();
13153 13195
13154 v8::Persistent<v8::Object> handle1, handle2; 13196 v8::Persistent<v8::Object> handle1, handle2;
13155 { 13197 {
13156 v8::HandleScope scope(isolate); 13198 v8::HandleScope scope(isolate);
13157 handle1.Reset(isolate, v8::Object::New()); 13199 handle1.Reset(isolate, v8::Object::New());
13158 handle2.Reset(isolate, v8::Object::New()); 13200 handle2.Reset(isolate, v8::Object::New());
13159 } 13201 }
13160 handle1.MakeWeak<v8::Value, void>(NULL, DisposeAndForceGcCallback); 13202 handle1.SetWeak(&handle1, DisposeAndForceGcCallback);
13161 to_be_disposed.Reset(isolate, handle2); 13203 to_be_disposed.Reset(isolate, handle2);
13162 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13204 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13163 } 13205 }
13164 13206
13165 void DisposingCallback(v8::Isolate* isolate, 13207 void DisposingCallback(
13166 v8::Persistent<v8::Value>* handle, 13208 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13167 void*) { 13209 data.GetParameter()->Reset();
13168 handle->Reset();
13169 } 13210 }
13170 13211
13171 void HandleCreatingCallback(v8::Isolate* isolate, 13212 void HandleCreatingCallback(
13172 v8::Persistent<v8::Value>* handle, 13213 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) {
13173 void*) { 13214 v8::HandleScope scope(data.GetIsolate());
13174 v8::HandleScope scope(isolate); 13215 v8::Persistent<v8::Object>(data.GetIsolate(), v8::Object::New());
13175 v8::Persistent<v8::Object>(isolate, v8::Object::New()); 13216 data.GetParameter()->Reset();
13176 handle->Reset();
13177 } 13217 }
13178 13218
13179 13219
13180 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { 13220 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
13181 LocalContext context; 13221 LocalContext context;
13182 v8::Isolate* isolate = context->GetIsolate(); 13222 v8::Isolate* isolate = context->GetIsolate();
13183 13223
13184 v8::Persistent<v8::Object> handle1, handle2, handle3; 13224 v8::Persistent<v8::Object> handle1, handle2, handle3;
13185 { 13225 {
13186 v8::HandleScope scope(isolate); 13226 v8::HandleScope scope(isolate);
13187 handle3.Reset(isolate, v8::Object::New()); 13227 handle3.Reset(isolate, v8::Object::New());
13188 handle2.Reset(isolate, v8::Object::New()); 13228 handle2.Reset(isolate, v8::Object::New());
13189 handle1.Reset(isolate, v8::Object::New()); 13229 handle1.Reset(isolate, v8::Object::New());
13190 } 13230 }
13191 handle2.MakeWeak<v8::Value, void>(NULL, DisposingCallback); 13231 handle2.SetWeak(&handle2, DisposingCallback);
13192 handle3.MakeWeak<v8::Value, void>(NULL, HandleCreatingCallback); 13232 handle3.SetWeak(&handle3, HandleCreatingCallback);
13193 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); 13233 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
13194 } 13234 }
13195 13235
13196 13236
13197 THREADED_TEST(CheckForCrossContextObjectLiterals) { 13237 THREADED_TEST(CheckForCrossContextObjectLiterals) {
13198 v8::V8::Initialize(); 13238 v8::V8::Initialize();
13199 13239
13200 const int nof = 2; 13240 const int nof = 2;
13201 const char* sources[nof] = { 13241 const char* sources[nof] = {
13202 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", 13242 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }",
(...skipping 7651 matching lines...) Expand 10 before | Expand all | Expand 10 after
20854 } 20894 }
20855 for (int i = 0; i < runs; i++) { 20895 for (int i = 0; i < runs; i++) {
20856 Local<String> expected; 20896 Local<String> expected;
20857 if (i != 0) { 20897 if (i != 0) {
20858 CHECK_EQ(v8_str("escape value"), values[i]); 20898 CHECK_EQ(v8_str("escape value"), values[i]);
20859 } else { 20899 } else {
20860 CHECK(values[i].IsEmpty()); 20900 CHECK(values[i].IsEmpty());
20861 } 20901 }
20862 } 20902 }
20863 } 20903 }
OLDNEW
« src/d8.cc ('K') | « 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