Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 84e65ace6d7d640c528ee30dff1995b104eb86f9..f60c06fb4ff41180335318cda0cc7edbc6996584 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -836,16 +836,29 @@ 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/02 08:49:11
A comment or two would be very useful here to desc
|
+ 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 +2406,33 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 1); |
+ KeyedCallIC ic(isolate); |
+ int argc = Code::ExtractArgumentsCountFromFlags(ic.target()->flags()); |
+ |
+ StackFrameLocator locator(isolate); |
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
+ int index = frame->ComputeExpressionsCount() - (argc + 1); |
+ Object* receiver = frame->GetExpression(index); |
+ Object* key = args[0]; |
danno
2013/10/02 08:49:11
Oh, this is awful. Please take a look at ArrayCons
Toon Verwaest
2013/10/02 16:28:16
Done.
|
+ |
+ 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); |