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 2059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2070 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 2070 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
2071 } | 2071 } |
2072 CHECK(marking->IsComplete()); | 2072 CHECK(marking->IsComplete()); |
2073 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2073 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2074 CHECK(marking->IsStopped()); | 2074 CHECK(marking->IsStopped()); |
2075 | 2075 |
2076 CHECK_EQ(2, cells->CellCount()); | 2076 CHECK_EQ(2, cells->CellCount()); |
2077 CHECK(cells->Cell(0)->value()->IsTheHole()); | 2077 CHECK(cells->Cell(0)->value()->IsTheHole()); |
2078 CHECK(cells->Cell(1)->value()->IsTheHole()); | 2078 CHECK(cells->Cell(1)->value()->IsTheHole()); |
2079 } | 2079 } |
| 2080 |
| 2081 |
| 2082 static Code* FindFirstIC(Code* code, Code::Kind kind) { |
| 2083 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 2084 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
| 2085 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | |
| 2086 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); |
| 2087 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
| 2088 RelocInfo* info = it.rinfo(); |
| 2089 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); |
| 2090 if (target->is_inline_cache_stub() && target->kind() == kind) { |
| 2091 return target; |
| 2092 } |
| 2093 } |
| 2094 return NULL; |
| 2095 } |
| 2096 |
| 2097 |
| 2098 TEST(IncrementalMarkingPreservesMonomorhpicIC) { |
| 2099 if (i::FLAG_always_opt) return; |
| 2100 InitializeVM(); |
| 2101 v8::HandleScope scope; |
| 2102 |
| 2103 // Prepare function f that contains a monomorphic IC for object |
| 2104 // originating from the same global context. |
| 2105 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" |
| 2106 "function f(o) { return o.x; } f(obj); f(obj);"); |
| 2107 Handle<JSFunction> f = |
| 2108 v8::Utils::OpenHandle( |
| 2109 *v8::Handle<v8::Function>::Cast( |
| 2110 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2111 |
| 2112 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2113 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2114 |
| 2115 // Fire context dispose notification. |
| 2116 v8::V8::ContextDisposedNotification(); |
| 2117 |
| 2118 // Go through all incremental marking steps in one swoop. |
| 2119 IncrementalMarking* marking = HEAP->incremental_marking(); |
| 2120 CHECK(marking->IsStopped()); |
| 2121 marking->Start(); |
| 2122 CHECK(marking->IsMarking()); |
| 2123 while (!marking->IsComplete()) { |
| 2124 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2125 } |
| 2126 CHECK(marking->IsComplete()); |
| 2127 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 2128 |
| 2129 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2130 CHECK(ic_after->ic_state() == MONOMORPHIC); |
| 2131 } |
| 2132 |
| 2133 |
| 2134 TEST(IncrementalMarkingClearsMonomorhpicIC) { |
| 2135 if (i::FLAG_always_opt) return; |
| 2136 InitializeVM(); |
| 2137 v8::HandleScope scope; |
| 2138 v8::Local<v8::Value> obj1; |
| 2139 |
| 2140 { |
| 2141 LocalContext env; |
| 2142 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
| 2143 obj1 = env->Global()->Get(v8_str("obj")); |
| 2144 } |
| 2145 |
| 2146 // Prepare function f that contains a monomorphic IC for object |
| 2147 // originating from a different global context. |
| 2148 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); |
| 2149 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); |
| 2150 Handle<JSFunction> f = |
| 2151 v8::Utils::OpenHandle( |
| 2152 *v8::Handle<v8::Function>::Cast( |
| 2153 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2154 |
| 2155 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2156 CHECK(ic_before->ic_state() == MONOMORPHIC); |
| 2157 |
| 2158 // Fire context dispose notification. |
| 2159 v8::V8::ContextDisposedNotification(); |
| 2160 |
| 2161 // Go through all incremental marking steps in one swoop. |
| 2162 IncrementalMarking* marking = HEAP->incremental_marking(); |
| 2163 CHECK(marking->IsStopped()); |
| 2164 marking->Start(); |
| 2165 CHECK(marking->IsMarking()); |
| 2166 while (!marking->IsComplete()) { |
| 2167 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2168 } |
| 2169 CHECK(marking->IsComplete()); |
| 2170 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 2171 |
| 2172 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2173 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2174 } |
| 2175 |
| 2176 |
| 2177 TEST(IncrementalMarkingClearsPolymorhpicIC) { |
| 2178 if (i::FLAG_always_opt) return; |
| 2179 InitializeVM(); |
| 2180 v8::HandleScope scope; |
| 2181 v8::Local<v8::Value> obj1, obj2; |
| 2182 |
| 2183 { |
| 2184 LocalContext env; |
| 2185 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
| 2186 obj1 = env->Global()->Get(v8_str("obj")); |
| 2187 } |
| 2188 |
| 2189 { |
| 2190 LocalContext env; |
| 2191 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); |
| 2192 obj2 = env->Global()->Get(v8_str("obj")); |
| 2193 } |
| 2194 |
| 2195 // Prepare function f that contains a polymorphic IC for objects |
| 2196 // originating from two different global contexts. |
| 2197 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); |
| 2198 v8::Context::GetCurrent()->Global()->Set(v8_str("obj2"), obj2); |
| 2199 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); |
| 2200 Handle<JSFunction> f = |
| 2201 v8::Utils::OpenHandle( |
| 2202 *v8::Handle<v8::Function>::Cast( |
| 2203 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
| 2204 |
| 2205 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2206 CHECK(ic_before->ic_state() == MEGAMORPHIC); |
| 2207 |
| 2208 // Fire context dispose notification. |
| 2209 v8::V8::ContextDisposedNotification(); |
| 2210 |
| 2211 // Go through all incremental marking steps in one swoop. |
| 2212 IncrementalMarking* marking = HEAP->incremental_marking(); |
| 2213 CHECK(marking->IsStopped()); |
| 2214 marking->Start(); |
| 2215 CHECK(marking->IsMarking()); |
| 2216 while (!marking->IsComplete()) { |
| 2217 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2218 } |
| 2219 CHECK(marking->IsComplete()); |
| 2220 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 2221 |
| 2222 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
| 2223 CHECK(ic_after->ic_state() == UNINITIALIZED); |
| 2224 } |
OLD | NEW |