| Index: runtime/vm/dart_api_impl_test.cc
|
| diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
|
| index 2ef04569b9fc6889f030f795ff2ee916a604b5ef..d65c7a89e21f75922b1cccbdb3e23a5dc8c6cdcd 100644
|
| --- a/runtime/vm/dart_api_impl_test.cc
|
| +++ b/runtime/vm/dart_api_impl_test.cc
|
| @@ -764,6 +764,108 @@ UNIT_TEST_CASE(NewPersistentHandle_FromPersistentHandle) {
|
| }
|
|
|
|
|
| +TEST_CASE(WeakPersistentHandle) {
|
| + Dart_Handle weak_new_ref = Dart_Null();
|
| + EXPECT(Dart_IsNull(weak_new_ref));
|
| +
|
| + Dart_Handle weak_old_ref = Dart_Null();
|
| + EXPECT(Dart_IsNull(weak_old_ref));
|
| +
|
| + bool is_same;
|
| +
|
| + {
|
| + Dart_EnterScope();
|
| +
|
| + // create an object in new space
|
| + Dart_Handle new_ref = Dart_NewString("new string");
|
| + EXPECT_VALID(new_ref);
|
| +
|
| + // create an object in old space
|
| + Dart_Handle old_ref;
|
| + {
|
| + DARTSCOPE(Isolate::Current());
|
| + const String& str =
|
| + String::Handle(String::New("old string", Heap::kOld));
|
| + old_ref = Api::NewLocalHandle(str);
|
| + EXPECT_VALID(old_ref);
|
| + }
|
| +
|
| + // create a weak ref to the new space object
|
| + weak_new_ref = Dart_NewWeakPersistentHandle(new_ref, NULL, NULL);
|
| + EXPECT_VALID(weak_new_ref);
|
| + EXPECT(!Dart_IsNull(weak_new_ref));
|
| +
|
| + // create a weak ref to the old space object
|
| + weak_old_ref = Dart_NewWeakPersistentHandle(old_ref, NULL, NULL);
|
| + EXPECT_VALID(weak_old_ref);
|
| + EXPECT(!Dart_IsNull(weak_old_ref));
|
| +
|
| + // garbage collect new space
|
| + Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
|
| +
|
| + // nothing should be invalidated or cleared
|
| + EXPECT_VALID(new_ref);
|
| + EXPECT(!Dart_IsNull(new_ref));
|
| + EXPECT_VALID(old_ref);
|
| + EXPECT(!Dart_IsNull(old_ref));
|
| +
|
| + EXPECT_VALID(weak_new_ref);
|
| + EXPECT(!Dart_IsNull(weak_new_ref));
|
| + is_same = false;
|
| + EXPECT_VALID(Dart_IsSame(new_ref, weak_new_ref, &is_same));
|
| + EXPECT(is_same);
|
| +
|
| + EXPECT_VALID(weak_old_ref);
|
| + EXPECT(!Dart_IsNull(weak_old_ref));
|
| + is_same = false;
|
| + EXPECT_VALID(Dart_IsSame(old_ref, weak_old_ref, &is_same));
|
| + EXPECT(is_same);
|
| +
|
| + // garbage collect old space
|
| + Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
|
| +
|
| + // nothing should be invalidated or cleared
|
| + EXPECT_VALID(new_ref);
|
| + EXPECT(!Dart_IsNull(new_ref));
|
| + EXPECT_VALID(old_ref);
|
| + EXPECT(!Dart_IsNull(old_ref));
|
| +
|
| + EXPECT_VALID(weak_new_ref);
|
| + EXPECT(!Dart_IsNull(weak_new_ref));
|
| + is_same = false;
|
| + EXPECT_VALID(Dart_IsSame(new_ref, weak_new_ref, &is_same));
|
| + EXPECT(is_same);
|
| +
|
| + EXPECT_VALID(weak_old_ref);
|
| + EXPECT(!Dart_IsNull(weak_old_ref));
|
| + is_same = false;
|
| + EXPECT_VALID(Dart_IsSame(old_ref, weak_old_ref, &is_same));
|
| + EXPECT(is_same);
|
| +
|
| + // delete local (strong) references
|
| + Dart_ExitScope();
|
| + }
|
| +
|
| + // garbage collect new space again
|
| + Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
|
| +
|
| + // weak ref to new space object should now be cleared
|
| + EXPECT_VALID(weak_new_ref);
|
| + EXPECT(Dart_IsNull(weak_new_ref));
|
| + EXPECT_VALID(weak_old_ref);
|
| + EXPECT(!Dart_IsNull(weak_old_ref));
|
| +
|
| + // garbage collect old space again
|
| + Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
|
| +
|
| + // weak ref to old space object should now be cleared
|
| + EXPECT_VALID(weak_new_ref);
|
| + EXPECT(Dart_IsNull(weak_new_ref));
|
| + EXPECT_VALID(weak_old_ref);
|
| + EXPECT(Dart_IsNull(weak_old_ref));
|
| +}
|
| +
|
| +
|
| // Unit test for creating multiple scopes and local handles within them.
|
| // Ensure that the local handles get all cleaned out when exiting the
|
| // scope.
|
|
|