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