Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index dc66e9b94fd056e866152cb43cc018ec33fa4963..c17ecbaf0324da1c8ebf9646ef9b430678d809cf 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -71,11 +71,11 @@ const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) { |
void IC::TraceIC(const char* type, |
- Handle<Object> name, |
- Code* new_target) { |
+ Handle<Object> name) { |
if (FLAG_trace_ic) { |
+ Code* new_target = raw_target(); |
State new_state = new_target->ic_state(); |
- PrintF("[%s in ", type); |
+ PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type); |
StackFrameIterator it(isolate()); |
while (it.frame()->fp() != this->fp()) it.Advance(); |
StackFrame* raw_frame = it.frame(); |
@@ -114,8 +114,8 @@ void IC::TraceIC(const char* type, |
#define TRACE_GENERIC_IC(isolate, type, reason) |
#endif // DEBUG |
-#define TRACE_IC(type, name, new_target) \ |
- ASSERT((TraceIC(type, name, *new_target), true)) |
+#define TRACE_IC(type, name) \ |
+ ASSERT((TraceIC(type, name), true)) |
IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { |
// To improve the performance of the (much used) IC code, we unfold a few |
@@ -178,15 +178,111 @@ Address IC::OriginalCodeAddress() const { |
#endif |
-bool IC::TryRemoveInvalidPrototypeDependentStub(Object* receiver, |
- Object* name) { |
+static bool HasInterceptorGetter(JSObject* object) { |
+ return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
+} |
+ |
+ |
+static bool HasInterceptorSetter(JSObject* object) { |
+ return !object->GetNamedInterceptor()->setter()->IsUndefined(); |
+} |
+ |
+ |
+static void LookupForRead(Handle<Object> object, |
+ Handle<String> name, |
+ LookupResult* lookup) { |
+ // Skip all the objects with named interceptors, but |
+ // without actual getter. |
+ while (true) { |
+ object->Lookup(*name, lookup); |
+ // Besides normal conditions (property not found or it's not |
+ // an interceptor), bail out if lookup is not cacheable: we won't |
+ // be able to IC it anyway and regular lookup should work fine. |
+ if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { |
+ return; |
+ } |
+ |
+ Handle<JSObject> holder(lookup->holder(), lookup->isolate()); |
+ if (HasInterceptorGetter(*holder)) { |
+ return; |
+ } |
+ |
+ holder->LocalLookupRealNamedProperty(*name, lookup); |
+ if (lookup->IsFound()) { |
+ ASSERT(!lookup->IsInterceptor()); |
+ return; |
+ } |
+ |
+ Handle<Object> proto(holder->GetPrototype(), lookup->isolate()); |
+ if (proto->IsNull()) { |
+ ASSERT(!lookup->IsFound()); |
+ return; |
+ } |
+ |
+ object = proto; |
+ } |
+} |
+ |
+ |
+bool CallIC::TryUpdateExtraICState(LookupResult* lookup, |
+ Handle<Object> object) { |
+ if (!lookup->IsConstantFunction()) return false; |
+ JSFunction* function = lookup->GetConstantFunction(); |
+ if (!function->shared()->HasBuiltinFunctionId()) return false; |
+ |
+ // Fetch the arguments passed to the called function. |
+ const int argc = target()->arguments_count(); |
+ Address entry = isolate()->c_entry_fp(isolate()->thread_local_top()); |
+ Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); |
+ Arguments args(argc + 1, |
+ &Memory::Object_at(fp + |
+ StandardFrameConstants::kCallerSPOffset + |
+ argc * kPointerSize)); |
+ switch (function->shared()->builtin_function_id()) { |
+ case kStringCharCodeAt: |
+ case kStringCharAt: |
+ if (object->IsString()) { |
+ String* string = String::cast(*object); |
+ // Check there's the right string value or wrapper in the receiver slot. |
+ ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); |
+ // If we're in the default (fastest) state and the index is |
+ // out of bounds, update the state to record this fact. |
+ if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && |
+ argc >= 1 && args[1]->IsNumber()) { |
+ double index = DoubleToInteger(args.number_at(1)); |
+ if (index < 0 || index >= string->length()) { |
+ extra_ic_state_ = |
+ StringStubState::update(extra_ic_state(), |
+ STRING_INDEX_OUT_OF_BOUNDS); |
+ return true; |
+ } |
+ } |
+ } |
+ break; |
+ default: |
+ return false; |
+ } |
+ return false; |
+} |
+ |
+ |
+bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, |
+ Handle<String> name) { |
DisallowHeapAllocation no_gc; |
+ if (target()->is_call_stub()) { |
+ LookupResult lookup(isolate()); |
+ LookupForRead(receiver, name, &lookup); |
+ if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) { |
+ return true; |
+ } |
+ } |
+ |
if (target()->is_keyed_stub()) { |
// Determine whether the failure is due to a name failure. |
if (!name->IsName()) return false; |
Name* stub_name = target()->FindFirstName(); |
- if (Name::cast(name) != stub_name) return false; |
+ if (*name != stub_name) return false; |
} |
InlineCacheHolderFlag cache_holder = |
@@ -204,7 +300,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Object* receiver, |
break; |
} |
- Map* map = IC::GetCodeCacheHolder(isolate(), receiver, cache_holder)->map(); |
+ Map* map = IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map(); |
// Decide whether the inline cache failed because of changes to the |
// receiver itself or changes to one of its prototypes. |
@@ -214,15 +310,15 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Object* receiver, |
// the receiver map's code cache. Therefore, if the current target |
// is in the receiver map's code cache, the inline cache failed due |
// to prototype check failure. |
- int index = map->IndexInCodeCache(name, *target()); |
+ int index = map->IndexInCodeCache(*name, *target()); |
if (index >= 0) { |
- map->RemoveFromCodeCache(String::cast(name), *target(), index); |
+ map->RemoveFromCodeCache(*name, *target(), index); |
// Handlers are stored in addition to the ICs on the map. Remove those, too. |
Code* handler = target()->FindFirstHandler(); |
if (handler != NULL) { |
- index = map->IndexInCodeCache(name, handler); |
+ index = map->IndexInCodeCache(*name, handler); |
if (index >= 0) { |
- map->RemoveFromCodeCache(String::cast(name), handler, index); |
+ map->RemoveFromCodeCache(*name, handler, index); |
} |
} |
return true; |
@@ -249,10 +345,9 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Object* receiver, |
} |
if (receiver->IsGlobalObject()) { |
- if (!name->IsName()) return false; |
LookupResult lookup(isolate()); |
- GlobalObject* global = GlobalObject::cast(receiver); |
- global->LocalLookupRealNamedProperty(Name::cast(name), &lookup); |
+ GlobalObject* global = GlobalObject::cast(*receiver); |
+ global->LocalLookupRealNamedProperty(*name, &lookup); |
if (!lookup.IsFound()) return false; |
PropertyCell* cell = global->GetPropertyCell(&lookup); |
return cell->type()->IsConstant(); |
@@ -262,20 +357,16 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Object* receiver, |
} |
-void IC::UpdateState(Object* receiver, Object* name) { |
+void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { |
if (state() != MONOMORPHIC || !name->IsString()) return; |
if (receiver->IsUndefined() || receiver->IsNull()) return; |
- Code::Kind kind = target()->kind(); |
// Remove the target from the code cache if it became invalid |
// because of changes in the prototype chain to avoid hitting it |
// again. |
- // Call stubs handle this later to allow extra IC state |
- // transitions. |
- if (kind != Code::CALL_IC && kind != Code::KEYED_CALL_IC && |
- TryRemoveInvalidPrototypeDependentStub(receiver, name)) { |
- MarkMonomorphicPrototypeFailure(); |
- return; |
+ if (TryRemoveInvalidPrototypeDependentStub( |
+ receiver, Handle<String>::cast(name))) { |
+ return MarkMonomorphicPrototypeFailure(); |
} |
// The builtins object is special. It only changes when JavaScript |
@@ -449,52 +540,6 @@ void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { |
} |
-static bool HasInterceptorGetter(JSObject* object) { |
- return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
-} |
- |
- |
-static bool HasInterceptorSetter(JSObject* object) { |
- return !object->GetNamedInterceptor()->setter()->IsUndefined(); |
-} |
- |
- |
-static void LookupForRead(Handle<Object> object, |
- Handle<String> name, |
- LookupResult* lookup) { |
- // Skip all the objects with named interceptors, but |
- // without actual getter. |
- while (true) { |
- object->Lookup(*name, lookup); |
- // Besides normal conditions (property not found or it's not |
- // an interceptor), bail out if lookup is not cacheable: we won't |
- // be able to IC it anyway and regular lookup should work fine. |
- if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { |
- return; |
- } |
- |
- Handle<JSObject> holder(lookup->holder(), lookup->isolate()); |
- if (HasInterceptorGetter(*holder)) { |
- return; |
- } |
- |
- holder->LocalLookupRealNamedProperty(*name, lookup); |
- if (lookup->IsFound()) { |
- ASSERT(!lookup->IsInterceptor()); |
- return; |
- } |
- |
- Handle<Object> proto(holder->GetPrototype(), lookup->isolate()); |
- if (proto->IsNull()) { |
- ASSERT(!lookup->IsFound()); |
- return; |
- } |
- |
- object = proto; |
- } |
-} |
- |
- |
Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { |
Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object); |
@@ -631,50 +676,7 @@ MaybeObject* CallICBase::LoadFunction(Handle<Object> object, |
} |
-bool CallIC::TryUpdateExtraICState(LookupResult* lookup, |
- Handle<Object> object) { |
- if (!lookup->IsConstantFunction()) return false; |
- JSFunction* function = lookup->GetConstantFunction(); |
- if (!function->shared()->HasBuiltinFunctionId()) return false; |
- |
- // Fetch the arguments passed to the called function. |
- const int argc = target()->arguments_count(); |
- Address entry = isolate()->c_entry_fp(isolate()->thread_local_top()); |
- Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); |
- Arguments args(argc + 1, |
- &Memory::Object_at(fp + |
- StandardFrameConstants::kCallerSPOffset + |
- argc * kPointerSize)); |
- switch (function->shared()->builtin_function_id()) { |
- case kStringCharCodeAt: |
- case kStringCharAt: |
- if (object->IsString()) { |
- String* string = String::cast(*object); |
- // Check there's the right string value or wrapper in the receiver slot. |
- ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); |
- // If we're in the default (fastest) state and the index is |
- // out of bounds, update the state to record this fact. |
- if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && |
- argc >= 1 && args[1]->IsNumber()) { |
- double index = DoubleToInteger(args.number_at(1)); |
- if (index < 0 || index >= string->length()) { |
- extra_ic_state_ = |
- StringStubState::update(extra_ic_state(), |
- STRING_INDEX_OUT_OF_BOUNDS); |
- return true; |
- } |
- } |
- } |
- break; |
- default: |
- return false; |
- } |
- return false; |
-} |
- |
- |
Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
- Code::ExtraICState extra_state, |
Handle<Object> object, |
Handle<String> name) { |
int argc = target()->arguments_count(); |
@@ -683,7 +685,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
case FIELD: { |
PropertyIndex index = lookup->GetFieldIndex(); |
return isolate()->stub_cache()->ComputeCallField( |
- argc, kind_, extra_state, name, object, holder, index); |
+ argc, kind_, extra_ic_state(), name, object, holder, index); |
} |
case CONSTANT: { |
if (!lookup->IsConstantFunction()) return Handle<Code>::null(); |
@@ -692,7 +694,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
// that the code stub is in the stub cache. |
Handle<JSFunction> function(lookup->GetConstantFunction(), isolate()); |
return isolate()->stub_cache()->ComputeCallConstant( |
- argc, kind_, extra_state, name, object, holder, function); |
+ argc, kind_, extra_ic_state(), name, object, holder, function); |
} |
case NORMAL: { |
// If we return a null handle, the IC will not be patched. |
@@ -706,7 +708,8 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); |
Handle<JSFunction> function(JSFunction::cast(cell->value())); |
return isolate()->stub_cache()->ComputeCallGlobal( |
- argc, kind_, extra_state, name, receiver, global, cell, function); |
+ argc, kind_, extra_ic_state(), name, |
+ receiver, global, cell, function); |
} else { |
// There is only one shared stub for calling normalized |
// properties. It does not traverse the prototype chain, so the |
@@ -714,20 +717,32 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
// applicable. |
if (!holder.is_identical_to(receiver)) return Handle<Code>::null(); |
return isolate()->stub_cache()->ComputeCallNormal( |
- argc, kind_, extra_state); |
+ argc, kind_, extra_ic_state()); |
} |
break; |
} |
case INTERCEPTOR: |
ASSERT(HasInterceptorGetter(*holder)); |
return isolate()->stub_cache()->ComputeCallInterceptor( |
- argc, kind_, extra_state, name, object, holder); |
+ argc, kind_, extra_ic_state(), name, object, holder); |
default: |
return Handle<Code>::null(); |
} |
} |
+Handle<Code> CallICBase::megamorphic_stub() { |
+ return isolate()->stub_cache()->ComputeCallMegamorphic( |
+ target()->arguments_count(), kind_, extra_ic_state()); |
+} |
+ |
+ |
+Handle<Code> CallICBase::pre_monomorphic_stub() { |
+ return isolate()->stub_cache()->ComputeCallPreMonomorphic( |
+ target()->arguments_count(), kind_, extra_ic_state()); |
+} |
+ |
+ |
void CallICBase::UpdateCaches(LookupResult* lookup, |
Handle<Object> object, |
Handle<String> name) { |
@@ -735,60 +750,23 @@ void CallICBase::UpdateCaches(LookupResult* lookup, |
if (!lookup->IsProperty() || !lookup->IsCacheable()) return; |
// Compute the number of arguments. |
- int argc = target()->arguments_count(); |
Handle<Code> code; |
- if (state() == UNINITIALIZED) { |
- // This is the first time we execute this inline cache. |
- // Set the target to the pre monomorphic stub to delay |
- // setting the monomorphic state. |
- code = isolate()->stub_cache()->ComputeCallPreMonomorphic( |
- argc, kind_, extra_ic_state()); |
- } else if (state() == MONOMORPHIC) { |
- if (kind_ == Code::CALL_IC && |
- static_cast<CallIC*>(this)->TryUpdateExtraICState(lookup, object)) { |
- code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name); |
- } else if (TryRemoveInvalidPrototypeDependentStub(*object, *name)) { |
- MarkMonomorphicPrototypeFailure(); |
- code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name); |
- } else { |
- code = isolate()->stub_cache()->ComputeCallMegamorphic( |
- argc, kind_, extra_ic_state()); |
ulan
2013/10/02 08:45:24
Why are we removing these cases?
Toon Verwaest
2013/10/02 08:56:05
They aren't removed, they are just folded in the e
|
- } |
- } else { |
- code = ComputeMonomorphicStub(lookup, extra_ic_state(), object, name); |
- } |
+ code = state() == UNINITIALIZED |
+ ? pre_monomorphic_stub() |
+ : ComputeMonomorphicStub(lookup, object, name); |
// If there's no appropriate stub we simply avoid updating the caches. |
+ // TODO(verwaest): Install a slow fallback in this case to avoid not learning, |
+ // and deopting Crankshaft code. |
if (code.is_null()) return; |
- // Patch the call site depending on the state of the cache. |
- switch (state()) { |
- case UNINITIALIZED: |
- case MONOMORPHIC_PROTOTYPE_FAILURE: |
- case PREMONOMORPHIC: |
- case MONOMORPHIC: |
- set_target(*code); |
- break; |
- case MEGAMORPHIC: { |
- // Cache code holding map should be consistent with |
- // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. |
- Handle<JSObject> cache_object = object->IsJSObject() |
- ? Handle<JSObject>::cast(object) |
- : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), |
- isolate()); |
- // Update the stub cache. |
- UpdateMegamorphicCache(cache_object->map(), *name, *code); |
- break; |
- } |
- case DEBUG_STUB: |
- break; |
- case POLYMORPHIC: |
- case GENERIC: |
- UNREACHABLE(); |
- break; |
- } |
+ Handle<JSObject> cache_object = object->IsJSObject() |
+ ? Handle<JSObject>::cast(object) |
+ : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), |
+ isolate()); |
- TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", name, target()); |
+ PatchCache(cache_object, name, code); |
+ TRACE_IC("CallIC", name); |
} |
@@ -819,7 +797,7 @@ MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, |
} |
ASSERT(!stub.is_null()); |
set_target(*stub); |
- TRACE_IC("KeyedCallIC", key, target()); |
+ TRACE_IC("CallIC", key); |
} |
Handle<Object> result = GetProperty(isolate(), object, key); |
@@ -1057,7 +1035,11 @@ void IC::PatchCache(Handle<HeapObject> receiver, |
UpdateMonomorphicIC(receiver, code, name); |
break; |
case MONOMORPHIC: |
- ASSERT(!target().is_identical_to(code)); |
+ // For now, call stubs are allowed to rewrite to the same stub. This |
+ // happens e.g., when the field does not contain a function. |
+ ASSERT(target()->is_call_stub() || |
+ target()->is_keyed_call_stub() || |
+ !target().is_identical_to(code)); |
if (!target()->is_keyed_stub()) { |
bool is_same_handler = false; |
{ |
@@ -1144,7 +1126,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup, |
} |
PatchCache(receiver, name, code); |
- TRACE_IC("LoadIC", name, target()); |
+ TRACE_IC("LoadIC", name); |
} |
@@ -1366,7 +1348,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, |
ASSERT(!stub.is_null()); |
set_target(*stub); |
- TRACE_IC("KeyedLoadIC", key, target()); |
+ TRACE_IC("LoadIC", key); |
} |
@@ -1558,7 +1540,7 @@ MaybeObject* StoreIC::Store(Handle<Object> object, |
Handle<Code> stub = |
StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate()); |
set_target(*stub); |
- TRACE_IC("StoreIC", name, stub); |
+ TRACE_IC("StoreIC", name); |
Handle<Object> result = JSReceiver::SetProperty( |
receiver, name, value, NONE, strict_mode(), store_mode); |
RETURN_IF_EMPTY_HANDLE(isolate(), result); |
@@ -1571,7 +1553,7 @@ MaybeObject* StoreIC::Store(Handle<Object> object, |
// proxy as receiver. |
Handle<Code> stub = global_proxy_stub(); |
set_target(*stub); |
- TRACE_IC("StoreIC", name, stub); |
+ TRACE_IC("StoreIC", name); |
} |
Handle<Object> result = JSReceiver::SetProperty( |
receiver, name, value, NONE, strict_mode(), store_mode); |
@@ -1592,7 +1574,7 @@ MaybeObject* StoreIC::Store(Handle<Object> object, |
if (state() == UNINITIALIZED) { |
Handle<Code> stub = pre_monomorphic_stub(); |
set_target(*stub); |
- TRACE_IC("StoreIC", name, stub); |
+ TRACE_IC("StoreIC", name); |
} else if (can_store) { |
UpdateCaches(&lookup, receiver, name, value); |
} else if (!name->IsCacheable(isolate()) || |
@@ -1628,7 +1610,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup, |
} |
PatchCache(receiver, name, code); |
- TRACE_IC("StoreIC", name, target()); |
+ TRACE_IC("StoreIC", name); |
} |
@@ -2016,7 +1998,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object, |
} |
ASSERT(!stub.is_null()); |
set_target(*stub); |
- TRACE_IC("KeyedStoreIC", key, target()); |
+ TRACE_IC("StoreIC", key); |
} |
return Runtime::SetObjectPropertyOrFail( |
@@ -2079,9 +2061,10 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
CallIC ic(isolate); |
- ic.UpdateState(args[0], args[1]); |
- MaybeObject* maybe_result = ic.LoadFunction(args.at<Object>(0), |
- args.at<String>(1)); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<String> key = args.at<String>(1); |
+ ic.UpdateState(receiver, key); |
+ MaybeObject* maybe_result = ic.LoadFunction(receiver, key); |
JSFunction* raw_function; |
if (!maybe_result->To(&raw_function)) return maybe_result; |
@@ -2103,9 +2086,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
KeyedCallIC ic(isolate); |
- ic.UpdateState(args[0], args[1]); |
- MaybeObject* maybe_result = |
- ic.LoadFunction(args.at<Object>(0), args.at<Object>(1)); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ MaybeObject* maybe_result = ic.LoadFunction(receiver, key); |
// Result could be a function or a failure. |
JSFunction* raw_function = NULL; |
if (!maybe_result->To(&raw_function)) return maybe_result; |
@@ -2123,8 +2107,10 @@ RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Load(args.at<Object>(0), args.at<String>(1)); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<String> key = args.at<String>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Load(receiver, key); |
} |
@@ -2133,8 +2119,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Load(args.at<Object>(0), args.at<Object>(1), MISS); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Load(receiver, key, MISS); |
} |
@@ -2142,8 +2130,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Load(args.at<Object>(0), args.at<Object>(1), MISS); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Load(receiver, key, MISS); |
} |
@@ -2151,10 +2141,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 2); |
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Load(args.at<Object>(0), |
- args.at<Object>(1), |
- MISS_FORCE_GENERIC); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Load(receiver, key, MISS_FORCE_GENERIC); |
} |
@@ -2163,10 +2153,10 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Store(args.at<Object>(0), |
- args.at<String>(1), |
- args.at<Object>(2)); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<String> key = args.at<String>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Store(receiver, key, args.at<Object>(2)); |
} |
@@ -2174,10 +2164,10 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Store(args.at<Object>(0), |
- args.at<String>(1), |
- args.at<Object>(2)); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<String> key = args.at<String>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Store(receiver, key, args.at<Object>(2)); |
} |
@@ -2260,11 +2250,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Store(args.at<Object>(0), |
- args.at<Object>(1), |
- args.at<Object>(2), |
- MISS); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Store(receiver, key, args.at<Object>(2), MISS); |
} |
@@ -2272,11 +2261,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Store(args.at<Object>(0), |
- args.at<Object>(1), |
- args.at<Object>(2), |
- MISS); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Store(receiver, key, args.at<Object>(2), MISS); |
} |
@@ -2318,11 +2306,10 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
- ic.UpdateState(args[0], args[1]); |
- return ic.Store(args.at<Object>(0), |
- args.at<Object>(1), |
- args.at<Object>(2), |
- MISS_FORCE_GENERIC); |
+ Handle<Object> receiver = args.at<Object>(0); |
+ Handle<Object> key = args.at<Object>(1); |
+ ic.UpdateState(receiver, key); |
+ return ic.Store(receiver, key, args.at<Object>(2), MISS_FORCE_GENERIC); |
} |