| 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 |