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