Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 84e65ace6d7d640c528ee30dff1995b104eb86f9..3f0e888477c50bd733eed6b3ede0c664c8e7dc76 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -836,16 +836,30 @@ MaybeObject* KeyedCallIC::LoadFunction(State state, |
if (use_ic && state != MEGAMORPHIC) { |
int argc = target()->arguments_count(); |
- Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( |
- argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
- if (object->IsJSObject()) { |
- Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
- if (receiver->elements()->map() == |
- isolate()->heap()->non_strict_arguments_elements_map()) { |
- stub = isolate()->stub_cache()->ComputeCallArguments(argc); |
+ Handle<Code> stub; |
+ |
+ if (object->IsJSArray() && key->IsSmi()) { |
danno
2013/10/11 16:13:24
Some comments for this logic would be good. It's n
Toon Verwaest
2013/11/04 13:59:44
Done.
|
+ Handle<JSArray> array = Handle<JSArray>::cast(object); |
+ ElementsKind kind = array->map()->elements_kind(); |
+ if (IsFastObjectElementsKind(kind) && |
+ array->map() == isolate()->get_initial_js_array_map(kind)) { |
+ KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc); |
+ stub = stub_gen.GetCode(isolate()); |
} |
} |
- ASSERT(!stub.is_null()); |
+ |
+ if (stub.is_null()) { |
+ stub = isolate()->stub_cache()->ComputeCallMegamorphic( |
+ argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); |
+ if (object->IsJSObject()) { |
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
+ if (receiver->elements()->map() == |
+ isolate()->heap()->non_strict_arguments_elements_map()) { |
+ stub = isolate()->stub_cache()->ComputeCallArguments(argc); |
+ } |
+ } |
+ ASSERT(!stub.is_null()); |
+ } |
set_target(*stub); |
TRACE_IC("KeyedCallIC", key, state, target()); |
} |
@@ -2393,6 +2407,29 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 2); |
+ KeyedCallIC ic(isolate); |
+ Arguments* caller_args = reinterpret_cast<Arguments*>(args[0]); |
+ Object* key = args[1]; |
+ Object* receiver = (*caller_args)[0]; |
+ |
+ IC::State state = IC::StateFrom(ic.target(), receiver, key); |
+ MaybeObject* maybe_result = |
+ ic.LoadFunction(state, handle(receiver, isolate), handle(key, isolate)); |
+ // Result could be a function or a failure. |
+ JSFunction* raw_function = NULL; |
+ if (!maybe_result->To(&raw_function)) return maybe_result; |
+ |
+ if (raw_function->is_compiled()) return raw_function; |
+ |
+ Handle<JSFunction> function(raw_function, isolate); |
+ JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
+ return *function; |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { |
SealHandleScope shs(isolate); |