OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 | 2 |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "execution.h" | 7 #include "execution.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
10 #include "global-handles.h" | 10 #include "global-handles.h" |
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 | 1746 |
1747 CHECK(HEAP->InNewSpace(*o)); | 1747 CHECK(HEAP->InNewSpace(*o)); |
1748 } | 1748 } |
1749 | 1749 |
1750 | 1750 |
1751 static int CountMapTransitions(Map* map) { | 1751 static int CountMapTransitions(Map* map) { |
1752 return map->transitions()->number_of_transitions(); | 1752 return map->transitions()->number_of_transitions(); |
1753 } | 1753 } |
1754 | 1754 |
1755 | 1755 |
| 1756 // Go through all incremental marking steps in one swoop. |
| 1757 static void SimulateIncrementalMarking() { |
| 1758 IncrementalMarking* marking = HEAP->incremental_marking(); |
| 1759 CHECK(marking->IsStopped()); |
| 1760 marking->Start(); |
| 1761 CHECK(marking->IsMarking()); |
| 1762 while (!marking->IsComplete()) { |
| 1763 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 1764 } |
| 1765 CHECK(marking->IsComplete()); |
| 1766 } |
| 1767 |
| 1768 |
1756 // Test that map transitions are cleared and maps are collected with | 1769 // Test that map transitions are cleared and maps are collected with |
1757 // incremental marking as well. | 1770 // incremental marking as well. |
1758 TEST(Regress1465) { | 1771 TEST(Regress1465) { |
1759 i::FLAG_allow_natives_syntax = true; | 1772 i::FLAG_allow_natives_syntax = true; |
1760 i::FLAG_trace_incremental_marking = true; | 1773 i::FLAG_trace_incremental_marking = true; |
1761 InitializeVM(); | 1774 InitializeVM(); |
1762 v8::HandleScope scope; | 1775 v8::HandleScope scope; |
1763 static const int transitions_count = 256; | 1776 static const int transitions_count = 256; |
1764 | 1777 |
1765 { | 1778 { |
1766 AlwaysAllocateScope always_allocate; | 1779 AlwaysAllocateScope always_allocate; |
1767 for (int i = 0; i < transitions_count; i++) { | 1780 for (int i = 0; i < transitions_count; i++) { |
1768 EmbeddedVector<char, 64> buffer; | 1781 EmbeddedVector<char, 64> buffer; |
1769 OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i); | 1782 OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i); |
1770 CompileRun(buffer.start()); | 1783 CompileRun(buffer.start()); |
1771 } | 1784 } |
1772 CompileRun("var root = new Object;"); | 1785 CompileRun("var root = new Object;"); |
1773 } | 1786 } |
1774 | 1787 |
1775 Handle<JSObject> root = | 1788 Handle<JSObject> root = |
1776 v8::Utils::OpenHandle( | 1789 v8::Utils::OpenHandle( |
1777 *v8::Handle<v8::Object>::Cast( | 1790 *v8::Handle<v8::Object>::Cast( |
1778 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); | 1791 v8::Context::GetCurrent()->Global()->Get(v8_str("root")))); |
1779 | 1792 |
1780 // Count number of live transitions before marking. | 1793 // Count number of live transitions before marking. |
1781 int transitions_before = CountMapTransitions(root->map()); | 1794 int transitions_before = CountMapTransitions(root->map()); |
1782 CompileRun("%DebugPrint(root);"); | 1795 CompileRun("%DebugPrint(root);"); |
1783 CHECK_EQ(transitions_count, transitions_before); | 1796 CHECK_EQ(transitions_count, transitions_before); |
1784 | 1797 |
1785 // Go through all incremental marking steps in one swoop. | 1798 SimulateIncrementalMarking(); |
1786 IncrementalMarking* marking = HEAP->incremental_marking(); | |
1787 CHECK(marking->IsStopped()); | |
1788 marking->Start(); | |
1789 CHECK(marking->IsMarking()); | |
1790 while (!marking->IsComplete()) { | |
1791 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
1792 } | |
1793 CHECK(marking->IsComplete()); | |
1794 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1799 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1795 | 1800 |
1796 // Count number of live transitions after marking. Note that one transition | 1801 // Count number of live transitions after marking. Note that one transition |
1797 // is left, because 'o' still holds an instance of one transition target. | 1802 // is left, because 'o' still holds an instance of one transition target. |
1798 int transitions_after = CountMapTransitions(root->map()); | 1803 int transitions_after = CountMapTransitions(root->map()); |
1799 CompileRun("%DebugPrint(root);"); | 1804 CompileRun("%DebugPrint(root);"); |
1800 CHECK_EQ(1, transitions_after); | 1805 CHECK_EQ(1, transitions_after); |
1801 } | 1806 } |
1802 | 1807 |
1803 | 1808 |
1804 TEST(Regress2143a) { | 1809 TEST(Regress2143a) { |
1805 i::FLAG_collect_maps = true; | 1810 i::FLAG_collect_maps = true; |
1806 i::FLAG_incremental_marking = true; | 1811 i::FLAG_incremental_marking = true; |
1807 InitializeVM(); | 1812 InitializeVM(); |
1808 v8::HandleScope scope; | 1813 v8::HandleScope scope; |
1809 | 1814 |
1810 // Prepare a map transition from the root object together with a yet | 1815 // Prepare a map transition from the root object together with a yet |
1811 // untransitioned root object. | 1816 // untransitioned root object. |
1812 CompileRun("var root = new Object;" | 1817 CompileRun("var root = new Object;" |
1813 "root.foo = 0;" | 1818 "root.foo = 0;" |
1814 "root = new Object;"); | 1819 "root = new Object;"); |
1815 | 1820 |
1816 // Go through all incremental marking steps in one swoop. | 1821 SimulateIncrementalMarking(); |
1817 IncrementalMarking* marking = HEAP->incremental_marking(); | |
1818 CHECK(marking->IsStopped()); | |
1819 marking->Start(); | |
1820 CHECK(marking->IsMarking()); | |
1821 while (!marking->IsComplete()) { | |
1822 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
1823 } | |
1824 CHECK(marking->IsComplete()); | |
1825 | 1822 |
1826 // Compile a StoreIC that performs the prepared map transition. This | 1823 // Compile a StoreIC that performs the prepared map transition. This |
1827 // will restart incremental marking and should make sure the root is | 1824 // will restart incremental marking and should make sure the root is |
1828 // marked grey again. | 1825 // marked grey again. |
1829 CompileRun("function f(o) {" | 1826 CompileRun("function f(o) {" |
1830 " o.foo = 0;" | 1827 " o.foo = 0;" |
1831 "}" | 1828 "}" |
1832 "f(new Object);" | 1829 "f(new Object);" |
1833 "f(root);"); | 1830 "f(root);"); |
1834 | 1831 |
(...skipping 20 matching lines...) Expand all Loading... |
1855 i::FLAG_allow_natives_syntax = true; | 1852 i::FLAG_allow_natives_syntax = true; |
1856 InitializeVM(); | 1853 InitializeVM(); |
1857 v8::HandleScope scope; | 1854 v8::HandleScope scope; |
1858 | 1855 |
1859 // Prepare a map transition from the root object together with a yet | 1856 // Prepare a map transition from the root object together with a yet |
1860 // untransitioned root object. | 1857 // untransitioned root object. |
1861 CompileRun("var root = new Object;" | 1858 CompileRun("var root = new Object;" |
1862 "root.foo = 0;" | 1859 "root.foo = 0;" |
1863 "root = new Object;"); | 1860 "root = new Object;"); |
1864 | 1861 |
1865 // Go through all incremental marking steps in one swoop. | 1862 SimulateIncrementalMarking(); |
1866 IncrementalMarking* marking = HEAP->incremental_marking(); | |
1867 CHECK(marking->IsStopped()); | |
1868 marking->Start(); | |
1869 CHECK(marking->IsMarking()); | |
1870 while (!marking->IsComplete()) { | |
1871 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
1872 } | |
1873 CHECK(marking->IsComplete()); | |
1874 | 1863 |
1875 // Compile an optimized LStoreNamedField that performs the prepared | 1864 // Compile an optimized LStoreNamedField that performs the prepared |
1876 // map transition. This will restart incremental marking and should | 1865 // map transition. This will restart incremental marking and should |
1877 // make sure the root is marked grey again. | 1866 // make sure the root is marked grey again. |
1878 CompileRun("function f(o) {" | 1867 CompileRun("function f(o) {" |
1879 " o.foo = 0;" | 1868 " o.foo = 0;" |
1880 "}" | 1869 "}" |
1881 "f(new Object);" | 1870 "f(new Object);" |
1882 "f(new Object);" | 1871 "f(new Object);" |
1883 "%OptimizeFunctionOnNextCall(f);" | 1872 "%OptimizeFunctionOnNextCall(f);" |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 v8::Utils::OpenHandle( | 2048 v8::Utils::OpenHandle( |
2060 *v8::Handle<v8::Function>::Cast( | 2049 *v8::Handle<v8::Function>::Cast( |
2061 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2050 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2062 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( | 2051 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( |
2063 f->shared()->code()->type_feedback_info())->type_feedback_cells()); | 2052 f->shared()->code()->type_feedback_info())->type_feedback_cells()); |
2064 | 2053 |
2065 CHECK_EQ(2, cells->CellCount()); | 2054 CHECK_EQ(2, cells->CellCount()); |
2066 CHECK(cells->Cell(0)->value()->IsJSFunction()); | 2055 CHECK(cells->Cell(0)->value()->IsJSFunction()); |
2067 CHECK(cells->Cell(1)->value()->IsJSFunction()); | 2056 CHECK(cells->Cell(1)->value()->IsJSFunction()); |
2068 | 2057 |
2069 // Go through all incremental marking steps in one swoop. | 2058 SimulateIncrementalMarking(); |
2070 IncrementalMarking* marking = HEAP->incremental_marking(); | |
2071 CHECK(marking->IsStopped()); | |
2072 marking->Start(); | |
2073 CHECK(marking->IsMarking()); | |
2074 while (!marking->IsComplete()) { | |
2075 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
2076 } | |
2077 CHECK(marking->IsComplete()); | |
2078 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2059 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2079 | 2060 |
2080 CHECK_EQ(2, cells->CellCount()); | 2061 CHECK_EQ(2, cells->CellCount()); |
2081 CHECK(cells->Cell(0)->value()->IsTheHole()); | 2062 CHECK(cells->Cell(0)->value()->IsTheHole()); |
2082 CHECK(cells->Cell(1)->value()->IsTheHole()); | 2063 CHECK(cells->Cell(1)->value()->IsTheHole()); |
2083 } | 2064 } |
2084 | 2065 |
2085 | 2066 |
2086 static Code* FindFirstIC(Code* code, Code::Kind kind) { | 2067 static Code* FindFirstIC(Code* code, Code::Kind kind) { |
2087 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 2068 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
(...skipping 23 matching lines...) Expand all Loading... |
2111 Handle<JSFunction> f = | 2092 Handle<JSFunction> f = |
2112 v8::Utils::OpenHandle( | 2093 v8::Utils::OpenHandle( |
2113 *v8::Handle<v8::Function>::Cast( | 2094 *v8::Handle<v8::Function>::Cast( |
2114 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2095 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2115 | 2096 |
2116 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2097 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2117 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2098 CHECK(ic_before->ic_state() == MONOMORPHIC); |
2118 | 2099 |
2119 // Fire context dispose notification. | 2100 // Fire context dispose notification. |
2120 v8::V8::ContextDisposedNotification(); | 2101 v8::V8::ContextDisposedNotification(); |
2121 | 2102 SimulateIncrementalMarking(); |
2122 // Go through all incremental marking steps in one swoop. | |
2123 IncrementalMarking* marking = HEAP->incremental_marking(); | |
2124 CHECK(marking->IsStopped()); | |
2125 marking->Start(); | |
2126 CHECK(marking->IsMarking()); | |
2127 while (!marking->IsComplete()) { | |
2128 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
2129 } | |
2130 CHECK(marking->IsComplete()); | |
2131 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2103 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2132 | 2104 |
2133 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2105 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2134 CHECK(ic_after->ic_state() == MONOMORPHIC); | 2106 CHECK(ic_after->ic_state() == MONOMORPHIC); |
2135 } | 2107 } |
2136 | 2108 |
2137 | 2109 |
2138 TEST(IncrementalMarkingClearsMonomorhpicIC) { | 2110 TEST(IncrementalMarkingClearsMonomorhpicIC) { |
2139 if (i::FLAG_always_opt) return; | 2111 if (i::FLAG_always_opt) return; |
2140 InitializeVM(); | 2112 InitializeVM(); |
(...skipping 13 matching lines...) Expand all Loading... |
2154 Handle<JSFunction> f = | 2126 Handle<JSFunction> f = |
2155 v8::Utils::OpenHandle( | 2127 v8::Utils::OpenHandle( |
2156 *v8::Handle<v8::Function>::Cast( | 2128 *v8::Handle<v8::Function>::Cast( |
2157 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2129 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2158 | 2130 |
2159 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2131 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2160 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2132 CHECK(ic_before->ic_state() == MONOMORPHIC); |
2161 | 2133 |
2162 // Fire context dispose notification. | 2134 // Fire context dispose notification. |
2163 v8::V8::ContextDisposedNotification(); | 2135 v8::V8::ContextDisposedNotification(); |
2164 | 2136 SimulateIncrementalMarking(); |
2165 // Go through all incremental marking steps in one swoop. | |
2166 IncrementalMarking* marking = HEAP->incremental_marking(); | |
2167 CHECK(marking->IsStopped()); | |
2168 marking->Start(); | |
2169 CHECK(marking->IsMarking()); | |
2170 while (!marking->IsComplete()) { | |
2171 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
2172 } | |
2173 CHECK(marking->IsComplete()); | |
2174 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2137 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2175 | 2138 |
2176 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2139 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2177 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2140 CHECK(ic_after->ic_state() == UNINITIALIZED); |
2178 } | 2141 } |
2179 | 2142 |
2180 | 2143 |
2181 TEST(IncrementalMarkingClearsPolymorhpicIC) { | 2144 TEST(IncrementalMarkingClearsPolymorhpicIC) { |
2182 if (i::FLAG_always_opt) return; | 2145 if (i::FLAG_always_opt) return; |
2183 InitializeVM(); | 2146 InitializeVM(); |
(...skipping 20 matching lines...) Expand all Loading... |
2204 Handle<JSFunction> f = | 2167 Handle<JSFunction> f = |
2205 v8::Utils::OpenHandle( | 2168 v8::Utils::OpenHandle( |
2206 *v8::Handle<v8::Function>::Cast( | 2169 *v8::Handle<v8::Function>::Cast( |
2207 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2170 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2208 | 2171 |
2209 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2172 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2210 CHECK(ic_before->ic_state() == MEGAMORPHIC); | 2173 CHECK(ic_before->ic_state() == MEGAMORPHIC); |
2211 | 2174 |
2212 // Fire context dispose notification. | 2175 // Fire context dispose notification. |
2213 v8::V8::ContextDisposedNotification(); | 2176 v8::V8::ContextDisposedNotification(); |
2214 | 2177 SimulateIncrementalMarking(); |
2215 // Go through all incremental marking steps in one swoop. | |
2216 IncrementalMarking* marking = HEAP->incremental_marking(); | |
2217 CHECK(marking->IsStopped()); | |
2218 marking->Start(); | |
2219 CHECK(marking->IsMarking()); | |
2220 while (!marking->IsComplete()) { | |
2221 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | |
2222 } | |
2223 CHECK(marking->IsComplete()); | |
2224 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2178 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2225 | 2179 |
2226 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2180 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2227 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2181 CHECK(ic_after->ic_state() == UNINITIALIZED); |
2228 } | 2182 } |
OLD | NEW |