Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(717)

Side by Side Diff: runtime/vm/dart_api_impl_test.cc

Issue 9956138: Process weak reference sets when a scavenge invokes the API callbacks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/scavenger.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/scavenger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698