| 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 |