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

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

Issue 1089853005: prepare to deprecate non phantom weak callbacks (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months 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
« no previous file with comments | « src/d8.cc ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3196 matching lines...) Expand 10 before | Expand all | Expand 10 after
3207 } 3207 }
3208 array[5]->MarkTriggerGc(); 3208 array[5]->MarkTriggerGc();
3209 array[10]->MarkTriggerGc(); 3209 array[10]->MarkTriggerGc();
3210 array[15]->MarkTriggerGc(); 3210 array[15]->MarkTriggerGc();
3211 CHECK_EQ(static_cast<int>(kLength), instance_counter); 3211 CHECK_EQ(static_cast<int>(kLength), instance_counter);
3212 CcTest::heap()->CollectAllGarbage(); 3212 CcTest::heap()->CollectAllGarbage();
3213 CHECK_EQ(0, instance_counter); 3213 CHECK_EQ(0, instance_counter);
3214 } 3214 }
3215 3215
3216 3216
3217 template <typename K, typename V>
3218 class WeakStdMapTraits : public v8::StdMapTraits<K, V> {
3219 public:
3220 typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V>> MapType;
3221 static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak;
3222 struct WeakCallbackDataType {
3223 MapType* map;
3224 K key;
3225 };
3226 static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
3227 Local<V> value) {
3228 WeakCallbackDataType* data = new WeakCallbackDataType;
3229 data->map = map;
3230 data->key = key;
3231 return data;
3232 }
3233 static MapType* MapFromWeakCallbackData(
3234 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
3235 return data.GetParameter()->map;
3236 }
3237 static K KeyFromWeakCallbackData(
3238 const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
3239 return data.GetParameter()->key;
3240 }
3241 static void DisposeCallbackData(WeakCallbackDataType* data) { delete data; }
3242 static void Dispose(v8::Isolate* isolate, v8::Global<V> value, K key) {}
3243 };
3244
3245
3246 template <typename Map>
3247 static void TestPersistentValueMap() {
3248 LocalContext env;
3249 v8::Isolate* isolate = env->GetIsolate();
3250 Map map(isolate);
3251 v8::internal::GlobalHandles* global_handles =
3252 reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
3253 int initial_handle_count = global_handles->global_handles_count();
3254 CHECK_EQ(0, static_cast<int>(map.Size()));
3255 {
3256 HandleScope scope(isolate);
3257 Local<v8::Object> obj = map.Get(7);
3258 CHECK(obj.IsEmpty());
3259 Local<v8::Object> expected = v8::Object::New(isolate);
3260 map.Set(7, expected);
3261 CHECK_EQ(1, static_cast<int>(map.Size()));
3262 obj = map.Get(7);
3263 CHECK(expected->Equals(obj));
3264 {
3265 typename Map::PersistentValueReference ref = map.GetReference(7);
3266 CHECK(expected->Equals(ref.NewLocal(isolate)));
3267 }
3268 v8::Global<v8::Object> removed = map.Remove(7);
3269 CHECK_EQ(0, static_cast<int>(map.Size()));
3270 CHECK(expected == removed);
3271 removed = map.Remove(7);
3272 CHECK(removed.IsEmpty());
3273 map.Set(8, expected);
3274 CHECK_EQ(1, static_cast<int>(map.Size()));
3275 map.Set(8, expected);
3276 CHECK_EQ(1, static_cast<int>(map.Size()));
3277 {
3278 typename Map::PersistentValueReference ref;
3279 Local<v8::Object> expected2 = v8::Object::New(isolate);
3280 removed = map.Set(8, v8::Global<v8::Object>(isolate, expected2), &ref);
3281 CHECK_EQ(1, static_cast<int>(map.Size()));
3282 CHECK(expected == removed);
3283 CHECK(expected2->Equals(ref.NewLocal(isolate)));
3284 }
3285 }
3286 CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
3287 if (map.IsWeak()) {
3288 reinterpret_cast<v8::internal::Isolate*>(isolate)
3289 ->heap()
3290 ->CollectAllGarbage();
3291 } else {
3292 map.Clear();
3293 }
3294 CHECK_EQ(0, static_cast<int>(map.Size()));
3295 CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
3296 }
3297
3298
3299 TEST(PersistentValueMap) {
3300 // Default case, w/o weak callbacks:
3301 TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object>>();
3302
3303 // Custom traits with weak callbacks:
3304 typedef v8::PersistentValueMap<int, v8::Object,
3305 WeakStdMapTraits<int, v8::Object>>
3306 WeakPersistentValueMap;
3307 TestPersistentValueMap<WeakPersistentValueMap>();
3308 }
3309
3310
3311 namespace { 3217 namespace {
3312 3218
3313 void* IntKeyToVoidPointer(int key) { return reinterpret_cast<void*>(key << 1); } 3219 void* IntKeyToVoidPointer(int key) { return reinterpret_cast<void*>(key << 1); }
3314 3220
3315 3221
3316 Local<v8::Object> NewObjectForIntKey( 3222 Local<v8::Object> NewObjectForIntKey(
3317 v8::Isolate* isolate, const v8::Global<v8::ObjectTemplate>& templ, 3223 v8::Isolate* isolate, const v8::Global<v8::ObjectTemplate>& templ,
3318 int key) { 3224 int key) {
3319 auto local = Local<v8::ObjectTemplate>::New(isolate, templ); 3225 auto local = Local<v8::ObjectTemplate>::New(isolate, templ);
3320 auto obj = local->NewInstance(); 3226 auto obj = local->NewInstance();
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 struct WeakCallCounterAndPersistent { 3467 struct WeakCallCounterAndPersistent {
3562 explicit WeakCallCounterAndPersistent(WeakCallCounter* counter) 3468 explicit WeakCallCounterAndPersistent(WeakCallCounter* counter)
3563 : counter(counter) {} 3469 : counter(counter) {}
3564 WeakCallCounter* counter; 3470 WeakCallCounter* counter;
3565 v8::Persistent<T> handle; 3471 v8::Persistent<T> handle;
3566 }; 3472 };
3567 3473
3568 3474
3569 template <typename T> 3475 template <typename T>
3570 static void WeakPointerCallback( 3476 static void WeakPointerCallback(
3571 const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T>>& data) { 3477 const v8::WeakCallbackInfo<WeakCallCounterAndPersistent<T>>& data) {
3572 CHECK_EQ(1234, data.GetParameter()->counter->id()); 3478 CHECK_EQ(1234, data.GetParameter()->counter->id());
3573 data.GetParameter()->counter->increment(); 3479 data.GetParameter()->counter->increment();
3574 data.GetParameter()->handle.Reset(); 3480 data.GetParameter()->handle.Reset();
3575 } 3481 }
3576 3482
3577 3483
3578 template <typename T> 3484 template <typename T>
3579 static UniqueId MakeUniqueId(const Persistent<T>& p) { 3485 static UniqueId MakeUniqueId(const Persistent<T>& p) {
3580 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); 3486 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
3581 } 3487 }
(...skipping 11 matching lines...) Expand all
3593 WeakCallCounterAndPersistent<Value> g1c1(&counter); 3499 WeakCallCounterAndPersistent<Value> g1c1(&counter);
3594 WeakCallCounterAndPersistent<Value> g2s1(&counter); 3500 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3595 WeakCallCounterAndPersistent<Value> g2s2(&counter); 3501 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3596 WeakCallCounterAndPersistent<Value> g2c1(&counter); 3502 WeakCallCounterAndPersistent<Value> g2c1(&counter);
3597 3503
3598 { 3504 {
3599 HandleScope scope(iso); 3505 HandleScope scope(iso);
3600 g1s1.handle.Reset(iso, Object::New(iso)); 3506 g1s1.handle.Reset(iso, Object::New(iso));
3601 g1s2.handle.Reset(iso, Object::New(iso)); 3507 g1s2.handle.Reset(iso, Object::New(iso));
3602 g1c1.handle.Reset(iso, Object::New(iso)); 3508 g1c1.handle.Reset(iso, Object::New(iso));
3603 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); 3509 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
3604 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); 3510 v8::WeakCallbackType::kParameter);
3605 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); 3511 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
3512 v8::WeakCallbackType::kParameter);
3513 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
3514 v8::WeakCallbackType::kParameter);
3606 3515
3607 g2s1.handle.Reset(iso, Object::New(iso)); 3516 g2s1.handle.Reset(iso, Object::New(iso));
3608 g2s2.handle.Reset(iso, Object::New(iso)); 3517 g2s2.handle.Reset(iso, Object::New(iso));
3609 g2c1.handle.Reset(iso, Object::New(iso)); 3518 g2c1.handle.Reset(iso, Object::New(iso));
3610 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); 3519 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
3611 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); 3520 v8::WeakCallbackType::kParameter);
3612 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); 3521 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
3522 v8::WeakCallbackType::kParameter);
3523 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
3524 v8::WeakCallbackType::kParameter);
3613 } 3525 }
3614 3526
3615 WeakCallCounterAndPersistent<Value> root(&counter); 3527 WeakCallCounterAndPersistent<Value> root(&counter);
3616 root.handle.Reset(iso, g1s1.handle); // make a root. 3528 root.handle.Reset(iso, g1s1.handle); // make a root.
3617 3529
3618 // Connect group 1 and 2, make a cycle. 3530 // Connect group 1 and 2, make a cycle.
3619 { 3531 {
3620 HandleScope scope(iso); 3532 HandleScope scope(iso);
3621 CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>()) 3533 CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())
3622 ->Set(0, Local<Value>::New(iso, g2s2.handle))); 3534 ->Set(0, Local<Value>::New(iso, g2s2.handle)));
(...skipping 13 matching lines...) Expand all
3636 } 3548 }
3637 // Do a single full GC, ensure incremental marking is stopped. 3549 // Do a single full GC, ensure incremental marking is stopped.
3638 v8::internal::Heap* heap = 3550 v8::internal::Heap* heap =
3639 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); 3551 reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
3640 heap->CollectAllGarbage(); 3552 heap->CollectAllGarbage();
3641 3553
3642 // All object should be alive. 3554 // All object should be alive.
3643 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3555 CHECK_EQ(0, counter.NumberOfWeakCalls());
3644 3556
3645 // Weaken the root. 3557 // Weaken the root.
3646 root.handle.SetWeak(&root, &WeakPointerCallback); 3558 root.handle.SetWeak(&root, &WeakPointerCallback,
3559 v8::WeakCallbackType::kParameter);
3647 // But make children strong roots---all the objects (except for children) 3560 // But make children strong roots---all the objects (except for children)
3648 // should be collectable now. 3561 // should be collectable now.
3649 g1c1.handle.ClearWeak(); 3562 g1c1.handle.ClearWeak();
3650 g2c1.handle.ClearWeak(); 3563 g2c1.handle.ClearWeak();
3651 3564
3652 // Groups are deleted, rebuild groups. 3565 // Groups are deleted, rebuild groups.
3653 { 3566 {
3654 UniqueId id1 = MakeUniqueId(g1s1.handle); 3567 UniqueId id1 = MakeUniqueId(g1s1.handle);
3655 UniqueId id2 = MakeUniqueId(g2s2.handle); 3568 UniqueId id2 = MakeUniqueId(g2s2.handle);
3656 iso->SetObjectGroupId(g1s1.handle, id1); 3569 iso->SetObjectGroupId(g1s1.handle, id1);
3657 iso->SetObjectGroupId(g1s2.handle, id1); 3570 iso->SetObjectGroupId(g1s2.handle, id1);
3658 iso->SetReferenceFromGroup(id1, g1c1.handle); 3571 iso->SetReferenceFromGroup(id1, g1c1.handle);
3659 iso->SetObjectGroupId(g2s1.handle, id2); 3572 iso->SetObjectGroupId(g2s1.handle, id2);
3660 iso->SetObjectGroupId(g2s2.handle, id2); 3573 iso->SetObjectGroupId(g2s2.handle, id2);
3661 iso->SetReferenceFromGroup(id2, g2c1.handle); 3574 iso->SetReferenceFromGroup(id2, g2c1.handle);
3662 } 3575 }
3663 3576
3664 heap->CollectAllGarbage(); 3577 heap->CollectAllGarbage();
3665 3578
3666 // All objects should be gone. 5 global handles in total. 3579 // All objects should be gone. 5 global handles in total.
3667 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3580 CHECK_EQ(5, counter.NumberOfWeakCalls());
3668 3581
3669 // And now make children weak again and collect them. 3582 // And now make children weak again and collect them.
3670 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); 3583 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
3671 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); 3584 v8::WeakCallbackType::kParameter);
3585 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
3586 v8::WeakCallbackType::kParameter);
3672 3587
3673 heap->CollectAllGarbage(); 3588 heap->CollectAllGarbage();
3674 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3589 CHECK_EQ(7, counter.NumberOfWeakCalls());
3675 } 3590 }
3676 3591
3677 3592
3678 THREADED_TEST(ApiObjectGroupsForSubtypes) { 3593 THREADED_TEST(ApiObjectGroupsForSubtypes) {
3679 LocalContext env; 3594 LocalContext env;
3680 v8::Isolate* iso = env->GetIsolate(); 3595 v8::Isolate* iso = env->GetIsolate();
3681 HandleScope scope(iso); 3596 HandleScope scope(iso);
3682 3597
3683 WeakCallCounter counter(1234); 3598 WeakCallCounter counter(1234);
3684 3599
3685 WeakCallCounterAndPersistent<Object> g1s1(&counter); 3600 WeakCallCounterAndPersistent<Object> g1s1(&counter);
3686 WeakCallCounterAndPersistent<String> g1s2(&counter); 3601 WeakCallCounterAndPersistent<String> g1s2(&counter);
3687 WeakCallCounterAndPersistent<String> g1c1(&counter); 3602 WeakCallCounterAndPersistent<String> g1c1(&counter);
3688 WeakCallCounterAndPersistent<Object> g2s1(&counter); 3603 WeakCallCounterAndPersistent<Object> g2s1(&counter);
3689 WeakCallCounterAndPersistent<String> g2s2(&counter); 3604 WeakCallCounterAndPersistent<String> g2s2(&counter);
3690 WeakCallCounterAndPersistent<String> g2c1(&counter); 3605 WeakCallCounterAndPersistent<String> g2c1(&counter);
3691 3606
3692 { 3607 {
3693 HandleScope scope(iso); 3608 HandleScope scope(iso);
3694 g1s1.handle.Reset(iso, Object::New(iso)); 3609 g1s1.handle.Reset(iso, Object::New(iso));
3695 g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1")); 3610 g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1"));
3696 g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2")); 3611 g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2"));
3697 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); 3612 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
3698 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); 3613 v8::WeakCallbackType::kParameter);
3699 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); 3614 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
3615 v8::WeakCallbackType::kParameter);
3616 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
3617 v8::WeakCallbackType::kParameter);
3700 3618
3701 g2s1.handle.Reset(iso, Object::New(iso)); 3619 g2s1.handle.Reset(iso, Object::New(iso));
3702 g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3")); 3620 g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3"));
3703 g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4")); 3621 g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4"));
3704 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); 3622 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
3705 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); 3623 v8::WeakCallbackType::kParameter);
3706 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); 3624 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
3625 v8::WeakCallbackType::kParameter);
3626 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
3627 v8::WeakCallbackType::kParameter);
3707 } 3628 }
3708 3629
3709 WeakCallCounterAndPersistent<Value> root(&counter); 3630 WeakCallCounterAndPersistent<Value> root(&counter);
3710 root.handle.Reset(iso, g1s1.handle); // make a root. 3631 root.handle.Reset(iso, g1s1.handle); // make a root.
3711 3632
3712 // Connect group 1 and 2, make a cycle. 3633 // Connect group 1 and 2, make a cycle.
3713 { 3634 {
3714 HandleScope scope(iso); 3635 HandleScope scope(iso);
3715 CHECK(Local<Object>::New(iso, g1s1.handle) 3636 CHECK(Local<Object>::New(iso, g1s1.handle)
3716 ->Set(0, Local<Object>::New(iso, g2s1.handle))); 3637 ->Set(0, Local<Object>::New(iso, g2s1.handle)));
(...skipping 13 matching lines...) Expand all
3730 } 3651 }
3731 // Do a single full GC, ensure incremental marking is stopped. 3652 // Do a single full GC, ensure incremental marking is stopped.
3732 v8::internal::Heap* heap = 3653 v8::internal::Heap* heap =
3733 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); 3654 reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
3734 heap->CollectAllGarbage(); 3655 heap->CollectAllGarbage();
3735 3656
3736 // All object should be alive. 3657 // All object should be alive.
3737 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3658 CHECK_EQ(0, counter.NumberOfWeakCalls());
3738 3659
3739 // Weaken the root. 3660 // Weaken the root.
3740 root.handle.SetWeak(&root, &WeakPointerCallback); 3661 root.handle.SetWeak(&root, &WeakPointerCallback,
3662 v8::WeakCallbackType::kParameter);
3741 // But make children strong roots---all the objects (except for children) 3663 // But make children strong roots---all the objects (except for children)
3742 // should be collectable now. 3664 // should be collectable now.
3743 g1c1.handle.ClearWeak(); 3665 g1c1.handle.ClearWeak();
3744 g2c1.handle.ClearWeak(); 3666 g2c1.handle.ClearWeak();
3745 3667
3746 // Groups are deleted, rebuild groups. 3668 // Groups are deleted, rebuild groups.
3747 { 3669 {
3748 UniqueId id1 = MakeUniqueId(g1s1.handle); 3670 UniqueId id1 = MakeUniqueId(g1s1.handle);
3749 UniqueId id2 = MakeUniqueId(g2s2.handle); 3671 UniqueId id2 = MakeUniqueId(g2s2.handle);
3750 iso->SetObjectGroupId(g1s1.handle, id1); 3672 iso->SetObjectGroupId(g1s1.handle, id1);
3751 iso->SetObjectGroupId(g1s2.handle, id1); 3673 iso->SetObjectGroupId(g1s2.handle, id1);
3752 iso->SetReference(g1s1.handle, g1c1.handle); 3674 iso->SetReference(g1s1.handle, g1c1.handle);
3753 iso->SetObjectGroupId(g2s1.handle, id2); 3675 iso->SetObjectGroupId(g2s1.handle, id2);
3754 iso->SetObjectGroupId(g2s2.handle, id2); 3676 iso->SetObjectGroupId(g2s2.handle, id2);
3755 iso->SetReferenceFromGroup(id2, g2c1.handle); 3677 iso->SetReferenceFromGroup(id2, g2c1.handle);
3756 } 3678 }
3757 3679
3758 heap->CollectAllGarbage(); 3680 heap->CollectAllGarbage();
3759 3681
3760 // All objects should be gone. 5 global handles in total. 3682 // All objects should be gone. 5 global handles in total.
3761 CHECK_EQ(5, counter.NumberOfWeakCalls()); 3683 CHECK_EQ(5, counter.NumberOfWeakCalls());
3762 3684
3763 // And now make children weak again and collect them. 3685 // And now make children weak again and collect them.
3764 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback); 3686 g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
3765 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback); 3687 v8::WeakCallbackType::kParameter);
3688 g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
3689 v8::WeakCallbackType::kParameter);
3766 3690
3767 heap->CollectAllGarbage(); 3691 heap->CollectAllGarbage();
3768 CHECK_EQ(7, counter.NumberOfWeakCalls()); 3692 CHECK_EQ(7, counter.NumberOfWeakCalls());
3769 } 3693 }
3770 3694
3771 3695
3772 THREADED_TEST(ApiObjectGroupsCycle) { 3696 THREADED_TEST(ApiObjectGroupsCycle) {
3773 LocalContext env; 3697 LocalContext env;
3774 v8::Isolate* iso = env->GetIsolate(); 3698 v8::Isolate* iso = env->GetIsolate();
3775 HandleScope scope(iso); 3699 HandleScope scope(iso);
3776 3700
3777 WeakCallCounter counter(1234); 3701 WeakCallCounter counter(1234);
3778 3702
3779 WeakCallCounterAndPersistent<Value> g1s1(&counter); 3703 WeakCallCounterAndPersistent<Value> g1s1(&counter);
3780 WeakCallCounterAndPersistent<Value> g1s2(&counter); 3704 WeakCallCounterAndPersistent<Value> g1s2(&counter);
3781 WeakCallCounterAndPersistent<Value> g2s1(&counter); 3705 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3782 WeakCallCounterAndPersistent<Value> g2s2(&counter); 3706 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3783 WeakCallCounterAndPersistent<Value> g3s1(&counter); 3707 WeakCallCounterAndPersistent<Value> g3s1(&counter);
3784 WeakCallCounterAndPersistent<Value> g3s2(&counter); 3708 WeakCallCounterAndPersistent<Value> g3s2(&counter);
3785 WeakCallCounterAndPersistent<Value> g4s1(&counter); 3709 WeakCallCounterAndPersistent<Value> g4s1(&counter);
3786 WeakCallCounterAndPersistent<Value> g4s2(&counter); 3710 WeakCallCounterAndPersistent<Value> g4s2(&counter);
3787 3711
3788 { 3712 {
3789 HandleScope scope(iso); 3713 HandleScope scope(iso);
3790 g1s1.handle.Reset(iso, Object::New(iso)); 3714 g1s1.handle.Reset(iso, Object::New(iso));
3791 g1s2.handle.Reset(iso, Object::New(iso)); 3715 g1s2.handle.Reset(iso, Object::New(iso));
3792 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); 3716 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
3793 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); 3717 v8::WeakCallbackType::kParameter);
3718 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
3719 v8::WeakCallbackType::kParameter);
3794 CHECK(g1s1.handle.IsWeak()); 3720 CHECK(g1s1.handle.IsWeak());
3795 CHECK(g1s2.handle.IsWeak()); 3721 CHECK(g1s2.handle.IsWeak());
3796 3722
3797 g2s1.handle.Reset(iso, Object::New(iso)); 3723 g2s1.handle.Reset(iso, Object::New(iso));
3798 g2s2.handle.Reset(iso, Object::New(iso)); 3724 g2s2.handle.Reset(iso, Object::New(iso));
3799 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); 3725 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
3800 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); 3726 v8::WeakCallbackType::kParameter);
3727 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
3728 v8::WeakCallbackType::kParameter);
3801 CHECK(g2s1.handle.IsWeak()); 3729 CHECK(g2s1.handle.IsWeak());
3802 CHECK(g2s2.handle.IsWeak()); 3730 CHECK(g2s2.handle.IsWeak());
3803 3731
3804 g3s1.handle.Reset(iso, Object::New(iso)); 3732 g3s1.handle.Reset(iso, Object::New(iso));
3805 g3s2.handle.Reset(iso, Object::New(iso)); 3733 g3s2.handle.Reset(iso, Object::New(iso));
3806 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback); 3734 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback,
3807 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback); 3735 v8::WeakCallbackType::kParameter);
3736 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback,
3737 v8::WeakCallbackType::kParameter);
3808 CHECK(g3s1.handle.IsWeak()); 3738 CHECK(g3s1.handle.IsWeak());
3809 CHECK(g3s2.handle.IsWeak()); 3739 CHECK(g3s2.handle.IsWeak());
3810 3740
3811 g4s1.handle.Reset(iso, Object::New(iso)); 3741 g4s1.handle.Reset(iso, Object::New(iso));
3812 g4s2.handle.Reset(iso, Object::New(iso)); 3742 g4s2.handle.Reset(iso, Object::New(iso));
3813 g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback); 3743 g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback,
3814 g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback); 3744 v8::WeakCallbackType::kParameter);
3745 g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback,
3746 v8::WeakCallbackType::kParameter);
3815 CHECK(g4s1.handle.IsWeak()); 3747 CHECK(g4s1.handle.IsWeak());
3816 CHECK(g4s2.handle.IsWeak()); 3748 CHECK(g4s2.handle.IsWeak());
3817 } 3749 }
3818 3750
3819 WeakCallCounterAndPersistent<Value> root(&counter); 3751 WeakCallCounterAndPersistent<Value> root(&counter);
3820 root.handle.Reset(iso, g1s1.handle); // make a root. 3752 root.handle.Reset(iso, g1s1.handle); // make a root.
3821 3753
3822 // Connect groups. We're building the following cycle: 3754 // Connect groups. We're building the following cycle:
3823 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3755 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3824 // groups. 3756 // groups.
(...skipping 17 matching lines...) Expand all
3842 } 3774 }
3843 // Do a single full GC 3775 // Do a single full GC
3844 v8::internal::Heap* heap = 3776 v8::internal::Heap* heap =
3845 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); 3777 reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
3846 heap->CollectAllGarbage(); 3778 heap->CollectAllGarbage();
3847 3779
3848 // All object should be alive. 3780 // All object should be alive.
3849 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3781 CHECK_EQ(0, counter.NumberOfWeakCalls());
3850 3782
3851 // Weaken the root. 3783 // Weaken the root.
3852 root.handle.SetWeak(&root, &WeakPointerCallback); 3784 root.handle.SetWeak(&root, &WeakPointerCallback,
3785 v8::WeakCallbackType::kParameter);
3853 3786
3854 // Groups are deleted, rebuild groups. 3787 // Groups are deleted, rebuild groups.
3855 { 3788 {
3856 UniqueId id1 = MakeUniqueId(g1s1.handle); 3789 UniqueId id1 = MakeUniqueId(g1s1.handle);
3857 UniqueId id2 = MakeUniqueId(g2s1.handle); 3790 UniqueId id2 = MakeUniqueId(g2s1.handle);
3858 UniqueId id3 = MakeUniqueId(g3s1.handle); 3791 UniqueId id3 = MakeUniqueId(g3s1.handle);
3859 UniqueId id4 = MakeUniqueId(g4s1.handle); 3792 UniqueId id4 = MakeUniqueId(g4s1.handle);
3860 iso->SetObjectGroupId(g1s1.handle, id1); 3793 iso->SetObjectGroupId(g1s1.handle, id1);
3861 iso->SetObjectGroupId(g1s2.handle, id1); 3794 iso->SetObjectGroupId(g1s2.handle, id1);
3862 iso->SetReferenceFromGroup(id1, g2s1.handle); 3795 iso->SetReferenceFromGroup(id1, g2s1.handle);
3863 iso->SetObjectGroupId(g2s1.handle, id2); 3796 iso->SetObjectGroupId(g2s1.handle, id2);
3864 iso->SetObjectGroupId(g2s2.handle, id2); 3797 iso->SetObjectGroupId(g2s2.handle, id2);
3865 iso->SetReferenceFromGroup(id2, g3s1.handle); 3798 iso->SetReferenceFromGroup(id2, g3s1.handle);
3866 iso->SetObjectGroupId(g3s1.handle, id3); 3799 iso->SetObjectGroupId(g3s1.handle, id3);
3867 iso->SetObjectGroupId(g3s2.handle, id3); 3800 iso->SetObjectGroupId(g3s2.handle, id3);
3868 iso->SetReferenceFromGroup(id3, g4s1.handle); 3801 iso->SetReferenceFromGroup(id3, g4s1.handle);
3869 iso->SetObjectGroupId(g4s1.handle, id4); 3802 iso->SetObjectGroupId(g4s1.handle, id4);
3870 iso->SetObjectGroupId(g4s2.handle, id4); 3803 iso->SetObjectGroupId(g4s2.handle, id4);
3871 iso->SetReferenceFromGroup(id4, g1s1.handle); 3804 iso->SetReferenceFromGroup(id4, g1s1.handle);
3872 } 3805 }
3873 3806
3874 heap->CollectAllGarbage(); 3807 heap->CollectAllGarbage();
3875 3808
3876 // All objects should be gone. 9 global handles in total. 3809 // All objects should be gone. 9 global handles in total.
3877 CHECK_EQ(9, counter.NumberOfWeakCalls()); 3810 CHECK_EQ(9, counter.NumberOfWeakCalls());
3878 } 3811 }
3879 3812
3880 3813
3881 THREADED_TEST(WeakRootsSurviveTwoRoundsOfGC) {
3882 LocalContext env;
3883 v8::Isolate* iso = env->GetIsolate();
3884 HandleScope scope(iso);
3885
3886 WeakCallCounter counter(1234);
3887
3888 WeakCallCounterAndPersistent<Value> weak_obj(&counter);
3889
3890 // Create a weak object that references a internalized string.
3891 {
3892 HandleScope scope(iso);
3893 weak_obj.handle.Reset(iso, Object::New(iso));
3894 weak_obj.handle.SetWeak(&weak_obj, &WeakPointerCallback);
3895 CHECK(weak_obj.handle.IsWeak());
3896 Local<Object>::New(iso, weak_obj.handle.As<Object>())
3897 ->Set(v8_str("x"), String::NewFromUtf8(iso, "magic cookie",
3898 String::kInternalizedString));
3899 }
3900 // Do a single full GC
3901 i::Isolate* i_iso = reinterpret_cast<v8::internal::Isolate*>(iso);
3902 i::Heap* heap = i_iso->heap();
3903 heap->CollectAllGarbage();
3904
3905 // We should have received the weak callback.
3906 CHECK_EQ(1, counter.NumberOfWeakCalls());
3907
3908 // Check that the string is still alive.
3909 {
3910 HandleScope scope(iso);
3911 i::MaybeHandle<i::String> magic_string =
3912 i::StringTable::LookupStringIfExists(
3913 i_iso,
3914 v8::Utils::OpenHandle(*String::NewFromUtf8(iso, "magic cookie")));
3915 magic_string.Check();
3916 }
3917 }
3918
3919
3920 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures 3814 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures
3921 // on the buildbots, so was made non-threaded for the time being. 3815 // on the buildbots, so was made non-threaded for the time being.
3922 TEST(ApiObjectGroupsCycleForScavenger) { 3816 TEST(ApiObjectGroupsCycleForScavenger) {
3923 i::FLAG_stress_compaction = false; 3817 i::FLAG_stress_compaction = false;
3924 i::FLAG_gc_global = false; 3818 i::FLAG_gc_global = false;
3925 LocalContext env; 3819 LocalContext env;
3926 v8::Isolate* iso = env->GetIsolate(); 3820 v8::Isolate* iso = env->GetIsolate();
3927 HandleScope scope(iso); 3821 HandleScope scope(iso);
3928 3822
3929 WeakCallCounter counter(1234); 3823 WeakCallCounter counter(1234);
3930 3824
3931 WeakCallCounterAndPersistent<Value> g1s1(&counter); 3825 WeakCallCounterAndPersistent<Value> g1s1(&counter);
3932 WeakCallCounterAndPersistent<Value> g1s2(&counter); 3826 WeakCallCounterAndPersistent<Value> g1s2(&counter);
3933 WeakCallCounterAndPersistent<Value> g2s1(&counter); 3827 WeakCallCounterAndPersistent<Value> g2s1(&counter);
3934 WeakCallCounterAndPersistent<Value> g2s2(&counter); 3828 WeakCallCounterAndPersistent<Value> g2s2(&counter);
3935 WeakCallCounterAndPersistent<Value> g3s1(&counter); 3829 WeakCallCounterAndPersistent<Value> g3s1(&counter);
3936 WeakCallCounterAndPersistent<Value> g3s2(&counter); 3830 WeakCallCounterAndPersistent<Value> g3s2(&counter);
3937 3831
3938 { 3832 {
3939 HandleScope scope(iso); 3833 HandleScope scope(iso);
3940 g1s1.handle.Reset(iso, Object::New(iso)); 3834 g1s1.handle.Reset(iso, Object::New(iso));
3941 g1s2.handle.Reset(iso, Object::New(iso)); 3835 g1s2.handle.Reset(iso, Object::New(iso));
3942 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback); 3836 g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
3943 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback); 3837 v8::WeakCallbackType::kParameter);
3838 g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
3839 v8::WeakCallbackType::kParameter);
3944 3840
3945 g2s1.handle.Reset(iso, Object::New(iso)); 3841 g2s1.handle.Reset(iso, Object::New(iso));
3946 g2s2.handle.Reset(iso, Object::New(iso)); 3842 g2s2.handle.Reset(iso, Object::New(iso));
3947 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback); 3843 g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
3948 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback); 3844 v8::WeakCallbackType::kParameter);
3845 g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
3846 v8::WeakCallbackType::kParameter);
3949 3847
3950 g3s1.handle.Reset(iso, Object::New(iso)); 3848 g3s1.handle.Reset(iso, Object::New(iso));
3951 g3s2.handle.Reset(iso, Object::New(iso)); 3849 g3s2.handle.Reset(iso, Object::New(iso));
3952 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback); 3850 g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback,
3953 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback); 3851 v8::WeakCallbackType::kParameter);
3852 g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback,
3853 v8::WeakCallbackType::kParameter);
3954 } 3854 }
3955 3855
3956 // Make a root. 3856 // Make a root.
3957 WeakCallCounterAndPersistent<Value> root(&counter); 3857 WeakCallCounterAndPersistent<Value> root(&counter);
3958 root.handle.Reset(iso, g1s1.handle); 3858 root.handle.Reset(iso, g1s1.handle);
3959 root.handle.MarkPartiallyDependent(); 3859 root.handle.MarkPartiallyDependent();
3960 3860
3961 // Connect groups. We're building the following cycle: 3861 // Connect groups. We're building the following cycle:
3962 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other 3862 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
3963 // groups. 3863 // groups.
(...skipping 20 matching lines...) Expand all
3984 } 3884 }
3985 3885
3986 v8::internal::Heap* heap = 3886 v8::internal::Heap* heap =
3987 reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); 3887 reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
3988 heap->CollectAllGarbage(); 3888 heap->CollectAllGarbage();
3989 3889
3990 // All objects should be alive. 3890 // All objects should be alive.
3991 CHECK_EQ(0, counter.NumberOfWeakCalls()); 3891 CHECK_EQ(0, counter.NumberOfWeakCalls());
3992 3892
3993 // Weaken the root. 3893 // Weaken the root.
3994 root.handle.SetWeak(&root, &WeakPointerCallback); 3894 root.handle.SetWeak(&root, &WeakPointerCallback,
3895 v8::WeakCallbackType::kParameter);
3995 root.handle.MarkPartiallyDependent(); 3896 root.handle.MarkPartiallyDependent();
3996 3897
3997 // Groups are deleted, rebuild groups. 3898 // Groups are deleted, rebuild groups.
3998 { 3899 {
3999 HandleScope handle_scope(iso); 3900 HandleScope handle_scope(iso);
4000 g1s1.handle.MarkPartiallyDependent(); 3901 g1s1.handle.MarkPartiallyDependent();
4001 g1s2.handle.MarkPartiallyDependent(); 3902 g1s2.handle.MarkPartiallyDependent();
4002 g2s1.handle.MarkPartiallyDependent(); 3903 g2s1.handle.MarkPartiallyDependent();
4003 g2s2.handle.MarkPartiallyDependent(); 3904 g2s2.handle.MarkPartiallyDependent();
4004 g3s1.handle.MarkPartiallyDependent(); 3905 g3s1.handle.MarkPartiallyDependent();
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 } 4180 }
4280 CcTest::heap()->CollectAllGarbage(); 4181 CcTest::heap()->CollectAllGarbage();
4281 { 4182 {
4282 HandleScope scope(isolate); 4183 HandleScope scope(isolate);
4283 CHECK(value->Equals(weak_map->Get(local1))); 4184 CHECK(value->Equals(weak_map->Get(local1)));
4284 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o1.handle)))); 4185 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o1.handle))));
4285 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o2.handle)))); 4186 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o2.handle))));
4286 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, s1.handle)))); 4187 CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, s1.handle))));
4287 } 4188 }
4288 4189
4289 o1.handle.SetWeak(&o1, &WeakPointerCallback); 4190 o1.handle.SetWeak(&o1, &WeakPointerCallback,
4290 o2.handle.SetWeak(&o2, &WeakPointerCallback); 4191 v8::WeakCallbackType::kParameter);
4291 s1.handle.SetWeak(&s1, &WeakPointerCallback); 4192 o2.handle.SetWeak(&o2, &WeakPointerCallback,
4193 v8::WeakCallbackType::kParameter);
4194 s1.handle.SetWeak(&s1, &WeakPointerCallback,
4195 v8::WeakCallbackType::kParameter);
4292 4196
4293 CcTest::heap()->CollectAllGarbage(); 4197 CcTest::heap()->CollectAllGarbage();
4294 CHECK_EQ(3, counter.NumberOfWeakCalls()); 4198 CHECK_EQ(3, counter.NumberOfWeakCalls());
4295 4199
4296 CHECK(o1.handle.IsEmpty()); 4200 CHECK(o1.handle.IsEmpty());
4297 CHECK(o2.handle.IsEmpty()); 4201 CHECK(o2.handle.IsEmpty());
4298 CHECK(s1.handle.IsEmpty()); 4202 CHECK(s1.handle.IsEmpty());
4299 4203
4300 CHECK(value->Equals(weak_map->Get(local1))); 4204 CHECK(value->Equals(weak_map->Get(local1)));
4301 CHECK(weak_map->Delete(local1)); 4205 CHECK(weak_map->Delete(local1));
(...skipping 2372 matching lines...) Expand 10 before | Expand all | Expand 10 after
6674 } 6578 }
6675 6579
6676 6580
6677 THREADED_TEST(InternalFieldCallback) { 6581 THREADED_TEST(InternalFieldCallback) {
6678 InternalFieldCallback(false); 6582 InternalFieldCallback(false);
6679 InternalFieldCallback(true); 6583 InternalFieldCallback(true);
6680 } 6584 }
6681 6585
6682 6586
6683 static void ResetUseValueAndSetFlag( 6587 static void ResetUseValueAndSetFlag(
6684 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { 6588 const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
6685 // Blink will reset the handle, and then use the other handle, so they 6589 // Blink will reset the handle, and then use the other handle, so they
6686 // can't use the same backing slot. 6590 // can't use the same backing slot.
6687 data.GetParameter()->handle.Reset(); 6591 data.GetParameter()->handle.Reset();
6688 data.GetValue()->IsBoolean(); // Make sure the handle still works.
6689 data.GetParameter()->flag = true; 6592 data.GetParameter()->flag = true;
6690 } 6593 }
6691 6594
6692 6595
6693 static void ResetWeakHandle(bool global_gc) { 6596 static void ResetWeakHandle(bool global_gc) {
6694 v8::Isolate* iso = CcTest::isolate(); 6597 v8::Isolate* iso = CcTest::isolate();
6695 v8::HandleScope scope(iso); 6598 v8::HandleScope scope(iso);
6696 v8::Handle<Context> context = Context::New(iso); 6599 v8::Handle<Context> context = Context::New(iso);
6697 Context::Scope context_scope(context); 6600 Context::Scope context_scope(context);
6698 6601
6699 FlagAndPersistent object_a, object_b; 6602 FlagAndPersistent object_a, object_b;
6700 6603
6701 { 6604 {
6702 v8::HandleScope handle_scope(iso); 6605 v8::HandleScope handle_scope(iso);
6703 Local<Object> a(v8::Object::New(iso)); 6606 Local<Object> a(v8::Object::New(iso));
6704 Local<Object> b(v8::Object::New(iso)); 6607 Local<Object> b(v8::Object::New(iso));
6705 object_a.handle.Reset(iso, a); 6608 object_a.handle.Reset(iso, a);
6706 object_b.handle.Reset(iso, b); 6609 object_b.handle.Reset(iso, b);
6707 if (global_gc) { 6610 if (global_gc) {
6708 CcTest::heap()->CollectAllGarbage( 6611 CcTest::heap()->CollectAllGarbage(
6709 TestHeap::Heap::kAbortIncrementalMarkingMask); 6612 TestHeap::Heap::kAbortIncrementalMarkingMask);
6710 } else { 6613 } else {
6711 CcTest::heap()->CollectGarbage(i::NEW_SPACE); 6614 CcTest::heap()->CollectGarbage(i::NEW_SPACE);
6712 } 6615 }
6713 } 6616 }
6714 6617
6715 object_a.flag = false; 6618 object_a.flag = false;
6716 object_b.flag = false; 6619 object_b.flag = false;
6717 object_a.handle.SetWeak(&object_a, &ResetUseValueAndSetFlag); 6620 object_a.handle.SetWeak(&object_a, &ResetUseValueAndSetFlag,
6718 object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag); 6621 v8::WeakCallbackType::kParameter);
6622 object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag,
6623 v8::WeakCallbackType::kParameter);
6719 if (!global_gc) { 6624 if (!global_gc) {
6720 object_a.handle.MarkIndependent(); 6625 object_a.handle.MarkIndependent();
6721 object_b.handle.MarkIndependent(); 6626 object_b.handle.MarkIndependent();
6722 CHECK(object_b.handle.IsIndependent()); 6627 CHECK(object_b.handle.IsIndependent());
6723 } 6628 }
6724 if (global_gc) { 6629 if (global_gc) {
6725 CcTest::heap()->CollectAllGarbage( 6630 CcTest::heap()->CollectAllGarbage(
6726 TestHeap::Heap::kAbortIncrementalMarkingMask); 6631 TestHeap::Heap::kAbortIncrementalMarkingMask);
6727 } else { 6632 } else {
6728 CcTest::heap()->CollectGarbage(i::NEW_SPACE); 6633 CcTest::heap()->CollectGarbage(i::NEW_SPACE);
6729 } 6634 }
6730 CHECK(object_a.flag); 6635 CHECK(object_a.flag);
6731 CHECK(object_b.flag); 6636 CHECK(object_b.flag);
6732 } 6637 }
6733 6638
6734 6639
6735 THREADED_TEST(ResetWeakHandle) { 6640 THREADED_TEST(ResetWeakHandle) {
6736 ResetWeakHandle(false); 6641 ResetWeakHandle(false);
6737 ResetWeakHandle(true); 6642 ResetWeakHandle(true);
6738 } 6643 }
6739 6644
6740 6645
6741 static void InvokeScavenge() { CcTest::heap()->CollectGarbage(i::NEW_SPACE); } 6646 static void InvokeScavenge() { CcTest::heap()->CollectGarbage(i::NEW_SPACE); }
6742 6647
6743 6648
6744 static void InvokeMarkSweep() { CcTest::heap()->CollectAllGarbage(); } 6649 static void InvokeMarkSweep() { CcTest::heap()->CollectAllGarbage(); }
6745 6650
6746 6651
6747 static void ForceScavenge( 6652 static void ForceScavenge2(
6748 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { 6653 const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
6749 data.GetParameter()->handle.Reset();
6750 data.GetParameter()->flag = true; 6654 data.GetParameter()->flag = true;
6751 InvokeScavenge(); 6655 InvokeScavenge();
6752 } 6656 }
6753 6657
6658 static void ForceScavenge1(
6659 const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
6660 data.GetParameter()->handle.Reset();
6661 data.SetSecondPassCallback(ForceScavenge2);
6662 }
6754 6663
6755 static void ForceMarkSweep( 6664
6756 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) { 6665 static void ForceMarkSweep2(
6757 data.GetParameter()->handle.Reset(); 6666 const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
6758 data.GetParameter()->flag = true; 6667 data.GetParameter()->flag = true;
6759 InvokeMarkSweep(); 6668 InvokeMarkSweep();
6760 } 6669 }
6761 6670
6671 static void ForceMarkSweep1(
6672 const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
6673 data.GetParameter()->handle.Reset();
6674 data.SetSecondPassCallback(ForceMarkSweep2);
6675 }
6676
6762 6677
6763 THREADED_TEST(GCFromWeakCallbacks) { 6678 THREADED_TEST(GCFromWeakCallbacks) {
6764 v8::Isolate* isolate = CcTest::isolate(); 6679 v8::Isolate* isolate = CcTest::isolate();
6765 v8::HandleScope scope(isolate); 6680 v8::HandleScope scope(isolate);
6766 v8::Handle<Context> context = Context::New(isolate); 6681 v8::Handle<Context> context = Context::New(isolate);
6767 Context::Scope context_scope(context); 6682 Context::Scope context_scope(context);
6768 6683
6769 static const int kNumberOfGCTypes = 2; 6684 static const int kNumberOfGCTypes = 2;
6770 typedef v8::WeakCallbackData<v8::Object, FlagAndPersistent>::Callback 6685 typedef v8::WeakCallbackInfo<FlagAndPersistent>::Callback Callback;
6771 Callback; 6686 Callback gc_forcing_callback[kNumberOfGCTypes] = {&ForceScavenge1,
6772 Callback gc_forcing_callback[kNumberOfGCTypes] = 6687 &ForceMarkSweep1};
6773 {&ForceScavenge, &ForceMarkSweep};
6774 6688
6775 typedef void (*GCInvoker)(); 6689 typedef void (*GCInvoker)();
6776 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; 6690 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep};
6777 6691
6778 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { 6692 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) {
6779 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { 6693 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) {
6780 FlagAndPersistent object; 6694 FlagAndPersistent object;
6781 { 6695 {
6782 v8::HandleScope handle_scope(isolate); 6696 v8::HandleScope handle_scope(isolate);
6783 object.handle.Reset(isolate, v8::Object::New(isolate)); 6697 object.handle.Reset(isolate, v8::Object::New(isolate));
6784 } 6698 }
6785 object.flag = false; 6699 object.flag = false;
6786 object.handle.SetWeak(&object, gc_forcing_callback[inner_gc]); 6700 object.handle.SetWeak(&object, gc_forcing_callback[inner_gc],
6701 v8::WeakCallbackType::kParameter);
6787 object.handle.MarkIndependent(); 6702 object.handle.MarkIndependent();
6788 invoke_gc[outer_gc](); 6703 invoke_gc[outer_gc]();
6789 CHECK(object.flag); 6704 CHECK(object.flag);
6790 } 6705 }
6791 } 6706 }
6792 } 6707 }
6793 6708
6794 6709
6795 static void RevivingCallback(
6796 const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
6797 data.GetParameter()->handle.ClearWeak();
6798 data.GetParameter()->flag = true;
6799 }
6800
6801
6802 THREADED_TEST(IndependentHandleRevival) {
6803 v8::Isolate* isolate = CcTest::isolate();
6804 v8::HandleScope scope(isolate);
6805 v8::Handle<Context> context = Context::New(isolate);
6806 Context::Scope context_scope(context);
6807
6808 FlagAndPersistent object;
6809 {
6810 v8::HandleScope handle_scope(isolate);
6811 v8::Local<v8::Object> o = v8::Object::New(isolate);
6812 object.handle.Reset(isolate, o);
6813 o->Set(v8_str("x"), v8::Integer::New(isolate, 1));
6814 v8::Local<String> y_str = v8_str("y");
6815 o->Set(y_str, y_str);
6816 }
6817 object.flag = false;
6818 object.handle.SetWeak(&object, &RevivingCallback);
6819 object.handle.MarkIndependent();
6820 CcTest::heap()->CollectGarbage(i::NEW_SPACE);
6821 CHECK(object.flag);
6822 CcTest::heap()->CollectAllGarbage();
6823 {
6824 v8::HandleScope handle_scope(isolate);
6825 v8::Local<v8::Object> o =
6826 v8::Local<v8::Object>::New(isolate, object.handle);
6827 v8::Local<String> y_str = v8_str("y");
6828 CHECK(v8::Integer::New(isolate, 1)->Equals(o->Get(v8_str("x"))));
6829 CHECK(o->Get(y_str)->Equals(y_str));
6830 }
6831 }
6832
6833
6834 v8::Handle<Function> args_fun; 6710 v8::Handle<Function> args_fun;
6835 6711
6836 6712
6837 static void ArgumentsTestCallback( 6713 static void ArgumentsTestCallback(
6838 const v8::FunctionCallbackInfo<v8::Value>& args) { 6714 const v8::FunctionCallbackInfo<v8::Value>& args) {
6839 ApiTestFuzzer::Fuzz(); 6715 ApiTestFuzzer::Fuzz();
6840 v8::Isolate* isolate = args.GetIsolate(); 6716 v8::Isolate* isolate = args.GetIsolate();
6841 CHECK(args_fun->Equals(args.Callee())); 6717 CHECK(args_fun->Equals(args.Callee()));
6842 CHECK_EQ(3, args.Length()); 6718 CHECK_EQ(3, args.Length());
6843 CHECK(v8::Integer::New(isolate, 1)->Equals(args[0])); 6719 CHECK(v8::Integer::New(isolate, 1)->Equals(args[0]));
(...skipping 4948 matching lines...) Expand 10 before | Expand all | Expand 10 after
11792 CopyableObject handle3(handle2); 11668 CopyableObject handle3(handle2);
11793 CHECK(handle1 == handle3); 11669 CHECK(handle1 == handle3);
11794 CHECK_EQ(initial_handles + 3, globals->global_handles_count()); 11670 CHECK_EQ(initial_handles + 3, globals->global_handles_count());
11795 } 11671 }
11796 // Verify autodispose 11672 // Verify autodispose
11797 CHECK_EQ(initial_handles, globals->global_handles_count()); 11673 CHECK_EQ(initial_handles, globals->global_handles_count());
11798 } 11674 }
11799 11675
11800 11676
11801 static void WeakApiCallback( 11677 static void WeakApiCallback(
11802 const v8::WeakCallbackData<v8::Object, Persistent<v8::Object> >& data) { 11678 const v8::WeakCallbackInfo<Persistent<v8::Object>>& data) {
11803 Local<Value> value = data.GetValue()->Get(v8_str("key"));
11804 CHECK_EQ(231, static_cast<int32_t>(Local<v8::Integer>::Cast(value)->Value()));
11805 data.GetParameter()->Reset(); 11679 data.GetParameter()->Reset();
11806 delete data.GetParameter(); 11680 delete data.GetParameter();
11807 } 11681 }
11808 11682
11809 11683
11810 TEST(WeakCallbackApi) { 11684 TEST(WeakCallbackApi) {
11811 LocalContext context; 11685 LocalContext context;
11812 v8::Isolate* isolate = context->GetIsolate(); 11686 v8::Isolate* isolate = context->GetIsolate();
11813 i::GlobalHandles* globals = 11687 i::GlobalHandles* globals =
11814 reinterpret_cast<i::Isolate*>(isolate)->global_handles(); 11688 reinterpret_cast<i::Isolate*>(isolate)->global_handles();
11815 int initial_handles = globals->global_handles_count(); 11689 int initial_handles = globals->global_handles_count();
11816 { 11690 {
11817 v8::HandleScope scope(isolate); 11691 v8::HandleScope scope(isolate);
11818 v8::Local<v8::Object> obj = v8::Object::New(isolate); 11692 v8::Local<v8::Object> obj = v8::Object::New(isolate);
11819 obj->Set(v8_str("key"), v8::Integer::New(isolate, 231)); 11693 obj->Set(v8_str("key"), v8::Integer::New(isolate, 231));
11820 v8::Persistent<v8::Object>* handle = 11694 v8::Persistent<v8::Object>* handle =
11821 new v8::Persistent<v8::Object>(isolate, obj); 11695 new v8::Persistent<v8::Object>(isolate, obj);
11822 handle->SetWeak<v8::Object, v8::Persistent<v8::Object> >(handle, 11696 handle->SetWeak<v8::Persistent<v8::Object>>(
11823 WeakApiCallback); 11697 handle, WeakApiCallback, v8::WeakCallbackType::kParameter);
11824 } 11698 }
11825 reinterpret_cast<i::Isolate*>(isolate)->heap()->CollectAllGarbage( 11699 reinterpret_cast<i::Isolate*>(isolate)->heap()->CollectAllGarbage(
11826 i::Heap::kAbortIncrementalMarkingMask); 11700 i::Heap::kAbortIncrementalMarkingMask);
11827 // Verify disposed. 11701 // Verify disposed.
11828 CHECK_EQ(initial_handles, globals->global_handles_count()); 11702 CHECK_EQ(initial_handles, globals->global_handles_count());
11829 } 11703 }
11830 11704
11831 11705
11832 v8::Persistent<v8::Object> some_object; 11706 v8::Persistent<v8::Object> some_object;
11833 v8::Persistent<v8::Object> bad_handle; 11707 v8::Persistent<v8::Object> bad_handle;
11834 11708
11835 void NewPersistentHandleCallback( 11709
11836 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { 11710 void NewPersistentHandleCallback2(
11711 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11837 v8::HandleScope scope(data.GetIsolate()); 11712 v8::HandleScope scope(data.GetIsolate());
11838 bad_handle.Reset(data.GetIsolate(), some_object); 11713 bad_handle.Reset(data.GetIsolate(), some_object);
11839 data.GetParameter()->Reset();
11840 } 11714 }
11841 11715
11842 11716
11717 void NewPersistentHandleCallback1(
11718 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11719 data.GetParameter()->Reset();
11720 data.SetSecondPassCallback(NewPersistentHandleCallback2);
11721 }
11722
11723
11843 THREADED_TEST(NewPersistentHandleFromWeakCallback) { 11724 THREADED_TEST(NewPersistentHandleFromWeakCallback) {
11844 LocalContext context; 11725 LocalContext context;
11845 v8::Isolate* isolate = context->GetIsolate(); 11726 v8::Isolate* isolate = context->GetIsolate();
11846 11727
11847 v8::Persistent<v8::Object> handle1, handle2; 11728 v8::Persistent<v8::Object> handle1, handle2;
11848 { 11729 {
11849 v8::HandleScope scope(isolate); 11730 v8::HandleScope scope(isolate);
11850 some_object.Reset(isolate, v8::Object::New(isolate)); 11731 some_object.Reset(isolate, v8::Object::New(isolate));
11851 handle1.Reset(isolate, v8::Object::New(isolate)); 11732 handle1.Reset(isolate, v8::Object::New(isolate));
11852 handle2.Reset(isolate, v8::Object::New(isolate)); 11733 handle2.Reset(isolate, v8::Object::New(isolate));
11853 } 11734 }
11854 // Note: order is implementation dependent alas: currently 11735 // Note: order is implementation dependent alas: currently
11855 // global handle nodes are processed by PostGarbageCollectionProcessing 11736 // global handle nodes are processed by PostGarbageCollectionProcessing
11856 // in reverse allocation order, so if second allocated handle is deleted, 11737 // in reverse allocation order, so if second allocated handle is deleted,
11857 // weak callback of the first handle would be able to 'reallocate' it. 11738 // weak callback of the first handle would be able to 'reallocate' it.
11858 handle1.SetWeak(&handle1, NewPersistentHandleCallback); 11739 handle1.SetWeak(&handle1, NewPersistentHandleCallback1,
11740 v8::WeakCallbackType::kParameter);
11859 handle2.Reset(); 11741 handle2.Reset();
11860 CcTest::heap()->CollectAllGarbage(); 11742 CcTest::heap()->CollectAllGarbage();
11861 } 11743 }
11862 11744
11863 11745
11864 v8::Persistent<v8::Object> to_be_disposed; 11746 v8::Persistent<v8::Object> to_be_disposed;
11865 11747
11866 void DisposeAndForceGcCallback( 11748
11867 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { 11749 void DisposeAndForceGcCallback2(
11750 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11868 to_be_disposed.Reset(); 11751 to_be_disposed.Reset();
11869 CcTest::heap()->CollectAllGarbage(); 11752 CcTest::heap()->CollectAllGarbage();
11870 data.GetParameter()->Reset();
11871 } 11753 }
11872 11754
11873 11755
11756 void DisposeAndForceGcCallback1(
11757 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11758 data.GetParameter()->Reset();
11759 data.SetSecondPassCallback(DisposeAndForceGcCallback2);
11760 }
11761
11762
11874 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { 11763 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
11875 LocalContext context; 11764 LocalContext context;
11876 v8::Isolate* isolate = context->GetIsolate(); 11765 v8::Isolate* isolate = context->GetIsolate();
11877 11766
11878 v8::Persistent<v8::Object> handle1, handle2; 11767 v8::Persistent<v8::Object> handle1, handle2;
11879 { 11768 {
11880 v8::HandleScope scope(isolate); 11769 v8::HandleScope scope(isolate);
11881 handle1.Reset(isolate, v8::Object::New(isolate)); 11770 handle1.Reset(isolate, v8::Object::New(isolate));
11882 handle2.Reset(isolate, v8::Object::New(isolate)); 11771 handle2.Reset(isolate, v8::Object::New(isolate));
11883 } 11772 }
11884 handle1.SetWeak(&handle1, DisposeAndForceGcCallback); 11773 handle1.SetWeak(&handle1, DisposeAndForceGcCallback1,
11774 v8::WeakCallbackType::kParameter);
11885 to_be_disposed.Reset(isolate, handle2); 11775 to_be_disposed.Reset(isolate, handle2);
11886 CcTest::heap()->CollectAllGarbage(); 11776 CcTest::heap()->CollectAllGarbage();
11887 } 11777 }
11888 11778
11889 void DisposingCallback( 11779 void DisposingCallback(
11890 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { 11780 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11891 data.GetParameter()->Reset(); 11781 data.GetParameter()->Reset();
11892 } 11782 }
11893 11783
11894 void HandleCreatingCallback( 11784 void HandleCreatingCallback2(
11895 const v8::WeakCallbackData<v8::Object, v8::Persistent<v8::Object> >& data) { 11785 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11896 v8::HandleScope scope(data.GetIsolate()); 11786 v8::HandleScope scope(data.GetIsolate());
11897 v8::Persistent<v8::Object>(data.GetIsolate(), 11787 v8::Global<v8::Object>(data.GetIsolate(), v8::Object::New(data.GetIsolate()));
11898 v8::Object::New(data.GetIsolate()));
11899 data.GetParameter()->Reset();
11900 } 11788 }
11901 11789
11902 11790
11791 void HandleCreatingCallback1(
11792 const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
11793 data.GetParameter()->Reset();
11794 data.SetSecondPassCallback(HandleCreatingCallback2);
11795 }
11796
11797
11903 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { 11798 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
11904 LocalContext context; 11799 LocalContext context;
11905 v8::Isolate* isolate = context->GetIsolate(); 11800 v8::Isolate* isolate = context->GetIsolate();
11906 11801
11907 v8::Persistent<v8::Object> handle1, handle2, handle3; 11802 v8::Persistent<v8::Object> handle1, handle2, handle3;
11908 { 11803 {
11909 v8::HandleScope scope(isolate); 11804 v8::HandleScope scope(isolate);
11910 handle3.Reset(isolate, v8::Object::New(isolate)); 11805 handle3.Reset(isolate, v8::Object::New(isolate));
11911 handle2.Reset(isolate, v8::Object::New(isolate)); 11806 handle2.Reset(isolate, v8::Object::New(isolate));
11912 handle1.Reset(isolate, v8::Object::New(isolate)); 11807 handle1.Reset(isolate, v8::Object::New(isolate));
11913 } 11808 }
11914 handle2.SetWeak(&handle2, DisposingCallback); 11809 handle2.SetWeak(&handle2, DisposingCallback,
11915 handle3.SetWeak(&handle3, HandleCreatingCallback); 11810 v8::WeakCallbackType::kParameter);
11811 handle3.SetWeak(&handle3, HandleCreatingCallback1,
11812 v8::WeakCallbackType::kParameter);
11916 CcTest::heap()->CollectAllGarbage(); 11813 CcTest::heap()->CollectAllGarbage();
11917 } 11814 }
11918 11815
11919 11816
11920 THREADED_TEST(CheckForCrossContextObjectLiterals) { 11817 THREADED_TEST(CheckForCrossContextObjectLiterals) {
11921 v8::V8::Initialize(); 11818 v8::V8::Initialize();
11922 11819
11923 const int nof = 2; 11820 const int nof = 2;
11924 const char* sources[nof] = { 11821 const char* sources[nof] = {
11925 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", 11822 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }",
(...skipping 9153 matching lines...) Expand 10 before | Expand all | Expand 10 after
21079 20976
21080 { 20977 {
21081 v8::HandleScope handle_scope(isolate); 20978 v8::HandleScope handle_scope(isolate);
21082 20979
21083 // Should work 20980 // Should work
21084 v8::Local<v8::Object> obj = v8::Object::New(isolate); 20981 v8::Local<v8::Object> obj = v8::Object::New(isolate);
21085 20982
21086 USE(obj); 20983 USE(obj);
21087 } 20984 }
21088 } 20985 }
OLDNEW
« no previous file with comments | « src/d8.cc ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698