| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |