| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
| 7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
| (...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 EXPECT_VALID(weak_ref); | 1364 EXPECT_VALID(weak_ref); |
| 1365 EXPECT(*peer == 0); | 1365 EXPECT(*peer == 0); |
| 1366 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1366 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1367 EXPECT(*peer == 0); | 1367 EXPECT(*peer == 0); |
| 1368 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 1368 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1369 EXPECT(*peer == 42); | 1369 EXPECT(*peer == 42); |
| 1370 delete peer; | 1370 delete peer; |
| 1371 Dart_DeletePersistentHandle(weak_ref); | 1371 Dart_DeletePersistentHandle(weak_ref); |
| 1372 } | 1372 } |
| 1373 | 1373 |
| 1374 |
| 1375 TEST_CASE(ObjectGroups) { |
| 1376 Dart_Handle strong = Dart_Null(); |
| 1377 EXPECT(Dart_IsNull(strong)); |
| 1378 |
| 1379 Dart_Handle weak1 = Dart_Null(); |
| 1380 EXPECT(Dart_IsNull(weak1)); |
| 1381 |
| 1382 Dart_Handle weak2 = Dart_Null(); |
| 1383 EXPECT(Dart_IsNull(weak2)); |
| 1384 |
| 1385 Dart_Handle weak3 = Dart_Null(); |
| 1386 EXPECT(Dart_IsNull(weak3)); |
| 1387 |
| 1388 Dart_Handle weak4 = Dart_Null(); |
| 1389 EXPECT(Dart_IsNull(weak4)); |
| 1390 |
| 1391 Dart_EnterScope(); |
| 1392 { |
| 1393 DARTSCOPE(Isolate::Current()); |
| 1394 String& str = String::Handle(); |
| 1395 |
| 1396 str ^= String::New("strongly reachable", Heap::kOld); |
| 1397 strong = Dart_NewPersistentHandle(Api::NewLocalHandle(str)); |
| 1398 EXPECT_VALID(strong); |
| 1399 EXPECT(!Dart_IsNull(strong)); |
| 1400 |
| 1401 str ^= String::New("weakly reachable 1", Heap::kOld); |
| 1402 weak1 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1403 EXPECT_VALID(weak1); |
| 1404 EXPECT(!Dart_IsNull(weak1)); |
| 1405 |
| 1406 str ^= String::New("weakly reachable 2", Heap::kOld); |
| 1407 weak2 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1408 EXPECT_VALID(weak2); |
| 1409 EXPECT(!Dart_IsNull(weak2)); |
| 1410 |
| 1411 str ^= String::New("weakly reachable 3", Heap::kOld); |
| 1412 weak3 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1413 EXPECT_VALID(weak3); |
| 1414 EXPECT(!Dart_IsNull(weak3)); |
| 1415 |
| 1416 str ^= String::New("weakly reachable 4", Heap::kOld); |
| 1417 weak4 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1418 EXPECT_VALID(weak4); |
| 1419 EXPECT(!Dart_IsNull(weak4)); |
| 1420 } |
| 1421 Dart_ExitScope(); |
| 1422 |
| 1423 EXPECT_VALID(strong); |
| 1424 |
| 1425 EXPECT_VALID(weak1); |
| 1426 EXPECT_VALID(weak2); |
| 1427 EXPECT_VALID(weak3); |
| 1428 EXPECT_VALID(weak4); |
| 1429 |
| 1430 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1431 |
| 1432 // New space collection should not affect old space objects |
| 1433 EXPECT(!Dart_IsNull(weak1)); |
| 1434 EXPECT(!Dart_IsNull(weak2)); |
| 1435 EXPECT(!Dart_IsNull(weak3)); |
| 1436 EXPECT(!Dart_IsNull(weak4)); |
| 1437 |
| 1438 { |
| 1439 Dart_Handle array1[] = { weak1, strong }; |
| 1440 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), |
| 1441 array1, ARRAY_SIZE(array1))); |
| 1442 |
| 1443 Dart_Handle array2[] = { weak2, weak1 }; |
| 1444 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), |
| 1445 array2, ARRAY_SIZE(array2))); |
| 1446 |
| 1447 Dart_Handle array3[] = { weak3, weak2 }; |
| 1448 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), |
| 1449 array3, ARRAY_SIZE(array3))); |
| 1450 |
| 1451 Dart_Handle array4[] = { weak4, weak3 }; |
| 1452 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), |
| 1453 array4, ARRAY_SIZE(array4))); |
| 1454 |
| 1455 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1456 } |
| 1457 |
| 1458 // All weak references should be preserved. |
| 1459 EXPECT(!Dart_IsNull(weak1)); |
| 1460 EXPECT(!Dart_IsNull(weak2)); |
| 1461 EXPECT(!Dart_IsNull(weak3)); |
| 1462 EXPECT(!Dart_IsNull(weak4)); |
| 1463 |
| 1464 { |
| 1465 Dart_Handle array1[] = { weak1, strong }; |
| 1466 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), |
| 1467 array1, ARRAY_SIZE(array1))); |
| 1468 |
| 1469 Dart_Handle array2[] = { weak2, weak1 }; |
| 1470 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), |
| 1471 array2, ARRAY_SIZE(array2))); |
| 1472 |
| 1473 Dart_Handle array3[] = { weak2 }; |
| 1474 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), |
| 1475 array3, ARRAY_SIZE(array3))); |
| 1476 |
| 1477 // Strong reference to weak3 to retain weak3 and weak4. |
| 1478 Dart_Handle weak3_strong_ref = Dart_NewPersistentHandle(weak3); |
| 1479 EXPECT_VALID(weak3_strong_ref); |
| 1480 |
| 1481 Dart_Handle array4[] = { weak4, weak3 }; |
| 1482 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), |
| 1483 array4, ARRAY_SIZE(array4))); |
| 1484 |
| 1485 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1486 |
| 1487 // Delete strong reference to weak3. |
| 1488 Dart_DeletePersistentHandle(weak3_strong_ref); |
| 1489 } |
| 1490 |
| 1491 // All weak references should be preserved. |
| 1492 EXPECT(!Dart_IsNull(weak1)); |
| 1493 EXPECT(!Dart_IsNull(weak2)); |
| 1494 EXPECT(!Dart_IsNull(weak3)); |
| 1495 EXPECT(!Dart_IsNull(weak4)); |
| 1496 |
| 1497 { |
| 1498 Dart_Handle array1[] = { weak1, strong }; |
| 1499 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), |
| 1500 array1, ARRAY_SIZE(array1))); |
| 1501 |
| 1502 Dart_Handle array2[] = { weak2, weak1 }; |
| 1503 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), |
| 1504 array2, ARRAY_SIZE(array2))); |
| 1505 |
| 1506 Dart_Handle array3[] = { weak2 }; |
| 1507 EXPECT_VALID(Dart_NewWeakReferenceSet(array3, ARRAY_SIZE(array3), |
| 1508 array3, ARRAY_SIZE(array3))); |
| 1509 |
| 1510 Dart_Handle array4[] = { weak4, weak3 }; |
| 1511 EXPECT_VALID(Dart_NewWeakReferenceSet(array4, ARRAY_SIZE(array4), |
| 1512 array4, ARRAY_SIZE(array4))); |
| 1513 |
| 1514 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1515 } |
| 1516 |
| 1517 // Only weak1 and weak2 should be preserved. |
| 1518 EXPECT(!Dart_IsNull(weak1)); |
| 1519 EXPECT(!Dart_IsNull(weak2)); |
| 1520 EXPECT(Dart_IsNull(weak3)); |
| 1521 EXPECT(Dart_IsNull(weak4)); |
| 1522 |
| 1523 { |
| 1524 Dart_Handle array1[] = { weak1, strong }; |
| 1525 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), |
| 1526 array1, ARRAY_SIZE(array1))); |
| 1527 |
| 1528 // weak3 is cleared so weak2 is unreferenced and should be cleared |
| 1529 Dart_Handle array2[] = { weak2, weak3 }; |
| 1530 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), |
| 1531 array2, ARRAY_SIZE(array2))); |
| 1532 |
| 1533 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1534 } |
| 1535 |
| 1536 // Only weak1 should be preserved, weak3 should not preserve weak2. |
| 1537 EXPECT(!Dart_IsNull(weak1)); |
| 1538 EXPECT(Dart_IsNull(weak2)); |
| 1539 EXPECT(Dart_IsNull(weak3)); // was cleared, should remain cleared |
| 1540 EXPECT(Dart_IsNull(weak4)); // was cleared, should remain cleared |
| 1541 |
| 1542 { |
| 1543 // weak{2,3,4} are cleared and should have no effect on weak1 |
| 1544 Dart_Handle array1[] = { strong, weak2, weak3, weak4 }; |
| 1545 EXPECT_VALID(Dart_NewWeakReferenceSet(array1, ARRAY_SIZE(array1), |
| 1546 array1, ARRAY_SIZE(array1))); |
| 1547 |
| 1548 // weak1 is weakly reachable and should be cleared |
| 1549 Dart_Handle array2[] = { weak1 }; |
| 1550 EXPECT_VALID(Dart_NewWeakReferenceSet(array2, ARRAY_SIZE(array2), |
| 1551 array2, ARRAY_SIZE(array2))); |
| 1552 |
| 1553 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1554 } |
| 1555 |
| 1556 // All weak references should now be cleared. |
| 1557 EXPECT(Dart_IsNull(weak1)); |
| 1558 EXPECT(Dart_IsNull(weak2)); |
| 1559 EXPECT(Dart_IsNull(weak3)); |
| 1560 EXPECT(Dart_IsNull(weak4)); |
| 1561 } |
| 1562 |
| 1563 |
| 1564 TEST_CASE(ImplicitReferences) { |
| 1565 Dart_Handle strong = Dart_Null(); |
| 1566 EXPECT(Dart_IsNull(strong)); |
| 1567 |
| 1568 Dart_Handle weak1 = Dart_Null(); |
| 1569 EXPECT(Dart_IsNull(weak1)); |
| 1570 |
| 1571 Dart_Handle weak2 = Dart_Null(); |
| 1572 EXPECT(Dart_IsNull(weak2)); |
| 1573 |
| 1574 Dart_Handle weak3 = Dart_Null(); |
| 1575 EXPECT(Dart_IsNull(weak3)); |
| 1576 |
| 1577 |
| 1578 Dart_EnterScope(); |
| 1579 { |
| 1580 DARTSCOPE(Isolate::Current()); |
| 1581 String& str = String::Handle(); |
| 1582 |
| 1583 str ^= String::New("strongly reachable", Heap::kOld); |
| 1584 strong = Dart_NewPersistentHandle(Api::NewLocalHandle(str)); |
| 1585 EXPECT(!Dart_IsNull(strong)); |
| 1586 EXPECT_VALID(strong); |
| 1587 |
| 1588 str ^= String::New("weakly reachable 1", Heap::kOld); |
| 1589 weak1 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1590 EXPECT(!Dart_IsNull(weak1)); |
| 1591 EXPECT_VALID(weak1); |
| 1592 |
| 1593 str ^= String::New("weakly reachable 2", Heap::kOld); |
| 1594 weak2 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1595 EXPECT(!Dart_IsNull(weak2)); |
| 1596 EXPECT_VALID(weak2); |
| 1597 |
| 1598 str ^= String::New("weakly reachable 3", Heap::kOld); |
| 1599 weak3 = Dart_NewWeakPersistentHandle(Api::NewLocalHandle(str), NULL, NULL); |
| 1600 EXPECT(!Dart_IsNull(weak3)); |
| 1601 EXPECT_VALID(weak3); |
| 1602 } |
| 1603 Dart_ExitScope(); |
| 1604 |
| 1605 EXPECT_VALID(strong); |
| 1606 |
| 1607 EXPECT_VALID(weak1); |
| 1608 EXPECT_VALID(weak2); |
| 1609 EXPECT_VALID(weak3); |
| 1610 |
| 1611 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1612 |
| 1613 // New space collection should not affect old space objects |
| 1614 EXPECT(!Dart_IsNull(weak1)); |
| 1615 EXPECT(!Dart_IsNull(weak2)); |
| 1616 EXPECT(!Dart_IsNull(weak3)); |
| 1617 |
| 1618 // A strongly referenced key should preserve all the values. |
| 1619 { |
| 1620 Dart_Handle keys[] = { strong }; |
| 1621 Dart_Handle values[] = { weak1, weak2, weak3 }; |
| 1622 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), |
| 1623 values, ARRAY_SIZE(values))); |
| 1624 |
| 1625 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1626 } |
| 1627 |
| 1628 // All weak references should be preserved. |
| 1629 EXPECT(!Dart_IsNull(weak1)); |
| 1630 EXPECT(!Dart_IsNull(weak2)); |
| 1631 EXPECT(!Dart_IsNull(weak3)); |
| 1632 |
| 1633 // Key membership does not imply a strong reference. |
| 1634 { |
| 1635 Dart_Handle keys[] = { strong, weak3 }; |
| 1636 Dart_Handle values[] = { weak1, weak2 }; |
| 1637 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), |
| 1638 values, ARRAY_SIZE(values))); |
| 1639 |
| 1640 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1641 } |
| 1642 |
| 1643 // All weak references except weak3 should be preserved. |
| 1644 EXPECT(!Dart_IsNull(weak1)); |
| 1645 EXPECT(!Dart_IsNull(weak2)); |
| 1646 EXPECT(Dart_IsNull(weak3)); |
| 1647 } |
| 1648 |
| 1374 #endif | 1649 #endif |
| 1375 | 1650 |
| 1376 | 1651 |
| 1377 // Unit test for creating multiple scopes and local handles within them. | 1652 // Unit test for creating multiple scopes and local handles within them. |
| 1378 // Ensure that the local handles get all cleaned out when exiting the | 1653 // Ensure that the local handles get all cleaned out when exiting the |
| 1379 // scope. | 1654 // scope. |
| 1380 UNIT_TEST_CASE(LocalHandles) { | 1655 UNIT_TEST_CASE(LocalHandles) { |
| 1381 TestCase::CreateTestIsolate(); | 1656 TestCase::CreateTestIsolate(); |
| 1382 Isolate* isolate = Isolate::Current(); | 1657 Isolate* isolate = Isolate::Current(); |
| 1383 EXPECT(isolate != NULL); | 1658 EXPECT(isolate != NULL); |
| (...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3733 // We should have received the expected number of interrupts. | 4008 // We should have received the expected number of interrupts. |
| 3734 EXPECT_EQ(kInterruptCount, interrupt_count); | 4009 EXPECT_EQ(kInterruptCount, interrupt_count); |
| 3735 | 4010 |
| 3736 // Give the spawned thread enough time to properly exit. | 4011 // Give the spawned thread enough time to properly exit. |
| 3737 Isolate::SetInterruptCallback(saved); | 4012 Isolate::SetInterruptCallback(saved); |
| 3738 } | 4013 } |
| 3739 | 4014 |
| 3740 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 4015 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). |
| 3741 | 4016 |
| 3742 } // namespace dart | 4017 } // namespace dart |
| OLD | NEW |