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