| 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 3196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |