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

Side by Side Diff: runtime/vm/dart_api_impl_test.cc

Issue 15772005: - Add different types for persistent and weak persistent handles (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "include/dart_api.h" 5 #include "include/dart_api.h"
6 #include "bin/builtin.h" 6 #include "bin/builtin.h"
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "platform/json.h" 8 #include "platform/json.h"
9 #include "platform/utils.h" 9 #include "platform/utils.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 static const intptr_t kExtLength = 16; 924 static const intptr_t kExtLength = 16;
925 static int8_t data[kExtLength] = { 0x41, 0x42, 0x41, 0x42, 925 static int8_t data[kExtLength] = { 0x41, 0x42, 0x41, 0x42,
926 0x41, 0x42, 0x41, 0x42, 926 0x41, 0x42, 0x41, 0x42,
927 0x41, 0x42, 0x41, 0x42, 927 0x41, 0x42, 0x41, 0x42,
928 0x41, 0x42, 0x41, 0x42, }; 928 0x41, 0x42, 0x41, 0x42, };
929 929
930 static void ExternalByteDataNativeFunction(Dart_NativeArguments args) { 930 static void ExternalByteDataNativeFunction(Dart_NativeArguments args) {
931 Dart_EnterScope(); 931 Dart_EnterScope();
932 Dart_Handle external_byte_data = Dart_NewExternalTypedData(kByteData, 932 Dart_Handle external_byte_data = Dart_NewExternalTypedData(kByteData,
933 data, 933 data,
934 16, 934 16);
935 NULL, NULL);
936 EXPECT_VALID(external_byte_data); 935 EXPECT_VALID(external_byte_data);
937 EXPECT_EQ(kByteData, Dart_GetTypeOfTypedData(external_byte_data)); 936 EXPECT_EQ(kByteData, Dart_GetTypeOfTypedData(external_byte_data));
938 Dart_SetReturnValue(args, external_byte_data); 937 Dart_SetReturnValue(args, external_byte_data);
939 Dart_ExitScope(); 938 Dart_ExitScope();
940 } 939 }
941 940
942 941
943 static Dart_NativeFunction ExternalByteDataNativeResolver(Dart_Handle name, 942 static Dart_NativeFunction ExternalByteDataNativeResolver(Dart_Handle name,
944 int arg_count) { 943 int arg_count) {
945 return &ExternalByteDataNativeFunction; 944 return &ExternalByteDataNativeFunction;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 Dart_Handle list_access_test_obj; 1098 Dart_Handle list_access_test_obj;
1100 list_access_test_obj = Dart_Invoke(lib, NewString("main"), 0, NULL); 1099 list_access_test_obj = Dart_Invoke(lib, NewString("main"), 0, NULL);
1101 EXPECT_VALID(list_access_test_obj); 1100 EXPECT_VALID(list_access_test_obj);
1102 TestDirectAccess(lib, list_access_test_obj, kInt8); 1101 TestDirectAccess(lib, list_access_test_obj, kInt8);
1103 1102
1104 // Test with an external typed data object. 1103 // Test with an external typed data object.
1105 uint8_t data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1104 uint8_t data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1106 intptr_t data_length = ARRAY_SIZE(data); 1105 intptr_t data_length = ARRAY_SIZE(data);
1107 Dart_Handle ext_list_access_test_obj; 1106 Dart_Handle ext_list_access_test_obj;
1108 ext_list_access_test_obj = Dart_NewExternalTypedData(kUint8, 1107 ext_list_access_test_obj = Dart_NewExternalTypedData(kUint8,
1109 data, 1108 data, data_length);
1110 data_length,
1111 NULL, NULL);
1112 EXPECT_VALID(ext_list_access_test_obj); 1109 EXPECT_VALID(ext_list_access_test_obj);
1113 TestDirectAccess(lib, ext_list_access_test_obj, kUint8); 1110 TestDirectAccess(lib, ext_list_access_test_obj, kUint8);
1114 } 1111 }
1115 1112
1116 1113
1117 TEST_CASE(TypedDataViewDirectAccess) { 1114 TEST_CASE(TypedDataViewDirectAccess) {
1118 const char* kScriptChars = 1115 const char* kScriptChars =
1119 "import 'dart:typed_data';\n" 1116 "import 'dart:typed_data';\n"
1120 "class Expect {\n" 1117 "class Expect {\n"
1121 " static equals(a, b) {\n" 1118 " static equals(a, b) {\n"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 1199
1203 void* raw_data = NULL; 1200 void* raw_data = NULL;
1204 intptr_t len; 1201 intptr_t len;
1205 Dart_TypedData_Type type; 1202 Dart_TypedData_Type type;
1206 EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len)); 1203 EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len));
1207 EXPECT(raw_data == data); 1204 EXPECT(raw_data == data);
1208 EXPECT_EQ(data_length, len); 1205 EXPECT_EQ(data_length, len);
1209 EXPECT_EQ(expected_type, type); 1206 EXPECT_EQ(expected_type, type);
1210 EXPECT_VALID(Dart_TypedDataReleaseData(obj)); 1207 EXPECT_VALID(Dart_TypedDataReleaseData(obj));
1211 1208
1212 void* peer = &data; // just a non-NULL value
1213 EXPECT_VALID(Dart_ExternalTypedDataGetPeer(obj, &peer));
1214 EXPECT(peer == NULL);
1215
1216 intptr_t list_length = 0; 1209 intptr_t list_length = 0;
1217 EXPECT_VALID(Dart_ListLength(obj, &list_length)); 1210 EXPECT_VALID(Dart_ListLength(obj, &list_length));
1218 EXPECT_EQ(data_length, list_length); 1211 EXPECT_EQ(data_length, list_length);
1219 1212
1220 // Load and check values from underlying array and API. 1213 // Load and check values from underlying array and API.
1221 for (intptr_t i = 0; i < list_length; ++i) { 1214 for (intptr_t i = 0; i < list_length; ++i) {
1222 EXPECT_EQ(11 * i, data[i]); 1215 EXPECT_EQ(11 * i, data[i]);
1223 Dart_Handle elt = Dart_ListGetAt(obj, i); 1216 Dart_Handle elt = Dart_ListGetAt(obj, i);
1224 EXPECT_VALID(elt); 1217 EXPECT_VALID(elt);
1225 int64_t value = 0; 1218 int64_t value = 0;
(...skipping 24 matching lines...) Expand all
1250 for (intptr_t i = 0; i < data_length; ++i) { 1243 for (intptr_t i = 0; i < data_length; ++i) {
1251 EXPECT_EQ(33 * i, data[i]); 1244 EXPECT_EQ(33 * i, data[i]);
1252 } 1245 }
1253 } 1246 }
1254 1247
1255 1248
1256 TEST_CASE(ExternalTypedDataAccess) { 1249 TEST_CASE(ExternalTypedDataAccess) {
1257 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 }; 1250 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 };
1258 intptr_t data_length = ARRAY_SIZE(data); 1251 intptr_t data_length = ARRAY_SIZE(data);
1259 1252
1260 Dart_Handle obj = Dart_NewExternalTypedData(kUint8, 1253 Dart_Handle obj = Dart_NewExternalTypedData(kUint8, data, data_length);
1261 data, data_length,
1262 NULL, NULL);
1263 ExternalTypedDataAccessTests(obj, kUint8, data, data_length); 1254 ExternalTypedDataAccessTests(obj, kUint8, data, data_length);
1264 } 1255 }
1265 1256
1266 1257
1267 TEST_CASE(ExternalClampedTypedDataAccess) { 1258 TEST_CASE(ExternalClampedTypedDataAccess) {
1268 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 }; 1259 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 };
1269 intptr_t data_length = ARRAY_SIZE(data); 1260 intptr_t data_length = ARRAY_SIZE(data);
1270 1261
1271 Dart_Handle obj = Dart_NewExternalTypedData(kUint8Clamped, 1262 Dart_Handle obj = Dart_NewExternalTypedData(kUint8Clamped, data, data_length);
1272 data, data_length,
1273 NULL, NULL);
1274 ExternalTypedDataAccessTests(obj, kUint8Clamped, data, data_length); 1263 ExternalTypedDataAccessTests(obj, kUint8Clamped, data, data_length);
1275 } 1264 }
1276 1265
1277 1266
1278 TEST_CASE(ExternalUint8ClampedArrayAccess) { 1267 TEST_CASE(ExternalUint8ClampedArrayAccess) {
1279 const char* kScriptChars = 1268 const char* kScriptChars =
1280 "testClamped(List a) {\n" 1269 "testClamped(List a) {\n"
1281 " if (a[1] != 11) return false;\n" 1270 " if (a[1] != 11) return false;\n"
1282 " a[1] = 3;\n" 1271 " a[1] = 3;\n"
1283 " if (a[1] != 3) return false;\n" 1272 " if (a[1] != 3) return false;\n"
1284 " a[1] = -12;\n" 1273 " a[1] = -12;\n"
1285 " if (a[1] != 0) return false;\n" 1274 " if (a[1] != 0) return false;\n"
1286 " a[1] = 1200;\n" 1275 " a[1] = 1200;\n"
1287 " if (a[1] != 255) return false;\n" 1276 " if (a[1] != 255) return false;\n"
1288 " return true;\n" 1277 " return true;\n"
1289 "}\n"; 1278 "}\n";
1290 1279
1291 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 }; 1280 uint8_t data[] = { 0, 11, 22, 33, 44, 55, 66, 77 };
1292 intptr_t data_length = ARRAY_SIZE(data); 1281 intptr_t data_length = ARRAY_SIZE(data);
1293 Dart_Handle obj = Dart_NewExternalTypedData(kUint8Clamped, 1282 Dart_Handle obj = Dart_NewExternalTypedData(kUint8Clamped,
1294 data, data_length, 1283 data, data_length);
1295 NULL, NULL);
1296 EXPECT_VALID(obj); 1284 EXPECT_VALID(obj);
1297 Dart_Handle result; 1285 Dart_Handle result;
1298 // Create a test library and Load up a test script in it. 1286 // Create a test library and Load up a test script in it.
1299 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); 1287 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
1300 Dart_Handle args[1]; 1288 Dart_Handle args[1];
1301 args[0] = obj; 1289 args[0] = obj;
1302 result = Dart_Invoke(lib, NewString("testClamped"), 1, args); 1290 result = Dart_Invoke(lib, NewString("testClamped"), 1, args);
1303 1291
1304 // Check that result is true. 1292 // Check that result is true.
1305 EXPECT_VALID(result); 1293 EXPECT_VALID(result);
1306 EXPECT(Dart_IsBoolean(result)); 1294 EXPECT(Dart_IsBoolean(result));
1307 bool value = false; 1295 bool value = false;
1308 result = Dart_BooleanValue(result, &value); 1296 result = Dart_BooleanValue(result, &value);
1309 EXPECT_VALID(result); 1297 EXPECT_VALID(result);
1310 EXPECT(value); 1298 EXPECT(value);
1311 } 1299 }
1312 1300
1313 1301
1314 static void ExternalTypedDataCallbackFinalizer(Dart_Handle handle, 1302 static void ExternalTypedDataCallbackFinalizer(Dart_WeakPersistentHandle handle,
1315 void* peer) { 1303 void* peer) {
1316 Dart_DeletePersistentHandle(handle); 1304 Dart_DeleteWeakPersistentHandle(handle);
1317 *static_cast<int*>(peer) = 42; 1305 *static_cast<int*>(peer) = 42;
1318 } 1306 }
1319 1307
1320 1308
1321 TEST_CASE(ExternalTypedDataCallback) { 1309 TEST_CASE(ExternalTypedDataCallback) {
1322 int peer = 0; 1310 int peer = 0;
1323 { 1311 {
1324 Dart_EnterScope(); 1312 Dart_EnterScope();
1325 uint8_t data[] = { 1, 2, 3, 4 }; 1313 uint8_t data[] = { 1, 2, 3, 4 };
1326 Dart_Handle obj = Dart_NewExternalTypedData( 1314 Dart_Handle obj = Dart_NewExternalTypedData(
1327 kUint8, 1315 kUint8,
1328 data, 1316 data,
1329 ARRAY_SIZE(data), 1317 ARRAY_SIZE(data));
1330 &peer, 1318 Dart_NewWeakPersistentHandle(obj,
1331 ExternalTypedDataCallbackFinalizer); 1319 &peer,
1320 ExternalTypedDataCallbackFinalizer);
1332 EXPECT_VALID(obj); 1321 EXPECT_VALID(obj);
1333 void* api_peer = NULL;
1334 EXPECT_VALID(Dart_ExternalTypedDataGetPeer(obj, &api_peer));
1335 EXPECT_EQ(api_peer, &peer);
1336 Dart_ExitScope(); 1322 Dart_ExitScope();
1337 } 1323 }
1338 EXPECT(peer == 0); 1324 EXPECT(peer == 0);
1339 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1325 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1340 EXPECT(peer == 0); 1326 EXPECT(peer == 0);
1341 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); 1327 Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
1342 EXPECT(peer == 42); 1328 EXPECT(peer == 42);
1343 } 1329 }
1344 1330
1345 1331
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 1363
1378 int peer = 0; 1364 int peer = 0;
1379 float data[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1365 float data[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1380 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1366 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1381 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1367 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
1382 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; 1368 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
1383 // Push a scope so that we can collect the local handle created as part of 1369 // Push a scope so that we can collect the local handle created as part of
1384 // Dart_NewExternalTypedData. 1370 // Dart_NewExternalTypedData.
1385 Dart_EnterScope(); 1371 Dart_EnterScope();
1386 { 1372 {
1387 Dart_Handle lcl = Dart_NewExternalTypedData( 1373 Dart_Handle lcl = Dart_NewExternalTypedData(kFloat32x4, data, 10);
1388 kFloat32x4, data, 10, &peer, ExternalTypedDataCallbackFinalizer); 1374 Dart_NewWeakPersistentHandle(lcl, &peer, ExternalTypedDataCallbackFinalizer) ;
1389 CheckFloat32x4Data(lcl); 1375 CheckFloat32x4Data(lcl);
1390 } 1376 }
1391 Dart_ExitScope(); 1377 Dart_ExitScope();
1392 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); 1378 Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
1393 EXPECT(peer == 42); 1379 EXPECT(peer == 42);
1394 } 1380 }
1395 1381
1396 1382
1397 // Unit test for entering a scope, creating a local handle and exiting 1383 // Unit test for entering a scope, creating a local handle and exiting
1398 // the scope. 1384 // the scope.
(...skipping 23 matching lines...) Expand all
1422 // Unit test for creating and deleting persistent handles. 1408 // Unit test for creating and deleting persistent handles.
1423 UNIT_TEST_CASE(PersistentHandles) { 1409 UNIT_TEST_CASE(PersistentHandles) {
1424 const char* kTestString1 = "Test String1"; 1410 const char* kTestString1 = "Test String1";
1425 const char* kTestString2 = "Test String2"; 1411 const char* kTestString2 = "Test String2";
1426 TestCase::CreateTestIsolate(); 1412 TestCase::CreateTestIsolate();
1427 Isolate* isolate = Isolate::Current(); 1413 Isolate* isolate = Isolate::Current();
1428 EXPECT(isolate != NULL); 1414 EXPECT(isolate != NULL);
1429 ApiState* state = isolate->api_state(); 1415 ApiState* state = isolate->api_state();
1430 EXPECT(state != NULL); 1416 EXPECT(state != NULL);
1431 ApiLocalScope* scope = state->top_scope(); 1417 ApiLocalScope* scope = state->top_scope();
1432 Dart_Handle handles[2000]; 1418 Dart_PersistentHandle handles[2000];
1433 Dart_EnterScope(); 1419 Dart_EnterScope();
1434 { 1420 {
1435 DARTSCOPE(isolate); 1421 DARTSCOPE(isolate);
1436 Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1)); 1422 Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1));
1437 for (int i = 0; i < 1000; i++) { 1423 for (int i = 0; i < 1000; i++) {
1438 handles[i] = Dart_NewPersistentHandle(ref1); 1424 handles[i] = Dart_NewPersistentHandle(ref1);
1439 } 1425 }
1440 Dart_EnterScope(); 1426 Dart_EnterScope();
1441 Dart_Handle ref2 = Api::NewHandle(isolate, String::New(kTestString2)); 1427 Dart_Handle ref2 = Api::NewHandle(isolate, String::New(kTestString2));
1442 for (int i = 1000; i < 2000; i++) { 1428 for (int i = 1000; i < 2000; i++) {
(...skipping 10 matching lines...) Expand all
1453 } 1439 }
1454 VERIFY_ON_TRANSITION; 1440 VERIFY_ON_TRANSITION;
1455 Dart_ExitScope(); 1441 Dart_ExitScope();
1456 } 1442 }
1457 Dart_ExitScope(); 1443 Dart_ExitScope();
1458 { 1444 {
1459 StackZone zone(isolate); 1445 StackZone zone(isolate);
1460 HANDLESCOPE(isolate); 1446 HANDLESCOPE(isolate);
1461 for (int i = 0; i < 500; i++) { 1447 for (int i = 0; i < 500; i++) {
1462 String& str = String::Handle(); 1448 String& str = String::Handle();
1463 str ^= Api::UnwrapHandle(handles[i]); 1449 str ^= Api::UnwrapAsPersistentHandle(handles[i])->raw();
1464 EXPECT(str.Equals(kTestString1)); 1450 EXPECT(str.Equals(kTestString1));
1465 } 1451 }
1466 for (int i = 500; i < 1000; i++) { 1452 for (int i = 500; i < 1000; i++) {
1467 String& str = String::Handle(); 1453 String& str = String::Handle();
1468 str ^= Api::UnwrapHandle(handles[i]); 1454 str ^= Api::UnwrapAsPersistentHandle(handles[i])->raw();
1469 EXPECT(str.Equals(kTestString2)); 1455 EXPECT(str.Equals(kTestString2));
1470 } 1456 }
1471 for (int i = 1000; i < 1500; i++) { 1457 for (int i = 1000; i < 1500; i++) {
1472 String& str = String::Handle(); 1458 String& str = String::Handle();
1473 str ^= Api::UnwrapHandle(handles[i]); 1459 str ^= Api::UnwrapAsPersistentHandle(handles[i])->raw();
1474 EXPECT(str.Equals(kTestString1)); 1460 EXPECT(str.Equals(kTestString1));
1475 } 1461 }
1476 for (int i = 1500; i < 2000; i++) { 1462 for (int i = 1500; i < 2000; i++) {
1477 String& str = String::Handle(); 1463 String& str = String::Handle();
1478 str ^= Api::UnwrapHandle(handles[i]); 1464 str ^= Api::UnwrapAsPersistentHandle(handles[i])->raw();
1479 EXPECT(str.Equals(kTestString2)); 1465 EXPECT(str.Equals(kTestString2));
1480 } 1466 }
1481 } 1467 }
1482 EXPECT(scope == state->top_scope()); 1468 EXPECT(scope == state->top_scope());
1483 EXPECT_EQ(2001, state->CountPersistentHandles()); 1469 EXPECT_EQ(2001, state->CountPersistentHandles());
1484 Dart_ShutdownIsolate(); 1470 Dart_ShutdownIsolate();
1485 } 1471 }
1486 1472
1487 1473
1488 // Test that we are able to create a persistent handle from a 1474 // Test that we are able to create a persistent handle from a
1489 // persistent handle. 1475 // persistent handle.
1490 UNIT_TEST_CASE(NewPersistentHandle_FromPersistentHandle) { 1476 UNIT_TEST_CASE(NewPersistentHandle_FromPersistentHandle) {
1491 TestIsolateScope __test_isolate__; 1477 TestIsolateScope __test_isolate__;
1492 1478
1493 Isolate* isolate = Isolate::Current(); 1479 Isolate* isolate = Isolate::Current();
1494 EXPECT(isolate != NULL); 1480 EXPECT(isolate != NULL);
1495 ApiState* state = isolate->api_state(); 1481 ApiState* state = isolate->api_state();
1496 EXPECT(state != NULL); 1482 EXPECT(state != NULL);
1497 DARTSCOPE(isolate); 1483 DARTSCOPE(isolate);
1498 1484
1499 // Start with a known persistent handle. 1485 // Start with a known persistent handle.
1500 Dart_Handle obj1 = Dart_True(); 1486 Dart_PersistentHandle obj1 = Dart_NewPersistentHandle(Dart_True());
1501 EXPECT(state->IsValidPersistentHandle(obj1)); 1487 EXPECT(state->IsValidPersistentHandle(obj1));
1502 1488
1503 // And use it to allocate a second persistent handle. 1489 // And use it to allocate a second persistent handle.
1504 Dart_Handle obj2 = Dart_NewPersistentHandle(obj1); 1490 Dart_Handle obj2 = Dart_HandleFromPersistent(obj1);
1505 EXPECT(state->IsValidPersistentHandle(obj2)); 1491 Dart_PersistentHandle obj3 = Dart_NewPersistentHandle(obj2);
1492 EXPECT(state->IsValidPersistentHandle(obj3));
1506 1493
1507 // Make sure that the value transferred. 1494 // Make sure that the value transferred.
1508 EXPECT(Dart_IsBoolean(obj2)); 1495 Dart_Handle obj4 = Dart_HandleFromPersistent(obj3);
1496 EXPECT(Dart_IsBoolean(obj4));
1509 bool value = false; 1497 bool value = false;
1510 Dart_Handle result = Dart_BooleanValue(obj2, &value); 1498 Dart_Handle result = Dart_BooleanValue(obj4, &value);
1511 EXPECT_VALID(result); 1499 EXPECT_VALID(result);
1512 EXPECT(value); 1500 EXPECT(value);
1513 } 1501 }
1514 1502
1515 1503
1516 // Helper class to ensure new gen GC is triggered without any side effects. 1504 // Helper class to ensure new gen GC is triggered without any side effects.
1517 // The normal call to CollectGarbage(Heap::kNew) could potentially trigger 1505 // The normal call to CollectGarbage(Heap::kNew) could potentially trigger
1518 // an old gen collection if there is a promotion failure and this could 1506 // an old gen collection if there is a promotion failure and this could
1519 // perturb the test. 1507 // perturb the test.
1520 class GCTestHelper : public AllStatic { 1508 class GCTestHelper : public AllStatic {
1521 public: 1509 public:
1522 static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) { 1510 static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) {
1523 bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks); 1511 bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks);
1524 Isolate::Current()->heap()->new_space_->Scavenge(invoke_api_callbacks); 1512 Isolate::Current()->heap()->new_space_->Scavenge(invoke_api_callbacks);
1525 } 1513 }
1526 }; 1514 };
1527 1515
1528 1516
1517 static Dart_Handle AsHandle(Dart_PersistentHandle weak) {
1518 return Dart_HandleFromPersistent(weak);
1519 }
1520
1521
1522 static Dart_Handle AsHandle(Dart_WeakPersistentHandle weak) {
1523 return Dart_HandleFromWeakPersistent(weak);
1524 }
1525
1526
1529 TEST_CASE(WeakPersistentHandle) { 1527 TEST_CASE(WeakPersistentHandle) {
1530 Dart_Handle weak_new_ref = Dart_Null(); 1528 Dart_Handle local_new_ref = Dart_Null();
1531 EXPECT(Dart_IsNull(weak_new_ref)); 1529 Dart_WeakPersistentHandle weak_new_ref = Dart_NewWeakPersistentHandle(
1530 local_new_ref, NULL, NULL);
1532 1531
1533 Dart_Handle weak_old_ref = Dart_Null(); 1532 Dart_Handle local_old_ref = Dart_Null();
1534 EXPECT(Dart_IsNull(weak_old_ref)); 1533 Dart_WeakPersistentHandle weak_old_ref = Dart_NewWeakPersistentHandle(
1534 local_old_ref, NULL, NULL);
1535 1535
1536 { 1536 {
1537 Dart_EnterScope(); 1537 Dart_EnterScope();
1538 1538
1539 // Create an object in new space. 1539 // Create an object in new space.
1540 Dart_Handle new_ref = NewString("new string"); 1540 Dart_Handle new_ref = NewString("new string");
1541 EXPECT_VALID(new_ref); 1541 EXPECT_VALID(new_ref);
1542 1542
1543 // Create an object in old space. 1543 // Create an object in old space.
1544 Dart_Handle old_ref; 1544 Dart_Handle old_ref;
1545 { 1545 {
1546 Isolate* isolate = Isolate::Current(); 1546 Isolate* isolate = Isolate::Current();
1547 DARTSCOPE(isolate); 1547 DARTSCOPE(isolate);
1548 old_ref = Api::NewHandle(isolate, String::New("old string", Heap::kOld)); 1548 old_ref = Api::NewHandle(isolate, String::New("old string", Heap::kOld));
1549 EXPECT_VALID(old_ref); 1549 EXPECT_VALID(old_ref);
1550 } 1550 }
1551 1551
1552 // Create a weak ref to the new space object. 1552 // Create a weak ref to the new space object.
1553 weak_new_ref = Dart_NewWeakPersistentHandle(new_ref, NULL, NULL); 1553 weak_new_ref = Dart_NewWeakPersistentHandle(new_ref, NULL, NULL);
1554 EXPECT_VALID(weak_new_ref); 1554 EXPECT_VALID(AsHandle(weak_new_ref));
1555 EXPECT(!Dart_IsNull(weak_new_ref)); 1555 EXPECT(!Dart_IsNull(AsHandle(weak_new_ref)));
1556 1556
1557 // Create a weak ref to the old space object. 1557 // Create a weak ref to the old space object.
1558 weak_old_ref = Dart_NewWeakPersistentHandle(old_ref, NULL, NULL); 1558 weak_old_ref = Dart_NewWeakPersistentHandle(old_ref, NULL, NULL);
1559 EXPECT_VALID(weak_old_ref); 1559 EXPECT_VALID(AsHandle(weak_old_ref));
1560 EXPECT(!Dart_IsNull(weak_old_ref)); 1560 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
1561 1561
1562 // Garbage collect new space. 1562 // Garbage collect new space.
1563 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1563 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1564 1564
1565 // Nothing should be invalidated or cleared. 1565 // Nothing should be invalidated or cleared.
1566 EXPECT_VALID(new_ref); 1566 EXPECT_VALID(new_ref);
1567 EXPECT(!Dart_IsNull(new_ref)); 1567 EXPECT(!Dart_IsNull(new_ref));
1568 EXPECT_VALID(old_ref); 1568 EXPECT_VALID(old_ref);
1569 EXPECT(!Dart_IsNull(old_ref)); 1569 EXPECT(!Dart_IsNull(old_ref));
1570 1570
1571 EXPECT_VALID(weak_new_ref); 1571 EXPECT_VALID(AsHandle(weak_new_ref));
1572 EXPECT(!Dart_IsNull(weak_new_ref)); 1572 EXPECT(!Dart_IsNull(AsHandle(weak_new_ref)));
1573 EXPECT(Dart_IdentityEquals(new_ref, weak_new_ref)); 1573 EXPECT(Dart_IdentityEquals(new_ref, AsHandle(weak_new_ref)));
1574 1574
1575 EXPECT_VALID(weak_old_ref); 1575 EXPECT_VALID(AsHandle(weak_old_ref));
1576 EXPECT(!Dart_IsNull(weak_old_ref)); 1576 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
1577 EXPECT(Dart_IdentityEquals(old_ref, weak_old_ref)); 1577 EXPECT(Dart_IdentityEquals(old_ref, AsHandle(weak_old_ref)));
1578 1578
1579 // Garbage collect old space. 1579 // Garbage collect old space.
1580 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1580 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1581 1581
1582 // Nothing should be invalidated or cleared. 1582 // Nothing should be invalidated or cleared.
1583 EXPECT_VALID(new_ref); 1583 EXPECT_VALID(new_ref);
1584 EXPECT(!Dart_IsNull(new_ref)); 1584 EXPECT(!Dart_IsNull(new_ref));
1585 EXPECT_VALID(old_ref); 1585 EXPECT_VALID(old_ref);
1586 EXPECT(!Dart_IsNull(old_ref)); 1586 EXPECT(!Dart_IsNull(old_ref));
1587 1587
1588 EXPECT_VALID(weak_new_ref); 1588 EXPECT_VALID(AsHandle(weak_new_ref));
1589 EXPECT(!Dart_IsNull(weak_new_ref)); 1589 EXPECT(!Dart_IsNull(AsHandle(weak_new_ref)));
1590 EXPECT(Dart_IdentityEquals(new_ref, weak_new_ref)); 1590 EXPECT(Dart_IdentityEquals(new_ref, AsHandle(weak_new_ref)));
1591 1591
1592 EXPECT_VALID(weak_old_ref); 1592 EXPECT_VALID(AsHandle(weak_old_ref));
1593 EXPECT(!Dart_IsNull(weak_old_ref)); 1593 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
1594 EXPECT(Dart_IdentityEquals(old_ref, weak_old_ref)); 1594 EXPECT(Dart_IdentityEquals(old_ref, AsHandle(weak_old_ref)));
1595 1595
1596 // Delete local (strong) references. 1596 // Delete local (strong) references.
1597 Dart_ExitScope(); 1597 Dart_ExitScope();
1598 } 1598 }
1599 1599
1600 // Garbage collect new space again. 1600 // Garbage collect new space again.
1601 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1601 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1602 1602
1603 // Weak ref to new space object should now be cleared. 1603 {
1604 EXPECT_VALID(weak_new_ref); 1604 Dart_EnterScope();
1605 EXPECT(Dart_IsNull(weak_new_ref)); 1605 // Weak ref to new space object should now be cleared.
1606 EXPECT_VALID(weak_old_ref); 1606 EXPECT_VALID(AsHandle(weak_new_ref));
1607 EXPECT(!Dart_IsNull(weak_old_ref)); 1607 EXPECT(Dart_IsNull(AsHandle(weak_new_ref)));
1608 EXPECT_VALID(AsHandle(weak_old_ref));
1609 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
1610 Dart_ExitScope();
1611 }
1608 1612
1609 // Garbage collect old space again. 1613 // Garbage collect old space again.
1610 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1614 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1611 1615
1612 // Weak ref to old space object should now be cleared. 1616 {
1613 EXPECT_VALID(weak_new_ref); 1617 Dart_EnterScope();
1614 EXPECT(Dart_IsNull(weak_new_ref)); 1618 // Weak ref to old space object should now be cleared.
1615 EXPECT_VALID(weak_old_ref); 1619 EXPECT_VALID(AsHandle(weak_new_ref));
1616 EXPECT(Dart_IsNull(weak_old_ref)); 1620 EXPECT(Dart_IsNull(AsHandle(weak_new_ref)));
1621 EXPECT_VALID(AsHandle(weak_old_ref));
1622 EXPECT(Dart_IsNull(AsHandle(weak_old_ref)));
1623 Dart_ExitScope();
1624 }
1617 1625
1618 Dart_DeletePersistentHandle(weak_new_ref); 1626 Dart_DeleteWeakPersistentHandle(weak_new_ref);
1619 Dart_DeletePersistentHandle(weak_old_ref); 1627 Dart_DeleteWeakPersistentHandle(weak_old_ref);
1620 1628
1621 // Garbage collect one last time to revisit deleted handles. 1629 // Garbage collect one last time to revisit deleted handles.
1622 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); 1630 Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
1623 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1631 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1624 } 1632 }
1625 1633
1626 1634
1627 static void WeakPersistentHandlePeerFinalizer(Dart_Handle handle, void* peer) { 1635 static void WeakPersistentHandlePeerFinalizer(Dart_WeakPersistentHandle handle, void* peer) {
1628 *static_cast<int*>(peer) = 42; 1636 *static_cast<int*>(peer) = 42;
1629 } 1637 }
1630 1638
1631 1639
1632 TEST_CASE(WeakPersistentHandleCallback) { 1640 TEST_CASE(WeakPersistentHandleCallback) {
1633 Dart_Handle weak_ref = Dart_Null(); 1641 Dart_WeakPersistentHandle weak_ref = NULL;
1634 EXPECT(Dart_IsNull(weak_ref));
1635 int peer = 0; 1642 int peer = 0;
1636 { 1643 {
1637 Dart_EnterScope(); 1644 Dart_EnterScope();
1638 Dart_Handle obj = NewString("new string"); 1645 Dart_Handle obj = NewString("new string");
1639 EXPECT_VALID(obj); 1646 EXPECT_VALID(obj);
1640 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 1647 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer,
1641 WeakPersistentHandlePeerFinalizer); 1648 WeakPersistentHandlePeerFinalizer);
1649 EXPECT_VALID(AsHandle(weak_ref));
1650 EXPECT(peer == 0);
1642 Dart_ExitScope(); 1651 Dart_ExitScope();
1643 } 1652 }
1644 EXPECT_VALID(weak_ref);
1645 EXPECT(peer == 0);
1646 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1653 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1647 EXPECT(peer == 0); 1654 EXPECT(peer == 0);
1648 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1655 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1649 EXPECT(peer == 42); 1656 EXPECT(peer == 42);
1650 Dart_DeletePersistentHandle(weak_ref); 1657 Dart_DeleteWeakPersistentHandle(weak_ref);
1651 } 1658 }
1652 1659
1653 1660
1654 TEST_CASE(WeakPersistentHandleNoCallback) { 1661 TEST_CASE(WeakPersistentHandleNoCallback) {
1655 Dart_Handle weak_ref = Dart_Null(); 1662 Dart_WeakPersistentHandle weak_ref = NULL;
1656 EXPECT(Dart_IsNull(weak_ref));
1657 int peer = 0; 1663 int peer = 0;
1658 { 1664 {
1659 Dart_EnterScope(); 1665 Dart_EnterScope();
1660 Dart_Handle obj = NewString("new string"); 1666 Dart_Handle obj = NewString("new string");
1661 EXPECT_VALID(obj); 1667 EXPECT_VALID(obj);
1662 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 1668 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer,
1663 WeakPersistentHandlePeerFinalizer); 1669 WeakPersistentHandlePeerFinalizer);
1664 Dart_ExitScope(); 1670 Dart_ExitScope();
1665 } 1671 }
1666 // A finalizer is not invoked on a deleted handle. Therefore, the 1672 // A finalizer is not invoked on a deleted handle. Therefore, the
1667 // peer value should not change after the referent is collected. 1673 // peer value should not change after the referent is collected.
1668 Dart_DeletePersistentHandle(weak_ref); 1674 Dart_DeleteWeakPersistentHandle(weak_ref);
1669 EXPECT_VALID(weak_ref);
1670 EXPECT(peer == 0); 1675 EXPECT(peer == 0);
1671 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1676 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1672 EXPECT(peer == 0); 1677 EXPECT(peer == 0);
1673 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1678 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1674 EXPECT(peer == 0); 1679 EXPECT(peer == 0);
1675 } 1680 }
1676 1681
1677 1682
1678 UNIT_TEST_CASE(WeakPersistentHandlesCallbackShutdown) { 1683 UNIT_TEST_CASE(WeakPersistentHandlesCallbackShutdown) {
1679 TestCase::CreateTestIsolate(); 1684 TestCase::CreateTestIsolate();
1680 Dart_EnterScope(); 1685 Dart_EnterScope();
1681 Dart_Handle ref = Dart_True(); 1686 Dart_Handle ref = Dart_True();
1682 int peer = 1234; 1687 int peer = 1234;
1683 Dart_NewWeakPersistentHandle(ref, 1688 Dart_NewWeakPersistentHandle(ref,
1684 &peer, 1689 &peer,
1685 WeakPersistentHandlePeerFinalizer); 1690 WeakPersistentHandlePeerFinalizer);
1686 Dart_ShutdownIsolate(); 1691 Dart_ShutdownIsolate();
1687 EXPECT(peer == 42); 1692 EXPECT(peer == 42);
1688 } 1693 }
1689 1694
1690 1695
1691 TEST_CASE(ObjectGroups) { 1696 TEST_CASE(ObjectGroups) {
1692 Dart_Handle strong = Dart_Null(); 1697 Dart_PersistentHandle strong = NULL;
1693 EXPECT(Dart_IsNull(strong)); 1698 Dart_WeakPersistentHandle strong_weak = NULL;
1694 1699
1695 Dart_Handle weak1 = Dart_Null(); 1700 Dart_WeakPersistentHandle weak1 = NULL;
1696 EXPECT(Dart_IsNull(weak1)); 1701 Dart_WeakPersistentHandle weak2 = NULL;
1697 1702 Dart_WeakPersistentHandle weak3 = NULL;
1698 Dart_Handle weak2 = Dart_Null(); 1703 Dart_WeakPersistentHandle weak4 = NULL;
1699 EXPECT(Dart_IsNull(weak2));
1700
1701 Dart_Handle weak3 = Dart_Null();
1702 EXPECT(Dart_IsNull(weak3));
1703
1704 Dart_Handle weak4 = Dart_Null();
1705 EXPECT(Dart_IsNull(weak4));
1706 1704
1707 Dart_EnterScope(); 1705 Dart_EnterScope();
1708 { 1706 {
1709 Isolate* isolate = Isolate::Current(); 1707 Isolate* isolate = Isolate::Current();
1710 DARTSCOPE(isolate); 1708 DARTSCOPE(isolate);
1711 1709
1712 strong = Dart_NewPersistentHandle( 1710 Dart_Handle local = Api::NewHandle(isolate, String::New("strongly reachable" , Heap::kOld));
1713 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kOld))); 1711 strong = Dart_NewPersistentHandle(local);
1714 EXPECT_VALID(strong); 1712 strong_weak = Dart_NewWeakPersistentHandle(local, NULL, NULL);
1715 EXPECT(!Dart_IsNull(strong)); 1713 EXPECT_VALID(AsHandle(strong));
1714 EXPECT(!Dart_IsNull(AsHandle(strong)));
1715
1716 1716
1717 weak1 = Dart_NewWeakPersistentHandle( 1717 weak1 = Dart_NewWeakPersistentHandle(
1718 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)), 1718 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)),
1719 NULL, NULL); 1719 NULL, NULL);
1720 EXPECT_VALID(weak1); 1720 EXPECT_VALID(AsHandle(weak1));
1721 EXPECT(!Dart_IsNull(weak1)); 1721 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1722 1722
1723 weak2 = Dart_NewWeakPersistentHandle( 1723 weak2 = Dart_NewWeakPersistentHandle(
1724 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)), 1724 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)),
1725 NULL, NULL); 1725 NULL, NULL);
1726 EXPECT_VALID(weak2); 1726 EXPECT_VALID(AsHandle(weak2));
1727 EXPECT(!Dart_IsNull(weak2)); 1727 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1728 1728
1729 weak3 = Dart_NewWeakPersistentHandle( 1729 weak3 = Dart_NewWeakPersistentHandle(
1730 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)), 1730 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)),
1731 NULL, NULL); 1731 NULL, NULL);
1732 EXPECT_VALID(weak3); 1732 EXPECT_VALID(AsHandle(weak3));
1733 EXPECT(!Dart_IsNull(weak3)); 1733 EXPECT(!Dart_IsNull(AsHandle(weak3)));
1734 1734
1735 weak4 = Dart_NewWeakPersistentHandle( 1735 weak4 = Dart_NewWeakPersistentHandle(
1736 Api::NewHandle(isolate, String::New("weakly reachable 4", Heap::kOld)), 1736 Api::NewHandle(isolate, String::New("weakly reachable 4", Heap::kOld)),
1737 NULL, NULL); 1737 NULL, NULL);
1738 EXPECT_VALID(weak4); 1738 EXPECT_VALID(AsHandle(weak4));
1739 EXPECT(!Dart_IsNull(weak4)); 1739 EXPECT(!Dart_IsNull(AsHandle(weak4)));
1740 } 1740 }
1741 Dart_ExitScope(); 1741 Dart_ExitScope();
1742 1742
1743 EXPECT_VALID(strong); 1743 {
1744 1744 Dart_EnterScope();
1745 EXPECT_VALID(weak1); 1745 EXPECT_VALID(AsHandle(strong));
1746 EXPECT_VALID(weak2); 1746 EXPECT_VALID(AsHandle(weak1));
1747 EXPECT_VALID(weak3); 1747 EXPECT_VALID(AsHandle(weak2));
1748 EXPECT_VALID(weak4); 1748 EXPECT_VALID(AsHandle(weak3));
1749 EXPECT_VALID(AsHandle(weak4));
1750 Dart_ExitScope();
1751 }
1749 1752
1750 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1753 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1751 1754
1752 // New space collection should not affect old space objects 1755 {
1753 EXPECT(!Dart_IsNull(weak1)); 1756 Dart_EnterScope();
1754 EXPECT(!Dart_IsNull(weak2)); 1757 // New space collection should not affect old space objects
1755 EXPECT(!Dart_IsNull(weak3)); 1758 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1756 EXPECT(!Dart_IsNull(weak4)); 1759 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1760 EXPECT(!Dart_IsNull(AsHandle(weak3)));
1761 EXPECT(!Dart_IsNull(AsHandle(weak4)));
1762 Dart_ExitScope();
1763 }
1757 1764
1758 { 1765 {
1759 Dart_Handle array1[] = { weak1, strong }; 1766 Dart_WeakPersistentHandle array1[] = { weak1, strong_weak };
1760 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), 1767 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1),
1761 array1, ARRAY_SIZE(array1))); 1768 array1, ARRAY_SIZE(array1)));
1762 1769
1763 Dart_Handle array2[] = { weak2, weak1 }; 1770 Dart_WeakPersistentHandle array2[] = { weak2, weak1 };
1764 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), 1771 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2),
1765 array2, ARRAY_SIZE(array2))); 1772 array2, ARRAY_SIZE(array2)));
1766 1773
1767 Dart_Handle array3[] = { weak3, weak2 }; 1774 Dart_WeakPersistentHandle array3[] = { weak3, weak2 };
1768 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), 1775 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3),
1769 array3, ARRAY_SIZE(array3))); 1776 array3, ARRAY_SIZE(array3)));
1770 1777
1771 Dart_Handle array4[] = { weak4, weak3 }; 1778 Dart_WeakPersistentHandle array4[] = { weak4, weak3 };
1772 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), 1779 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4),
1773 array4, ARRAY_SIZE(array4))); 1780 array4, ARRAY_SIZE(array4)));
1774 1781
1775 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1782 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1776 } 1783 }
1777 1784
1778 // All weak references should be preserved. 1785 {
1779 EXPECT(!Dart_IsNull(weak1)); 1786 Dart_EnterScope();
1780 EXPECT(!Dart_IsNull(weak2)); 1787 // All weak references should be preserved.
1781 EXPECT(!Dart_IsNull(weak3)); 1788 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
1782 EXPECT(!Dart_IsNull(weak4)); 1789 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1790 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1791 EXPECT(!Dart_IsNull(AsHandle(weak3)));
1792 EXPECT(!Dart_IsNull(AsHandle(weak4)));
1793 Dart_ExitScope();
1794 }
1783 1795
1784 { 1796 {
1785 Dart_Handle array1[] = { weak1, strong }; 1797 Dart_EnterScope();
1798 Dart_WeakPersistentHandle array1[] = { weak1, strong_weak };
1786 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), 1799 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1),
1787 array1, ARRAY_SIZE(array1))); 1800 array1, ARRAY_SIZE(array1)));
1788 1801
1789 Dart_Handle array2[] = { weak2, weak1 }; 1802 Dart_WeakPersistentHandle array2[] = { weak2, weak1 };
1790 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), 1803 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2),
1791 array2, ARRAY_SIZE(array2))); 1804 array2, ARRAY_SIZE(array2)));
1792 1805
1793 Dart_Handle array3[] = { weak2 }; 1806 Dart_WeakPersistentHandle array3[] = { weak2 };
1794 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), 1807 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3),
1795 array3, ARRAY_SIZE(array3))); 1808 array3, ARRAY_SIZE(array3)));
1796 1809
1797 // Strong reference to weak3 to retain weak3 and weak4. 1810 // Strong reference to weak3 to retain weak3 and weak4.
1798 Dart_Handle weak3_strong_ref = Dart_NewPersistentHandle(weak3); 1811 Dart_PersistentHandle weak3_strong_ref = Dart_NewPersistentHandle(AsHandle(w eak3));
1799 EXPECT_VALID(weak3_strong_ref); 1812 EXPECT_VALID(AsHandle(weak3_strong_ref));
1800 1813
1801 Dart_Handle array4[] = { weak4, weak3 }; 1814 Dart_WeakPersistentHandle array4[] = { weak4, weak3 };
1802 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), 1815 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4),
1803 array4, ARRAY_SIZE(array4))); 1816 array4, ARRAY_SIZE(array4)));
1804 1817
1805 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1818 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1806 1819
1807 // Delete strong reference to weak3. 1820 // Delete strong reference to weak3.
1808 Dart_DeletePersistentHandle(weak3_strong_ref); 1821 Dart_DeletePersistentHandle(weak3_strong_ref);
1822 Dart_ExitScope();
1809 } 1823 }
1810 1824
1811 // All weak references should be preserved. 1825 {
1812 EXPECT(!Dart_IsNull(weak1)); 1826 Dart_EnterScope();
1813 EXPECT(!Dart_IsNull(weak2)); 1827 // All weak references should be preserved.
1814 EXPECT(!Dart_IsNull(weak3)); 1828 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
1815 EXPECT(!Dart_IsNull(weak4)); 1829 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1830 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1831 EXPECT(!Dart_IsNull(AsHandle(weak3)));
1832 EXPECT(!Dart_IsNull(AsHandle(weak4)));
1833 Dart_ExitScope();
1834 }
1816 1835
1817 { 1836 {
1818 Dart_Handle array1[] = { weak1, strong }; 1837 Dart_WeakPersistentHandle array1[] = { weak1, strong_weak };
1819 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), 1838 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1),
1820 array1, ARRAY_SIZE(array1))); 1839 array1, ARRAY_SIZE(array1)));
1821 1840
1822 Dart_Handle array2[] = { weak2, weak1 }; 1841 Dart_WeakPersistentHandle array2[] = { weak2, weak1 };
1823 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), 1842 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2),
1824 array2, ARRAY_SIZE(array2))); 1843 array2, ARRAY_SIZE(array2)));
1825 1844
1826 Dart_Handle array3[] = { weak2 }; 1845 Dart_WeakPersistentHandle array3[] = { weak2 };
1827 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), 1846 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3),
1828 array3, ARRAY_SIZE(array3))); 1847 array3, ARRAY_SIZE(array3)));
1829 1848
1830 Dart_Handle array4[] = { weak4, weak3 }; 1849 Dart_WeakPersistentHandle array4[] = { weak4, weak3 };
1831 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), 1850 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4),
1832 array4, ARRAY_SIZE(array4))); 1851 array4, ARRAY_SIZE(array4)));
1833 1852
1834 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1853 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1835 } 1854 }
1836 1855
1837 // Only weak1 and weak2 should be preserved. 1856 {
1838 EXPECT(!Dart_IsNull(weak1)); 1857 Dart_EnterScope();
1839 EXPECT(!Dart_IsNull(weak2)); 1858 // Only weak1 and weak2 should be preserved.
1840 EXPECT(Dart_IsNull(weak3)); 1859 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
1841 EXPECT(Dart_IsNull(weak4)); 1860 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1861 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1862 EXPECT(Dart_IsNull(AsHandle(weak3)));
1863 EXPECT(Dart_IsNull(AsHandle(weak4)));
1864 Dart_ExitScope();
1865 }
1842 1866
1843 { 1867 {
1844 Dart_Handle array1[] = { weak1, strong }; 1868 Dart_WeakPersistentHandle array1[] = { weak1, strong_weak };
1845 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), 1869 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1),
1846 array1, ARRAY_SIZE(array1))); 1870 array1, ARRAY_SIZE(array1)));
1847 1871
1848 // weak3 is cleared so weak2 is unreferenced and should be cleared 1872 // weak3 is cleared so weak2 is unreferenced and should be cleared
1849 Dart_Handle array2[] = { weak2, weak3 }; 1873 Dart_WeakPersistentHandle array2[] = { weak2, weak3 };
1850 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), 1874 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2),
1851 array2, ARRAY_SIZE(array2))); 1875 array2, ARRAY_SIZE(array2)));
1852 1876
1853 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1877 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1854 } 1878 }
1855 1879
1856 // Only weak1 should be preserved, weak3 should not preserve weak2. 1880 {
1857 EXPECT(!Dart_IsNull(weak1)); 1881 Dart_EnterScope();
1858 EXPECT(Dart_IsNull(weak2)); 1882 // Only weak1 should be preserved, weak3 should not preserve weak2.
1859 EXPECT(Dart_IsNull(weak3)); // was cleared, should remain cleared 1883 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
1860 EXPECT(Dart_IsNull(weak4)); // was cleared, should remain cleared 1884 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1885 EXPECT(Dart_IsNull(AsHandle(weak2)));
1886 EXPECT(Dart_IsNull(AsHandle(weak3))); // was cleared, should remain cleared
1887 EXPECT(Dart_IsNull(AsHandle(weak4))); // was cleared, should remain cleared
1888 Dart_ExitScope();
1889 }
1861 1890
1862 { 1891 {
1863 // weak{2,3,4} are cleared and should have no effect on weak1 1892 // weak{2,3,4} are cleared and should have no effect on weak1
1864 Dart_Handle array1[] = { strong, weak2, weak3, weak4 }; 1893 Dart_WeakPersistentHandle array1[] = { strong_weak, weak2, weak3, weak4 };
1865 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), 1894 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1),
1866 array1, ARRAY_SIZE(array1))); 1895 array1, ARRAY_SIZE(array1)));
1867 1896
1868 // weak1 is weakly reachable and should be cleared 1897 // weak1 is weakly reachable and should be cleared
1869 Dart_Handle array2[] = { weak1 }; 1898 Dart_WeakPersistentHandle array2[] = { weak1 };
1870 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), 1899 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2),
1871 array2, ARRAY_SIZE(array2))); 1900 array2, ARRAY_SIZE(array2)));
1872 1901
1873 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 1902 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
1874 } 1903 }
1875 1904
1876 // All weak references should now be cleared. 1905 {
1877 EXPECT(Dart_IsNull(weak1)); 1906 Dart_EnterScope();
1878 EXPECT(Dart_IsNull(weak2)); 1907 // All weak references should now be cleared.
1879 EXPECT(Dart_IsNull(weak3)); 1908 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
1880 EXPECT(Dart_IsNull(weak4)); 1909 EXPECT(Dart_IsNull(AsHandle(weak1)));
1910 EXPECT(Dart_IsNull(AsHandle(weak2)));
1911 EXPECT(Dart_IsNull(AsHandle(weak3)));
1912 EXPECT(Dart_IsNull(AsHandle(weak4)));
1913 Dart_ExitScope();
1914 }
1881 } 1915 }
1882 1916
1883 1917
1884 TEST_CASE(PrologueWeakPersistentHandles) { 1918 TEST_CASE(PrologueWeakPersistentHandles) {
1885 Dart_Handle old_pwph = Dart_Null(); 1919 Dart_WeakPersistentHandle old_pwph = NULL;
1886 EXPECT(Dart_IsNull(old_pwph)); 1920 Dart_WeakPersistentHandle new_pwph = NULL;
1887 Dart_Handle new_pwph = Dart_Null(); 1921
1888 EXPECT(Dart_IsNull(new_pwph));
1889 Dart_EnterScope(); 1922 Dart_EnterScope();
1890 { 1923 {
1891 Isolate* isolate = Isolate::Current(); 1924 Isolate* isolate = Isolate::Current();
1892 DARTSCOPE(isolate); 1925 DARTSCOPE(isolate);
1893 new_pwph = Dart_NewPrologueWeakPersistentHandle( 1926 new_pwph = Dart_NewPrologueWeakPersistentHandle(
1894 Api::NewHandle(isolate, 1927 Api::NewHandle(isolate,
1895 String::New("new space prologue weak", Heap::kNew)), 1928 String::New("new space prologue weak", Heap::kNew)),
1896 NULL, NULL); 1929 NULL, NULL);
1897 EXPECT_VALID(new_pwph); 1930 EXPECT_VALID(AsHandle(new_pwph));
1898 EXPECT(!Dart_IsNull(new_pwph)); 1931 EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
1899 old_pwph = Dart_NewPrologueWeakPersistentHandle( 1932 old_pwph = Dart_NewPrologueWeakPersistentHandle(
1900 Api::NewHandle(isolate, 1933 Api::NewHandle(isolate,
1901 String::New("old space prologue weak", Heap::kOld)), 1934 String::New("old space prologue weak", Heap::kOld)),
1902 NULL, NULL); 1935 NULL, NULL);
1903 EXPECT_VALID(old_pwph); 1936 EXPECT_VALID(AsHandle(old_pwph));
1904 EXPECT(!Dart_IsNull(old_pwph)); 1937 EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
1905 } 1938 }
1906 Dart_ExitScope(); 1939 Dart_ExitScope();
1907 EXPECT_VALID(new_pwph); 1940
1908 EXPECT(!Dart_IsNull(new_pwph)); 1941 {
1909 EXPECT(Dart_IsPrologueWeakPersistentHandle(new_pwph)); 1942 Dart_EnterScope();
1910 EXPECT_VALID(old_pwph); 1943 EXPECT_VALID(AsHandle(new_pwph));
1911 EXPECT(!Dart_IsNull(old_pwph)); 1944 EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
1912 EXPECT(Dart_IsPrologueWeakPersistentHandle(old_pwph)); 1945 EXPECT(Dart_IsPrologueWeakPersistentHandle(new_pwph));
1946 EXPECT_VALID(AsHandle(old_pwph));
1947 EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
1948 EXPECT(Dart_IsPrologueWeakPersistentHandle(old_pwph));
1949 Dart_ExitScope();
1950 }
1951
1913 // Garbage collect new space without invoking API callbacks. 1952 // Garbage collect new space without invoking API callbacks.
1914 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 1953 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1915 1954
1916 // Both prologue weak handles should be preserved. 1955 {
1917 EXPECT(!Dart_IsNull(new_pwph)); 1956 Dart_EnterScope();
1918 EXPECT(!Dart_IsNull(old_pwph)); 1957 // Both prologue weak handles should be preserved.
1958 EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
1959 EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
1960 Dart_ExitScope();
1961 }
1962
1919 // Garbage collect old space without invoking API callbacks. 1963 // Garbage collect old space without invoking API callbacks.
1920 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, 1964 Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
1921 Heap::kIgnoreApiCallbacks); 1965 Heap::kIgnoreApiCallbacks);
1922 // Both prologue weak handles should be preserved. 1966
1923 EXPECT(!Dart_IsNull(new_pwph)); 1967 {
1924 EXPECT(!Dart_IsNull(old_pwph)); 1968 Dart_EnterScope();
1969 // Both prologue weak handles should be preserved.
1970 EXPECT(!Dart_IsNull(AsHandle(new_pwph)));
1971 EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
1972 Dart_ExitScope();
1973 }
1974
1925 // Garbage collect new space invoking API callbacks. 1975 // Garbage collect new space invoking API callbacks.
1926 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); 1976 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
1927 1977
1928 // The prologue weak handle with a new space referent should now be 1978 {
1929 // cleared. The old space referent should be preserved. 1979 Dart_EnterScope();
1930 EXPECT(Dart_IsNull(new_pwph)); 1980 // The prologue weak handle with a new space referent should now be
1931 EXPECT(!Dart_IsNull(old_pwph)); 1981 // cleared. The old space referent should be preserved.
1982 EXPECT(Dart_IsNull(AsHandle(new_pwph)));
1983 EXPECT(!Dart_IsNull(AsHandle(old_pwph)));
1984 Dart_ExitScope();
1985 }
1986
1932 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, 1987 Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
1933 Heap::kInvokeApiCallbacks); 1988 Heap::kInvokeApiCallbacks);
1934 // The prologue weak handle with an old space referent should now be 1989
1935 // cleared. The new space referent should remain cleared. 1990 {
1936 EXPECT(Dart_IsNull(new_pwph)); 1991 Dart_EnterScope();
1937 EXPECT(Dart_IsNull(old_pwph)); 1992 // The prologue weak handle with an old space referent should now be
1993 // cleared. The new space referent should remain cleared.
1994 EXPECT(Dart_IsNull(AsHandle(new_pwph)));
1995 EXPECT(Dart_IsNull(AsHandle(old_pwph)));
1996 Dart_ExitScope();
1997 }
1938 } 1998 }
1939 1999
1940 2000
1941 TEST_CASE(ImplicitReferencesOldSpace) { 2001 TEST_CASE(ImplicitReferencesOldSpace) {
1942 Dart_Handle strong = Dart_Null(); 2002 Dart_PersistentHandle strong = NULL;
1943 EXPECT(Dart_IsNull(strong)); 2003 Dart_WeakPersistentHandle strong_weak = NULL;
1944 2004
1945 Dart_Handle weak1 = Dart_Null(); 2005 Dart_WeakPersistentHandle weak1 = NULL;
1946 EXPECT(Dart_IsNull(weak1)); 2006 Dart_WeakPersistentHandle weak2 = NULL;
1947 2007 Dart_WeakPersistentHandle weak3 = NULL;
1948 Dart_Handle weak2 = Dart_Null();
1949 EXPECT(Dart_IsNull(weak2));
1950
1951 Dart_Handle weak3 = Dart_Null();
1952 EXPECT(Dart_IsNull(weak3));
1953 2008
1954 Dart_EnterScope(); 2009 Dart_EnterScope();
1955 { 2010 {
1956 Isolate* isolate = Isolate::Current(); 2011 Isolate* isolate = Isolate::Current();
1957 DARTSCOPE(isolate); 2012 DARTSCOPE(isolate);
1958 2013
1959 strong = Dart_NewPersistentHandle( 2014 Dart_Handle local = Api::NewHandle(isolate, String::New("strongly reachable" , Heap::kOld));
1960 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kOld))); 2015 strong = Dart_NewPersistentHandle(local);
1961 EXPECT(!Dart_IsNull(strong)); 2016 strong_weak = Dart_NewWeakPersistentHandle(local, NULL, NULL);
1962 EXPECT_VALID(strong); 2017
2018 EXPECT(!Dart_IsNull(AsHandle(strong)));
2019 EXPECT_VALID(AsHandle(strong));
2020 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
2021 EXPECT_VALID(AsHandle(strong_weak));
2022 EXPECT(Dart_IdentityEquals(AsHandle(strong), AsHandle(strong_weak)))
1963 2023
1964 weak1 = Dart_NewWeakPersistentHandle( 2024 weak1 = Dart_NewWeakPersistentHandle(
1965 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)), 2025 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)),
1966 NULL, NULL); 2026 NULL, NULL);
1967 EXPECT(!Dart_IsNull(weak1)); 2027 EXPECT(!Dart_IsNull(AsHandle(weak1)));
1968 EXPECT_VALID(weak1); 2028 EXPECT_VALID(AsHandle(weak1));
1969 2029
1970 weak2 = Dart_NewWeakPersistentHandle( 2030 weak2 = Dart_NewWeakPersistentHandle(
1971 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)), 2031 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)),
1972 NULL, NULL); 2032 NULL, NULL);
1973 EXPECT(!Dart_IsNull(weak2)); 2033 EXPECT(!Dart_IsNull(AsHandle(weak2)));
1974 EXPECT_VALID(weak2); 2034 EXPECT_VALID(AsHandle(weak2));
1975 2035
1976 weak3 = Dart_NewWeakPersistentHandle( 2036 weak3 = Dart_NewWeakPersistentHandle(
1977 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)), 2037 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)),
1978 NULL, NULL); 2038 NULL, NULL);
1979 EXPECT(!Dart_IsNull(weak3)); 2039 EXPECT(!Dart_IsNull(AsHandle(weak3)));
1980 EXPECT_VALID(weak3); 2040 EXPECT_VALID(AsHandle(weak3));
1981 } 2041 }
1982 Dart_ExitScope(); 2042 Dart_ExitScope();
1983 2043
1984 EXPECT_VALID(strong); 2044 {
1985 2045 Dart_EnterScope();
1986 EXPECT_VALID(weak1); 2046 EXPECT_VALID(AsHandle(strong_weak));
1987 EXPECT_VALID(weak2); 2047 EXPECT_VALID(AsHandle(weak1));
1988 EXPECT_VALID(weak3); 2048 EXPECT_VALID(AsHandle(weak2));
2049 EXPECT_VALID(AsHandle(weak3));
2050 Dart_ExitScope();
2051 }
1989 2052
1990 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 2053 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
1991 2054
1992 // New space collection should not affect old space objects 2055 {
1993 EXPECT(!Dart_IsNull(weak1)); 2056 Dart_EnterScope();
1994 EXPECT(!Dart_IsNull(weak2)); 2057 // New space collection should not affect old space objects
1995 EXPECT(!Dart_IsNull(weak3)); 2058 EXPECT_VALID(AsHandle(strong_weak));
2059 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2060 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2061 EXPECT(!Dart_IsNull(AsHandle(weak3)));
2062 Dart_ExitScope();
2063 }
1996 2064
1997 // A strongly referenced key should preserve all the values. 2065 // A strongly referenced key should preserve all the values.
1998 { 2066 {
1999 Dart_Handle keys[] = { strong }; 2067 Dart_WeakPersistentHandle keys[] = { strong_weak };
2000 Dart_Handle values[] = { weak1, weak2, weak3 }; 2068 Dart_WeakPersistentHandle values[] = { weak1, weak2, weak3 };
2001 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), 2069 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys),
2002 values, ARRAY_SIZE(values))); 2070 values, ARRAY_SIZE(values)));
2003 2071
2004 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 2072 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
2005 } 2073 }
2006 2074
2007 // All weak references should be preserved. 2075 {
2008 EXPECT(!Dart_IsNull(weak1)); 2076 Dart_EnterScope();
2009 EXPECT(!Dart_IsNull(weak2)); 2077 // All weak references should be preserved.
2010 EXPECT(!Dart_IsNull(weak3)); 2078 EXPECT_VALID(AsHandle(strong_weak));
2079 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2080 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2081 EXPECT(!Dart_IsNull(AsHandle(weak3)));
2082 Dart_ExitScope();
2083 }
2011 2084
2012 // Key membership does not imply a strong reference. 2085 // Key membership does not imply a strong reference.
2013 { 2086 {
2014 Dart_Handle keys[] = { strong, weak3 }; 2087 Dart_WeakPersistentHandle keys[] = { strong_weak, weak3 };
2015 Dart_Handle values[] = { weak1, weak2 }; 2088 Dart_WeakPersistentHandle values[] = { weak1, weak2 };
2016 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), 2089 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys),
2017 values, ARRAY_SIZE(values))); 2090 values, ARRAY_SIZE(values)));
2018 2091
2019 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 2092 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
2020 } 2093 }
2021 2094
2022 // All weak references except weak3 should be preserved. 2095 {
2023 EXPECT(!Dart_IsNull(weak1)); 2096 Dart_EnterScope();
2024 EXPECT(!Dart_IsNull(weak2)); 2097 // All weak references except weak3 should be preserved.
2025 EXPECT(Dart_IsNull(weak3)); 2098 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2099 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2100 EXPECT(Dart_IsNull(AsHandle(weak3)));
2101 Dart_ExitScope();
2102 }
2026 } 2103 }
2027 2104
2028 2105
2029 TEST_CASE(ImplicitReferencesNewSpace) { 2106 TEST_CASE(ImplicitReferencesNewSpace) {
2030 Dart_Handle strong = Dart_Null(); 2107 Dart_PersistentHandle strong = NULL;
2031 EXPECT(Dart_IsNull(strong)); 2108 Dart_WeakPersistentHandle strong_weak = NULL;
2032 2109
2033 Dart_Handle weak1 = Dart_Null(); 2110 Dart_WeakPersistentHandle weak1 = NULL;
2034 EXPECT(Dart_IsNull(weak1)); 2111 Dart_WeakPersistentHandle weak2 = NULL;
2035 2112 Dart_WeakPersistentHandle weak3 = NULL;
2036 Dart_Handle weak2 = Dart_Null();
2037 EXPECT(Dart_IsNull(weak2));
2038
2039 Dart_Handle weak3 = Dart_Null();
2040 EXPECT(Dart_IsNull(weak3));
2041 2113
2042 Dart_EnterScope(); 2114 Dart_EnterScope();
2043 { 2115 {
2044 Isolate* isolate = Isolate::Current(); 2116 Isolate* isolate = Isolate::Current();
2045 DARTSCOPE(isolate); 2117 DARTSCOPE(isolate);
2046 2118
2047 strong = Dart_NewPersistentHandle( 2119 Dart_Handle local = Api::NewHandle(isolate, String::New("strongly reachable" , Heap::kOld));
2048 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kNew))); 2120 strong = Dart_NewPersistentHandle(local);
2049 EXPECT(!Dart_IsNull(strong)); 2121 strong_weak = Dart_NewWeakPersistentHandle(local, NULL, NULL);
2050 EXPECT_VALID(strong); 2122
2123 EXPECT(!Dart_IsNull(AsHandle(strong)));
2124 EXPECT_VALID(AsHandle(strong));
2125 EXPECT(!Dart_IsNull(AsHandle(strong_weak)));
2126 EXPECT_VALID(AsHandle(strong_weak));
2127 EXPECT(Dart_IdentityEquals(AsHandle(strong), AsHandle(strong_weak)))
2051 2128
2052 weak1 = Dart_NewWeakPersistentHandle( 2129 weak1 = Dart_NewWeakPersistentHandle(
2053 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kNew)), 2130 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kNew)),
2054 NULL, NULL); 2131 NULL, NULL);
2055 EXPECT(!Dart_IsNull(weak1)); 2132 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2056 EXPECT_VALID(weak1); 2133 EXPECT_VALID(AsHandle(weak1));
2057 2134
2058 weak2 = Dart_NewWeakPersistentHandle( 2135 weak2 = Dart_NewWeakPersistentHandle(
2059 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kNew)), 2136 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kNew)),
2060 NULL, NULL); 2137 NULL, NULL);
2061 EXPECT(!Dart_IsNull(weak2)); 2138 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2062 EXPECT_VALID(weak2); 2139 EXPECT_VALID(AsHandle(weak2));
2063 2140
2064 weak3 = Dart_NewWeakPersistentHandle( 2141 weak3 = Dart_NewWeakPersistentHandle(
2065 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kNew)), 2142 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kNew)),
2066 NULL, NULL); 2143 NULL, NULL);
2067 EXPECT(!Dart_IsNull(weak3)); 2144 EXPECT(!Dart_IsNull(AsHandle(weak3)));
2068 EXPECT_VALID(weak3); 2145 EXPECT_VALID(AsHandle(weak3));
2069 } 2146 }
2070 Dart_ExitScope(); 2147 Dart_ExitScope();
2071 2148
2072 EXPECT_VALID(strong); 2149 {
2073 2150 Dart_EnterScope();
2074 EXPECT_VALID(weak1); 2151 EXPECT_VALID(AsHandle(strong_weak));
2075 EXPECT_VALID(weak2); 2152 EXPECT_VALID(AsHandle(weak1));
2076 EXPECT_VALID(weak3); 2153 EXPECT_VALID(AsHandle(weak2));
2154 EXPECT_VALID(AsHandle(weak3));
2155 Dart_ExitScope();
2156 }
2077 2157
2078 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); 2158 Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
2079 2159
2080 // Old space collection should not affect old space objects. 2160 {
2081 EXPECT(!Dart_IsNull(weak1)); 2161 Dart_EnterScope();
2082 EXPECT(!Dart_IsNull(weak2)); 2162 // Old space collection should not affect old space objects.
2083 EXPECT(!Dart_IsNull(weak3)); 2163 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2164 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2165 EXPECT(!Dart_IsNull(AsHandle(weak3)));
2166 Dart_ExitScope();
2167 }
2084 2168
2085 // A strongly referenced key should preserve all the values. 2169 // A strongly referenced key should preserve all the values.
2086 { 2170 {
2087 Dart_Handle keys[] = { strong }; 2171 Dart_WeakPersistentHandle keys[] = { strong_weak };
2088 Dart_Handle values[] = { weak1, weak2, weak3 }; 2172 Dart_WeakPersistentHandle values[] = { weak1, weak2, weak3 };
2089 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), 2173 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys),
2090 values, ARRAY_SIZE(values))); 2174 values, ARRAY_SIZE(values)));
2091 2175
2092 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); 2176 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
2093 } 2177 }
2094 2178
2095 // All weak references should be preserved. 2179 {
2096 EXPECT(!Dart_IsNull(weak1)); 2180 Dart_EnterScope();
2097 EXPECT(!Dart_IsNull(weak2)); 2181 // All weak references should be preserved.
2098 EXPECT(!Dart_IsNull(weak3)); 2182 EXPECT(!Dart_IsNull(AsHandle(weak1)));
2183 EXPECT(!Dart_IsNull(AsHandle(weak2)));
2184 EXPECT(!Dart_IsNull(AsHandle(weak3)));
2185 Dart_ExitScope();
2186 }
2099 2187
2100 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); 2188 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
2101 2189
2102 // No weak references should be preserved. 2190 {
2103 EXPECT(Dart_IsNull(weak1)); 2191 Dart_EnterScope();
2104 EXPECT(Dart_IsNull(weak2)); 2192 // No weak references should be preserved.
2105 EXPECT(Dart_IsNull(weak3)); 2193 EXPECT(Dart_IsNull(AsHandle(weak1)));
2194 EXPECT(Dart_IsNull(AsHandle(weak2)));
2195 EXPECT(Dart_IsNull(AsHandle(weak3)));
2196 Dart_ExitScope();
2197 }
2106 } 2198 }
2107 2199
2108 2200
2109 static int global_prologue_callback_status; 2201 static int global_prologue_callback_status;
2110 2202
2111 2203
2112 static void PrologueCallbackTimes2() { 2204 static void PrologueCallbackTimes2() {
2113 global_prologue_callback_status *= 2; 2205 global_prologue_callback_status *= 2;
2114 } 2206 }
2115 2207
(...skipping 5673 matching lines...) Expand 10 before | Expand all | Expand 10 after
7789 NewString("main"), 7881 NewString("main"),
7790 0, 7882 0,
7791 NULL); 7883 NULL);
7792 int64_t value = 0; 7884 int64_t value = 0;
7793 result = Dart_IntegerToInt64(result, &value); 7885 result = Dart_IntegerToInt64(result, &value);
7794 EXPECT_VALID(result); 7886 EXPECT_VALID(result);
7795 EXPECT_EQ(8, value); 7887 EXPECT_EQ(8, value);
7796 } 7888 }
7797 7889
7798 } // namespace dart 7890 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698