Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Unified Diff: src/ic.cc

Issue 25464004: Use PatchCache for call ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698