| 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 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1611 EXPECT(!Dart_IsNull(old_pwph)); | 1611 EXPECT(!Dart_IsNull(old_pwph)); |
| 1612 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | 1612 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 1613 Heap::kInvokeApiCallbacks); | 1613 Heap::kInvokeApiCallbacks); |
| 1614 // The prologue weak handle with an old space referent should now be | 1614 // The prologue weak handle with an old space referent should now be |
| 1615 // cleared. The new space referent should remain cleared. | 1615 // cleared. The new space referent should remain cleared. |
| 1616 EXPECT(Dart_IsNull(new_pwph)); | 1616 EXPECT(Dart_IsNull(new_pwph)); |
| 1617 EXPECT(Dart_IsNull(old_pwph)); | 1617 EXPECT(Dart_IsNull(old_pwph)); |
| 1618 } | 1618 } |
| 1619 | 1619 |
| 1620 | 1620 |
| 1621 TEST_CASE(ImplicitReferences) { | 1621 TEST_CASE(ImplicitReferencesOldSpace) { |
| 1622 Dart_Handle strong = Dart_Null(); | 1622 Dart_Handle strong = Dart_Null(); |
| 1623 EXPECT(Dart_IsNull(strong)); | 1623 EXPECT(Dart_IsNull(strong)); |
| 1624 | 1624 |
| 1625 Dart_Handle weak1 = Dart_Null(); | 1625 Dart_Handle weak1 = Dart_Null(); |
| 1626 EXPECT(Dart_IsNull(weak1)); | 1626 EXPECT(Dart_IsNull(weak1)); |
| 1627 | 1627 |
| 1628 Dart_Handle weak2 = Dart_Null(); | 1628 Dart_Handle weak2 = Dart_Null(); |
| 1629 EXPECT(Dart_IsNull(weak2)); | 1629 EXPECT(Dart_IsNull(weak2)); |
| 1630 | 1630 |
| 1631 Dart_Handle weak3 = Dart_Null(); | 1631 Dart_Handle weak3 = Dart_Null(); |
| 1632 EXPECT(Dart_IsNull(weak3)); | 1632 EXPECT(Dart_IsNull(weak3)); |
| 1633 | 1633 |
| 1634 | |
| 1635 Dart_EnterScope(); | 1634 Dart_EnterScope(); |
| 1636 { | 1635 { |
| 1637 Isolate* isolate = Isolate::Current(); | 1636 Isolate* isolate = Isolate::Current(); |
| 1638 DARTSCOPE(isolate); | 1637 DARTSCOPE(isolate); |
| 1639 | 1638 |
| 1640 strong = Dart_NewPersistentHandle( | 1639 strong = Dart_NewPersistentHandle( |
| 1641 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kOld))); | 1640 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kOld))); |
| 1642 EXPECT(!Dart_IsNull(strong)); | 1641 EXPECT(!Dart_IsNull(strong)); |
| 1643 EXPECT_VALID(strong); | 1642 EXPECT_VALID(strong); |
| 1644 | 1643 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1699 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1701 } | 1700 } |
| 1702 | 1701 |
| 1703 // All weak references except weak3 should be preserved. | 1702 // All weak references except weak3 should be preserved. |
| 1704 EXPECT(!Dart_IsNull(weak1)); | 1703 EXPECT(!Dart_IsNull(weak1)); |
| 1705 EXPECT(!Dart_IsNull(weak2)); | 1704 EXPECT(!Dart_IsNull(weak2)); |
| 1706 EXPECT(Dart_IsNull(weak3)); | 1705 EXPECT(Dart_IsNull(weak3)); |
| 1707 } | 1706 } |
| 1708 | 1707 |
| 1709 | 1708 |
| 1709 TEST_CASE(ImplicitReferencesNewSpace) { |
| 1710 Dart_Handle strong = Dart_Null(); |
| 1711 EXPECT(Dart_IsNull(strong)); |
| 1712 |
| 1713 Dart_Handle weak1 = Dart_Null(); |
| 1714 EXPECT(Dart_IsNull(weak1)); |
| 1715 |
| 1716 Dart_Handle weak2 = Dart_Null(); |
| 1717 EXPECT(Dart_IsNull(weak2)); |
| 1718 |
| 1719 Dart_Handle weak3 = Dart_Null(); |
| 1720 EXPECT(Dart_IsNull(weak3)); |
| 1721 |
| 1722 Dart_EnterScope(); |
| 1723 { |
| 1724 Isolate* isolate = Isolate::Current(); |
| 1725 DARTSCOPE(isolate); |
| 1726 |
| 1727 strong = Dart_NewPersistentHandle( |
| 1728 Api::NewHandle(isolate, String::New("strongly reachable", Heap::kNew))); |
| 1729 EXPECT(!Dart_IsNull(strong)); |
| 1730 EXPECT_VALID(strong); |
| 1731 |
| 1732 weak1 = Dart_NewWeakPersistentHandle( |
| 1733 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kNew)), |
| 1734 NULL, NULL); |
| 1735 EXPECT(!Dart_IsNull(weak1)); |
| 1736 EXPECT_VALID(weak1); |
| 1737 |
| 1738 weak2 = Dart_NewWeakPersistentHandle( |
| 1739 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kNew)), |
| 1740 NULL, NULL); |
| 1741 EXPECT(!Dart_IsNull(weak2)); |
| 1742 EXPECT_VALID(weak2); |
| 1743 |
| 1744 weak3 = Dart_NewWeakPersistentHandle( |
| 1745 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kNew)), |
| 1746 NULL, NULL); |
| 1747 EXPECT(!Dart_IsNull(weak3)); |
| 1748 EXPECT_VALID(weak3); |
| 1749 } |
| 1750 Dart_ExitScope(); |
| 1751 |
| 1752 EXPECT_VALID(strong); |
| 1753 |
| 1754 EXPECT_VALID(weak1); |
| 1755 EXPECT_VALID(weak2); |
| 1756 EXPECT_VALID(weak3); |
| 1757 |
| 1758 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1759 |
| 1760 // Old space collection should not affect old space objects. |
| 1761 EXPECT(!Dart_IsNull(weak1)); |
| 1762 EXPECT(!Dart_IsNull(weak2)); |
| 1763 EXPECT(!Dart_IsNull(weak3)); |
| 1764 |
| 1765 // A strongly referenced key should preserve all the values. |
| 1766 { |
| 1767 Dart_Handle keys[] = { strong }; |
| 1768 Dart_Handle values[] = { weak1, weak2, weak3 }; |
| 1769 EXPECT_VALID(Dart_NewWeakReferenceSet(keys, ARRAY_SIZE(keys), |
| 1770 values, ARRAY_SIZE(values))); |
| 1771 |
| 1772 Isolate::Current()->heap()->CollectGarbage(Heap::kNew, |
| 1773 Heap::kInvokeApiCallbacks); |
| 1774 } |
| 1775 |
| 1776 // All weak references should be preserved. |
| 1777 EXPECT(!Dart_IsNull(weak1)); |
| 1778 EXPECT(!Dart_IsNull(weak2)); |
| 1779 EXPECT(!Dart_IsNull(weak3)); |
| 1780 |
| 1781 Isolate::Current()->heap()->CollectGarbage(Heap::kNew, |
| 1782 Heap::kIgnoreApiCallbacks); |
| 1783 |
| 1784 // No weak references should be preserved. |
| 1785 EXPECT(Dart_IsNull(weak1)); |
| 1786 EXPECT(Dart_IsNull(weak2)); |
| 1787 EXPECT(Dart_IsNull(weak3)); |
| 1788 } |
| 1789 |
| 1790 |
| 1710 static int global_prologue_callback_status; | 1791 static int global_prologue_callback_status; |
| 1711 | 1792 |
| 1712 | 1793 |
| 1713 static void PrologueCallbackTimes2() { | 1794 static void PrologueCallbackTimes2() { |
| 1714 global_prologue_callback_status *= 2; | 1795 global_prologue_callback_status *= 2; |
| 1715 } | 1796 } |
| 1716 | 1797 |
| 1717 | 1798 |
| 1718 static void PrologueCallbackTimes3() { | 1799 static void PrologueCallbackTimes3() { |
| 1719 global_prologue_callback_status *= 3; | 1800 global_prologue_callback_status *= 3; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1808 // Remove epilogue callbacks again. This is an error. | 1889 // Remove epilogue callbacks again. This is an error. |
| 1809 EXPECT(Dart_IsError(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes4))); | 1890 EXPECT(Dart_IsError(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes4))); |
| 1810 EXPECT(Dart_IsError(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes5))); | 1891 EXPECT(Dart_IsError(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes5))); |
| 1811 } | 1892 } |
| 1812 | 1893 |
| 1813 | 1894 |
| 1814 TEST_CASE(SingleGarbageCollectionCallback) { | 1895 TEST_CASE(SingleGarbageCollectionCallback) { |
| 1815 // Add a prologue callback. | 1896 // Add a prologue callback. |
| 1816 EXPECT_VALID(Dart_AddGcPrologueCallback(&PrologueCallbackTimes2)); | 1897 EXPECT_VALID(Dart_AddGcPrologueCallback(&PrologueCallbackTimes2)); |
| 1817 | 1898 |
| 1818 // Garbage collect new space. This should not invoke the prologue | 1899 // Garbage collect new space ignoring callbacks. This should not |
| 1819 // callback. No status values should change. | 1900 // invoke the prologue callback. No status values should change. |
| 1820 global_prologue_callback_status = 3; | 1901 global_prologue_callback_status = 3; |
| 1821 global_epilogue_callback_status = 7; | 1902 global_epilogue_callback_status = 7; |
| 1822 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 1903 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1823 EXPECT_EQ(3, global_prologue_callback_status); | 1904 EXPECT_EQ(3, global_prologue_callback_status); |
| 1824 EXPECT_EQ(7, global_epilogue_callback_status); | 1905 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1825 | 1906 |
| 1907 // Garbage collect new space invoking callbacks. This should |
| 1908 // invoke the prologue callback. No status values should change. |
| 1909 global_prologue_callback_status = 3; |
| 1910 global_epilogue_callback_status = 7; |
| 1911 Isolate::Current()->heap()->CollectGarbage(Heap::kNew, |
| 1912 Heap::kInvokeApiCallbacks); |
| 1913 EXPECT_EQ(6, global_prologue_callback_status); |
| 1914 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1915 |
| 1916 // Garbage collect old space ignoring callbacks. This should invoke |
| 1917 // the prologue callback. The prologue status value should change. |
| 1918 global_prologue_callback_status = 3; |
| 1919 global_epilogue_callback_status = 7; |
| 1920 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 1921 Heap::kIgnoreApiCallbacks); |
| 1922 EXPECT_EQ(3, global_prologue_callback_status); |
| 1923 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1924 |
| 1826 // Garbage collect old space. This should invoke the prologue | 1925 // Garbage collect old space. This should invoke the prologue |
| 1827 // callback. The prologue status value should change. | 1926 // callback. The prologue status value should change. |
| 1927 global_prologue_callback_status = 3; |
| 1928 global_epilogue_callback_status = 7; |
| 1828 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1929 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1829 EXPECT_EQ(6, global_prologue_callback_status); | 1930 EXPECT_EQ(6, global_prologue_callback_status); |
| 1830 EXPECT_EQ(7, global_epilogue_callback_status); | 1931 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1831 | 1932 |
| 1832 // Garbage collect old space again. Callbacks are persistent so the | 1933 // Garbage collect old space again. Callbacks are persistent so the |
| 1833 // prolog status value should change again. | 1934 // prolog status value should change again. |
| 1834 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1935 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1835 EXPECT_EQ(12, global_prologue_callback_status); | 1936 EXPECT_EQ(12, global_prologue_callback_status); |
| 1836 EXPECT_EQ(7, global_epilogue_callback_status); | 1937 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1837 | 1938 |
| 1838 // Add an epilogue callback. | 1939 // Add an epilogue callback. |
| 1839 EXPECT_VALID(Dart_AddGcEpilogueCallback(&EpilogueCallbackTimes4)); | 1940 EXPECT_VALID(Dart_AddGcEpilogueCallback(&EpilogueCallbackTimes4)); |
| 1840 | 1941 |
| 1841 // Garbage collect new space. This should not invoke the prologue | 1942 // Garbage collect new space. This should not invoke the prologue |
| 1842 // or the epilogue callback. No status values should change. | 1943 // or the epilogue callback. No status values should change. |
| 1843 global_prologue_callback_status = 3; | 1944 global_prologue_callback_status = 3; |
| 1844 global_epilogue_callback_status = 7; | 1945 global_epilogue_callback_status = 7; |
| 1845 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 1946 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1846 EXPECT_EQ(3, global_prologue_callback_status); | 1947 EXPECT_EQ(3, global_prologue_callback_status); |
| 1847 EXPECT_EQ(7, global_epilogue_callback_status); | 1948 EXPECT_EQ(7, global_epilogue_callback_status); |
| 1848 | 1949 |
| 1950 // Garbage collect new space. This should invoke the prologue and |
| 1951 // the epilogue callback. The prologue and epilogue status values |
| 1952 // should change. |
| 1953 Isolate::Current()->heap()->CollectGarbage(Heap::kNew, |
| 1954 Heap::kInvokeApiCallbacks); |
| 1955 EXPECT_EQ(6, global_prologue_callback_status); |
| 1956 EXPECT_EQ(28, global_epilogue_callback_status); |
| 1957 |
| 1849 // Garbage collect old space. This should invoke the prologue and | 1958 // Garbage collect old space. This should invoke the prologue and |
| 1850 // the epilogue callbacks. The prologue and epilogue status values | 1959 // the epilogue callbacks. The prologue and epilogue status values |
| 1851 // should change. | 1960 // should change. |
| 1961 global_prologue_callback_status = 3; |
| 1962 global_epilogue_callback_status = 7; |
| 1852 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1963 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1853 EXPECT_EQ(6, global_prologue_callback_status); | 1964 EXPECT_EQ(6, global_prologue_callback_status); |
| 1854 EXPECT_EQ(28, global_epilogue_callback_status); | 1965 EXPECT_EQ(28, global_epilogue_callback_status); |
| 1855 | 1966 |
| 1967 // Garbage collect old space again without invoking callbacks. |
| 1968 // Nothing should change. |
| 1969 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 1970 Heap::kIgnoreApiCallbacks); |
| 1971 EXPECT_EQ(6, global_prologue_callback_status); |
| 1972 EXPECT_EQ(28, global_epilogue_callback_status); |
| 1973 |
| 1856 // Garbage collect old space again. Callbacks are persistent so the | 1974 // Garbage collect old space again. Callbacks are persistent so the |
| 1857 // prologue and epilogue status values should change again. | 1975 // prologue and epilogue status values should change again. |
| 1858 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1976 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1859 EXPECT_EQ(12, global_prologue_callback_status); | 1977 EXPECT_EQ(12, global_prologue_callback_status); |
| 1860 EXPECT_EQ(112, global_epilogue_callback_status); | 1978 EXPECT_EQ(112, global_epilogue_callback_status); |
| 1861 | 1979 |
| 1862 // Remove the prologue and epilogue callbacks | 1980 // Remove the prologue and epilogue callbacks |
| 1863 EXPECT_VALID(Dart_RemoveGcPrologueCallback(&PrologueCallbackTimes2)); | 1981 EXPECT_VALID(Dart_RemoveGcPrologueCallback(&PrologueCallbackTimes2)); |
| 1864 EXPECT_VALID(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes4)); | 1982 EXPECT_VALID(Dart_RemoveGcEpilogueCallback(&EpilogueCallbackTimes4)); |
| 1865 | 1983 |
| (...skipping 2972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4838 EXPECT_VALID(result); | 4956 EXPECT_VALID(result); |
| 4839 EXPECT(Dart_IsDouble(result)); | 4957 EXPECT(Dart_IsDouble(result)); |
| 4840 double out; | 4958 double out; |
| 4841 result = Dart_DoubleValue(result, &out); | 4959 result = Dart_DoubleValue(result, &out); |
| 4842 fprintf(stderr, "Benchmark_UseDartApi: %f us per iteration\n", out); | 4960 fprintf(stderr, "Benchmark_UseDartApi: %f us per iteration\n", out); |
| 4843 } | 4961 } |
| 4844 | 4962 |
| 4845 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 4963 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). |
| 4846 | 4964 |
| 4847 } // namespace dart | 4965 } // namespace dart |
| OLD | NEW |