OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 2120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2131 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); | 2131 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); |
2132 } | 2132 } |
2133 DCHECK(!stub.is_null()); | 2133 DCHECK(!stub.is_null()); |
2134 set_target(*stub); | 2134 set_target(*stub); |
2135 TRACE_IC("StoreIC", key); | 2135 TRACE_IC("StoreIC", key); |
2136 | 2136 |
2137 return store_handle; | 2137 return store_handle; |
2138 } | 2138 } |
2139 | 2139 |
2140 | 2140 |
2141 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, | 2141 bool CallIC::DoCustomHandler(Handle<Object> function, |
2142 const CallICState& callic_state) { | 2142 const CallICState& callic_state) { |
2143 DCHECK(FLAG_use_ic && function->IsJSFunction()); | 2143 DCHECK(FLAG_use_ic && function->IsJSFunction()); |
2144 | 2144 |
2145 // Are we the array function? | 2145 // Are we the array function? |
2146 Handle<JSFunction> array_function = | 2146 Handle<JSFunction> array_function = |
2147 Handle<JSFunction>(isolate()->native_context()->array_function()); | 2147 Handle<JSFunction>(isolate()->native_context()->array_function()); |
2148 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { | 2148 if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { |
2149 // Alter the slot. | 2149 // Alter the slot. |
2150 CallICNexus* nexus = casted_nexus<CallICNexus>(); | 2150 CallICNexus* nexus = casted_nexus<CallICNexus>(); |
2151 nexus->ConfigureMonomorphicArray(); | 2151 nexus->ConfigureMonomorphicArray(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 2196 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
2197 name = handle(js_function->shared()->name(), isolate()); | 2197 name = handle(js_function->shared()->name(), isolate()); |
2198 } | 2198 } |
2199 | 2199 |
2200 TRACE_IC("CallIC", name); | 2200 TRACE_IC("CallIC", name); |
2201 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(), | 2201 OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(), |
2202 GENERIC); | 2202 GENERIC); |
2203 } | 2203 } |
2204 | 2204 |
2205 | 2205 |
2206 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function) { | 2206 void CallIC::HandleMiss(Handle<Object> function) { |
2207 CallICState callic_state(target()->extra_ic_state()); | 2207 CallICState callic_state(target()->extra_ic_state()); |
2208 Handle<Object> name = isolate()->factory()->empty_string(); | 2208 Handle<Object> name = isolate()->factory()->empty_string(); |
2209 CallICNexus* nexus = casted_nexus<CallICNexus>(); | 2209 CallICNexus* nexus = casted_nexus<CallICNexus>(); |
2210 Object* feedback = nexus->GetFeedback(); | 2210 Object* feedback = nexus->GetFeedback(); |
2211 | 2211 |
2212 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. | 2212 // Hand-coded MISS handling is easier if CallIC slots don't contain smis. |
2213 DCHECK(!feedback->IsSmi()); | 2213 DCHECK(!feedback->IsSmi()); |
2214 | 2214 |
2215 if (feedback->IsWeakCell() || !function->IsJSFunction()) { | 2215 if (feedback->IsWeakCell() || !function->IsJSFunction()) { |
2216 // We are going generic. | 2216 // We are going generic. |
2217 nexus->ConfigureGeneric(); | 2217 nexus->ConfigureGeneric(); |
2218 } else { | 2218 } else { |
2219 // The feedback is either uninitialized or an allocation site. | 2219 // The feedback is either uninitialized or an allocation site. |
2220 // It might be an allocation site because if we re-compile the full code | 2220 // It might be an allocation site because if we re-compile the full code |
2221 // to add deoptimization support, we call with the default call-ic, and | 2221 // to add deoptimization support, we call with the default call-ic, and |
2222 // merely need to patch the target to match the feedback. | 2222 // merely need to patch the target to match the feedback. |
2223 // TODO(mvstanton): the better approach is to dispense with patching | 2223 // TODO(mvstanton): the better approach is to dispense with patching |
2224 // altogether, which is in progress. | 2224 // altogether, which is in progress. |
2225 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || | 2225 DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || |
2226 feedback->IsAllocationSite()); | 2226 feedback->IsAllocationSite()); |
2227 | 2227 |
2228 // Do we want to install a custom handler? | 2228 // Do we want to install a custom handler? |
2229 if (FLAG_use_ic && DoCustomHandler(receiver, function, callic_state)) { | 2229 if (FLAG_use_ic && DoCustomHandler(function, callic_state)) { |
2230 return; | 2230 return; |
2231 } | 2231 } |
2232 | 2232 |
2233 nexus->ConfigureMonomorphic(Handle<JSFunction>::cast(function)); | 2233 nexus->ConfigureMonomorphic(Handle<JSFunction>::cast(function)); |
2234 } | 2234 } |
2235 | 2235 |
2236 if (function->IsJSFunction()) { | 2236 if (function->IsJSFunction()) { |
2237 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); | 2237 Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); |
2238 name = handle(js_function->shared()->name(), isolate()); | 2238 name = handle(js_function->shared()->name(), isolate()); |
2239 } | 2239 } |
2240 | 2240 |
2241 IC::State new_state = nexus->StateFromFeedback(); | 2241 IC::State new_state = nexus->StateFromFeedback(); |
2242 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), state(), new_state); | 2242 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), state(), new_state); |
2243 TRACE_IC("CallIC", name); | 2243 TRACE_IC("CallIC", name); |
2244 } | 2244 } |
2245 | 2245 |
2246 | 2246 |
2247 #undef TRACE_IC | 2247 #undef TRACE_IC |
2248 | 2248 |
2249 | 2249 |
2250 // ---------------------------------------------------------------------------- | 2250 // ---------------------------------------------------------------------------- |
2251 // Static IC stub generators. | 2251 // Static IC stub generators. |
2252 // | 2252 // |
2253 | 2253 |
2254 // Used from ic-<arch>.cc. | 2254 // Used from ic-<arch>.cc. |
2255 RUNTIME_FUNCTION(CallIC_Miss) { | 2255 RUNTIME_FUNCTION(CallIC_Miss) { |
2256 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2256 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2257 HandleScope scope(isolate); | 2257 HandleScope scope(isolate); |
2258 DCHECK(args.length() == 4); | 2258 DCHECK(args.length() == 3); |
2259 Handle<Object> receiver = args.at<Object>(0); | 2259 Handle<Object> function = args.at<Object>(0); |
2260 Handle<Object> function = args.at<Object>(1); | 2260 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); |
2261 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); | 2261 Handle<Smi> slot = args.at<Smi>(2); |
2262 Handle<Smi> slot = args.at<Smi>(3); | |
2263 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); | 2262 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
2264 CallICNexus nexus(vector, vector_slot); | 2263 CallICNexus nexus(vector, vector_slot); |
2265 CallIC ic(isolate, &nexus); | 2264 CallIC ic(isolate, &nexus); |
2266 ic.HandleMiss(receiver, function); | 2265 ic.HandleMiss(function); |
2267 return *function; | 2266 return *function; |
2268 } | 2267 } |
2269 | 2268 |
2270 | 2269 |
2271 RUNTIME_FUNCTION(CallIC_Customization_Miss) { | 2270 RUNTIME_FUNCTION(CallIC_Customization_Miss) { |
2272 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2271 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2273 HandleScope scope(isolate); | 2272 HandleScope scope(isolate); |
2274 DCHECK(args.length() == 4); | 2273 DCHECK(args.length() == 3); |
2275 Handle<Object> function = args.at<Object>(1); | 2274 Handle<Object> function = args.at<Object>(0); |
2276 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); | 2275 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); |
2277 Handle<Smi> slot = args.at<Smi>(3); | 2276 Handle<Smi> slot = args.at<Smi>(2); |
2278 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); | 2277 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
2279 CallICNexus nexus(vector, vector_slot); | 2278 CallICNexus nexus(vector, vector_slot); |
2280 // A miss on a custom call ic always results in going megamorphic. | 2279 // A miss on a custom call ic always results in going megamorphic. |
2281 CallIC ic(isolate, &nexus); | 2280 CallIC ic(isolate, &nexus); |
2282 ic.PatchMegamorphic(function); | 2281 ic.PatchMegamorphic(function); |
2283 return *function; | 2282 return *function; |
2284 } | 2283 } |
2285 | 2284 |
2286 | 2285 |
2287 // Used from ic-<arch>.cc. | 2286 // Used from ic-<arch>.cc. |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2989 static const Address IC_utilities[] = { | 2988 static const Address IC_utilities[] = { |
2990 #define ADDR(name) FUNCTION_ADDR(name), | 2989 #define ADDR(name) FUNCTION_ADDR(name), |
2991 IC_UTIL_LIST(ADDR) NULL | 2990 IC_UTIL_LIST(ADDR) NULL |
2992 #undef ADDR | 2991 #undef ADDR |
2993 }; | 2992 }; |
2994 | 2993 |
2995 | 2994 |
2996 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 2995 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
2997 } | 2996 } |
2998 } // namespace v8::internal | 2997 } // namespace v8::internal |
OLD | NEW |