summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic.cc')
-rw-r--r--deps/v8/src/ic.cc271
1 files changed, 167 insertions, 104 deletions
diff --git a/deps/v8/src/ic.cc b/deps/v8/src/ic.cc
index da2211b7b..515c6f71a 100644
--- a/deps/v8/src/ic.cc
+++ b/deps/v8/src/ic.cc
@@ -160,7 +160,7 @@ Address IC::OriginalCodeAddress() const {
// Find the function on the stack and both the active code for the
// function and the original code.
JSFunction* function = JSFunction::cast(frame->function());
- Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<SharedFunctionInfo> shared(function->shared(), isolate());
Code* code = shared->code();
ASSERT(Debug::HasDebugInfo(shared));
Code* original_code = Debug::GetDebugInfo(shared)->original_code();
@@ -190,7 +190,7 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
// The stub was generated for JSObject but called for non-JSObject.
// IC::GetCodeCacheHolder is not applicable.
return false;
- } else if (cache_holder == DELEGATE_MAP &&
+ } else if (cache_holder == PROTOTYPE_MAP &&
receiver->GetPrototype(isolate)->IsNull()) {
// IC::GetCodeCacheHolder is not applicable.
return false;
@@ -435,7 +435,7 @@ static void LookupForRead(Handle<Object> object,
return;
}
- Handle<JSObject> holder(lookup->holder());
+ Handle<JSObject> holder(lookup->holder(), lookup->isolate());
if (HasInterceptorGetter(*holder)) {
return;
}
@@ -446,7 +446,7 @@ static void LookupForRead(Handle<Object> object,
return;
}
- Handle<Object> proto(holder->GetPrototype(), name->GetIsolate());
+ Handle<Object> proto(holder->GetPrototype(), lookup->isolate());
if (proto->IsNull()) {
ASSERT(!lookup->IsFound());
return;
@@ -636,7 +636,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
Handle<Object> object,
Handle<String> name) {
int argc = target()->arguments_count();
- Handle<JSObject> holder(lookup->holder());
+ Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) {
case FIELD: {
PropertyIndex index = lookup->GetFieldIndex();
@@ -647,7 +647,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
// Get the constant function and compute the code stub for this
// call; used for rewriting to monomorphic state and making sure
// that the code stub is in the stub cache.
- Handle<JSFunction> function(lookup->GetConstantFunction());
+ Handle<JSFunction> function(lookup->GetConstantFunction(), isolate());
return isolate()->stub_cache()->ComputeCallConstant(
argc, kind_, extra_state, name, object, holder, function);
}
@@ -658,7 +658,8 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
if (holder->IsGlobalObject()) {
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
- Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+ Handle<JSGlobalPropertyCell> cell(
+ global->GetPropertyCell(lookup), isolate());
if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
Handle<JSFunction> function(JSFunction::cast(cell->value()));
return isolate()->stub_cache()->ComputeCallGlobal(
@@ -746,7 +747,8 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// 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())));
+ : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
+ isolate());
// Update the stub cache.
UpdateMegamorphicCache(cache_object->map(), *name, *code);
break;
@@ -855,28 +857,6 @@ MaybeObject* LoadIC::Load(State state,
return Smi::FromInt(String::cast(*string)->length());
}
- // Use specialized code for getting the length of arrays.
- if (object->IsJSArray() &&
- name->Equals(isolate()->heap()->length_string())) {
- Handle<Code> stub;
- if (state == UNINITIALIZED) {
- stub = pre_monomorphic_stub();
- } else if (state == PREMONOMORPHIC) {
- ArrayLengthStub array_length_stub(kind());
- stub = array_length_stub.GetCode(isolate());
- } else if (state != MEGAMORPHIC) {
- ASSERT(state != GENERIC);
- stub = megamorphic_stub();
- }
- if (!stub.is_null()) {
- set_target(*stub);
-#ifdef DEBUG
- if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
-#endif
- }
- return JSArray::cast(*object)->length();
- }
-
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
name->Equals(isolate()->heap()->prototype_string()) &&
@@ -1035,6 +1015,22 @@ void IC::CopyICToMegamorphicCache(Handle<String> name) {
}
+bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
+ AssertNoAllocation no_allocation;
+
+ Map* current_map = target()->FindFirstMap();
+ ElementsKind receiver_elements_kind = receiver_map->elements_kind();
+ bool more_general_transition =
+ IsMoreGeneralElementsKindTransition(
+ current_map->elements_kind(), receiver_elements_kind);
+ Map* transitioned_map = more_general_transition
+ ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
+ : NULL;
+
+ return transitioned_map == receiver_map;
+}
+
+
// Since GC may have been invoked, by the time PatchCache is called, |state| is
// not necessarily equal to target()->state().
void IC::PatchCache(State state,
@@ -1052,6 +1048,17 @@ void IC::PatchCache(State state,
// Only move to megamorphic if the target changes.
if (target() != *code) {
if (target()->is_load_stub()) {
+ bool is_same_handler = false;
+ {
+ AssertNoAllocation no_allocation;
+ Code* old_handler = target()->FindFirstCode();
+ is_same_handler = old_handler == *code;
+ }
+ if (is_same_handler
+ && IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
+ UpdateMonomorphicIC(receiver, code, name);
+ break;
+ }
if (UpdatePolymorphicIC(state, strict_mode, receiver, name, code)) {
break;
}
@@ -1196,7 +1203,8 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
case NORMAL:
if (holder->IsGlobalObject()) {
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
- Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+ Handle<JSGlobalPropertyCell> cell(
+ global->GetPropertyCell(lookup), isolate());
return isolate()->stub_cache()->ComputeLoadGlobal(
name, receiver, global, cell, lookup->IsDontDelete());
}
@@ -1223,6 +1231,12 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
if (!holder->HasFastProperties()) break;
return isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, Handle<JSFunction>::cast(getter));
+ } else if (receiver->IsJSArray() &&
+ name->Equals(isolate()->heap()->length_string())) {
+ PropertyIndex lengthIndex =
+ PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
+ return isolate()->stub_cache()->ComputeLoadField(
+ name, receiver, holder, lengthIndex);
}
// TODO(dcarney): Handle correctly.
if (callback->IsDeclaredAccessorInfo()) break;
@@ -1272,7 +1286,7 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
return generic_stub();
}
- Handle<Map> receiver_map(receiver->map());
+ Handle<Map> receiver_map(receiver->map(), isolate());
MapHandleList target_receiver_maps;
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
// Optimistically assume that ICs that haven't reached the MONOMORPHIC state
@@ -1283,7 +1297,8 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
if (target() == *string_stub()) {
target_receiver_maps.Add(isolate()->factory()->string_map());
} else {
- GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
+ GetReceiverMapsForStub(Handle<Code>(target(), isolate()),
+ &target_receiver_maps);
if (target_receiver_maps.length() == 0) {
return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
}
@@ -1355,7 +1370,8 @@ MaybeObject* KeyedLoadIC::Load(State state,
stub = non_strict_arguments_stub();
} else if (receiver->HasIndexedInterceptor()) {
stub = indexed_interceptor_stub();
- } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
+ } else if (!key->ToSmi()->IsFailure() &&
+ (target() != *non_strict_arguments_stub())) {
stub = LoadElementStub(receiver);
}
}
@@ -1379,13 +1395,13 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
if (!lookup->IsProperty()) return Handle<Code>::null();
// Compute a monomorphic stub.
- Handle<JSObject> holder(lookup->holder());
+ Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) {
case FIELD:
return isolate()->stub_cache()->ComputeKeyedLoadField(
name, receiver, holder, lookup->GetFieldIndex());
case CONSTANT_FUNCTION: {
- Handle<JSFunction> constant(lookup->GetConstantFunction());
+ Handle<JSFunction> constant(lookup->GetConstantFunction(), isolate());
return isolate()->stub_cache()->ComputeKeyedLoadConstant(
name, receiver, holder, constant);
}
@@ -1413,41 +1429,42 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
}
-static bool StoreICableLookup(LookupResult* lookup) {
- // Bail out if we didn't find a result.
- if (!lookup->IsFound()) return false;
-
- // Bail out if inline caching is not allowed.
- if (!lookup->IsCacheable()) return false;
-
- // If the property is read-only, we leave the IC in its current state.
- if (lookup->IsTransition()) {
- return !lookup->GetTransitionDetails().IsReadOnly();
- }
- return !lookup->IsReadOnly();
-}
-
-
static bool LookupForWrite(Handle<JSObject> receiver,
Handle<String> name,
LookupResult* lookup) {
- receiver->LocalLookup(*name, lookup);
- if (!lookup->IsFound()) {
- receiver->map()->LookupTransition(*receiver, *name, lookup);
- }
- if (!StoreICableLookup(lookup)) {
- // 2nd chance: There can be accessors somewhere in the prototype chain.
- receiver->Lookup(*name, lookup);
- return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup);
- }
+ Handle<JSObject> holder = receiver;
+ receiver->Lookup(*name, lookup);
+ if (lookup->IsFound()) {
+ if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
+
+ if (lookup->holder() == *receiver) {
+ if (lookup->IsInterceptor() &&
+ receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
+ receiver->LocalLookupRealNamedProperty(*name, lookup);
+ return lookup->IsFound() &&
+ !lookup->IsReadOnly() &&
+ lookup->IsCacheable();
+ }
+ return true;
+ }
- if (lookup->IsInterceptor() &&
- receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
- receiver->LocalLookupRealNamedProperty(*name, lookup);
- return StoreICableLookup(lookup);
+ if (lookup->IsPropertyCallbacks()) return true;
+
+ // Currently normal holders in the prototype chain are not supported. They
+ // would require a runtime positive lookup and verification that the details
+ // have not changed.
+ if (lookup->IsInterceptor() || lookup->IsNormal()) return false;
+ holder = Handle<JSObject>(lookup->holder(), lookup->isolate());
}
- return true;
+ // While normally LookupTransition gets passed the receiver, in this case we
+ // pass the holder of the property that we overwrite. This keeps the holder in
+ // the LookupResult intact so we can later use it to generate a prototype
+ // chain check. This avoids a double lookup, but requires us to pass in the
+ // receiver when trying to fetch extra information from the transition.
+ receiver->map()->LookupTransition(*holder, *name, lookup);
+ return lookup->IsTransition() &&
+ !lookup->GetTransitionDetails(receiver->map()).IsReadOnly();
}
@@ -1547,7 +1564,6 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<String> name,
Handle<Object> value) {
ASSERT(!receiver->IsJSGlobalProxy());
- ASSERT(StoreICableLookup(lookup));
ASSERT(lookup->IsFound());
// These are not cacheable, so we never see such LookupResults here.
@@ -1570,19 +1586,19 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
switch (lookup->type()) {
case FIELD:
return isolate()->stub_cache()->ComputeStoreField(
- name, receiver, lookup->GetFieldIndex().field_index(),
- Handle<Map>::null(), strict_mode);
+ name, receiver, lookup, Handle<Map>::null(), strict_mode);
case NORMAL:
if (receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the
// global object.
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
- Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+ Handle<JSGlobalPropertyCell> cell(
+ global->GetPropertyCell(lookup), isolate());
return isolate()->stub_cache()->ComputeStoreGlobal(
name, global, cell, strict_mode);
}
- if (!holder.is_identical_to(receiver)) break;
+ ASSERT(holder.is_identical_to(receiver));
return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject(), isolate());
@@ -1595,8 +1611,8 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
return isolate()->stub_cache()->ComputeStoreCallback(
name, receiver, holder, info, strict_mode);
} else if (callback->IsAccessorPair()) {
- Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter(),
- isolate());
+ Handle<Object> setter(
+ Handle<AccessorPair>::cast(callback)->setter(), isolate());
if (!setter->IsJSFunction()) break;
if (holder->IsGlobalObject()) break;
if (!holder->HasFastProperties()) break;
@@ -1617,7 +1633,10 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
case CONSTANT_FUNCTION:
break;
case TRANSITION: {
- Handle<Map> transition(lookup->GetTransitionTarget());
+ // Explicitly pass in the receiver map since LookupForWrite may have
+ // stored something else than the receiver in the holder.
+ Handle<Map> transition(
+ lookup->GetTransitionTarget(receiver->map()), isolate());
int descriptor = transition->LastAdded();
DescriptorArray* target_descriptors = transition->instance_descriptors();
@@ -1625,9 +1644,8 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
if (details.type() != FIELD || details.attributes() != NONE) break;
- int field_index = target_descriptors->GetFieldIndex(descriptor);
return isolate()->stub_cache()->ComputeStoreField(
- name, receiver, field_index, transition, strict_mode);
+ name, receiver, lookup, transition, strict_mode);
}
case NONEXISTENT:
case HANDLER:
@@ -1649,7 +1667,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
}
- if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
+ if (!FLAG_compiled_keyed_stores &&
+ (store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS)) {
// TODO(danno): We'll soon handle MONOMORPHIC ICs that also support
// copying COW arrays and silently ignoring some OOB stores into external
@@ -1661,7 +1680,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
}
State ic_state = target()->ic_state();
- Handle<Map> receiver_map(receiver->map());
+ Handle<Map> receiver_map(receiver->map(), isolate());
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
// Optimistically assume that ICs that haven't reached the MONOMORPHIC state
// yet will do so and stay there.
@@ -1697,24 +1716,18 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
transitioned_receiver_map =
ComputeTransitionedMap(receiver, store_mode);
}
- ElementsKind transitioned_kind =
- transitioned_receiver_map->elements_kind();
- bool more_general_transition =
- IsMoreGeneralElementsKindTransition(
- previous_receiver_map->elements_kind(),
- transitioned_kind);
- Map* transitioned_previous_map = more_general_transition
- ? previous_receiver_map->LookupElementsTransitionMap(transitioned_kind)
- : NULL;
- if (transitioned_previous_map == *transitioned_receiver_map) {
+ if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) {
// Element family is the same, use the "worst" case map.
store_mode = GetNonTransitioningStoreMode(store_mode);
return isolate()->stub_cache()->ComputeKeyedStoreElement(
transitioned_receiver_map, strict_mode, store_mode);
} else if (*previous_receiver_map == receiver->map()) {
- if (IsGrowStoreMode(store_mode)) {
+ if (IsGrowStoreMode(store_mode) ||
+ store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
+ store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
// A "normal" IC that handles stores can switch to a version that can
- // grow at the end of the array and still stay MONOMORPHIC.
+ // grow at the end of the array, handle OOB accesses or copy COW arrays
+ // and still stay MONOMORPHIC.
return isolate()->stub_cache()->ComputeKeyedStoreElement(
receiver_map, strict_mode, store_mode);
}
@@ -1761,6 +1774,26 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
}
}
+ // If the store mode isn't the standard mode, make sure that all polymorphic
+ // receivers are either external arrays, or all "normal" arrays. Otherwise,
+ // use the generic stub.
+ if (store_mode != STANDARD_STORE) {
+ int external_arrays = 0;
+ for (int i = 0; i < target_receiver_maps.length(); ++i) {
+ if (target_receiver_maps[i]->has_external_array_elements()) {
+ external_arrays++;
+ }
+ }
+ if (external_arrays != 0 &&
+ external_arrays != target_receiver_maps.length()) {
+ TRACE_GENERIC_IC(isolate(), "KeyedIC",
+ "unsupported combination of external and normal arrays");
+ return strict_mode == kStrictMode
+ ? generic_stub_strict()
+ : generic_stub();
+ }
+ }
+
return isolate()->stub_cache()->ComputeStoreElementPolymorphic(
&target_receiver_maps, store_mode, strict_mode);
}
@@ -1794,7 +1827,7 @@ Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
case STORE_NO_TRANSITION_HANDLE_COW:
case STANDARD_STORE:
case STORE_AND_GROW_NO_TRANSITION:
- return Handle<Map>(receiver->map());
+ return Handle<Map>(receiver->map(), isolate());
}
return Handle<Map>::null();
}
@@ -1813,8 +1846,10 @@ bool IsOutOfBoundsAccess(Handle<JSObject> receiver,
KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
Handle<Object> key,
Handle<Object> value) {
- ASSERT(key->IsSmi());
- int index = Smi::cast(*key)->value();
+ ASSERT(!key->ToSmi()->IsFailure());
+ Smi* smi_key = NULL;
+ key->ToSmi()->To(&smi_key);
+ int index = smi_key->value();
bool oob_access = IsOutOfBoundsAccess(receiver, index);
bool allow_growth = receiver->IsJSArray() && oob_access;
if (allow_growth) {
@@ -1872,6 +1907,10 @@ KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
if (!FLAG_trace_external_array_abuse &&
receiver->map()->has_external_array_elements() && oob_access) {
return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
+ }
+ Heap* heap = receiver->GetHeap();
+ if (receiver->elements()->map() == heap->fixed_cow_array_map()) {
+ return STORE_NO_TRANSITION_HANDLE_COW;
} else {
return STANDARD_STORE;
}
@@ -1910,13 +1949,20 @@ MaybeObject* KeyedStoreIC::Store(State state,
if (miss_mode != MISS_FORCE_GENERIC) {
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ bool key_is_smi_like = key->IsSmi() ||
+ (FLAG_compiled_keyed_stores && !key->ToSmi()->IsFailure());
if (receiver->elements()->map() ==
isolate()->heap()->non_strict_arguments_elements_map()) {
stub = non_strict_arguments_stub();
- } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
+ } else if (key_is_smi_like &&
+ (target() != *non_strict_arguments_stub())) {
KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
stub = StoreElementStub(receiver, store_mode, strict_mode);
+ } else {
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number");
}
+ } else {
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object");
}
} else {
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic");
@@ -1941,19 +1987,20 @@ Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
switch (lookup->type()) {
case FIELD:
return isolate()->stub_cache()->ComputeKeyedStoreField(
- name, receiver, lookup->GetFieldIndex().field_index(),
- Handle<Map>::null(), strict_mode);
+ name, receiver, lookup, Handle<Map>::null(), strict_mode);
case TRANSITION: {
- Handle<Map> transition(lookup->GetTransitionTarget());
+ // Explicitly pass in the receiver map since LookupForWrite may have
+ // stored something else than the receiver in the holder.
+ Handle<Map> transition(
+ lookup->GetTransitionTarget(receiver->map()), isolate());
int descriptor = transition->LastAdded();
DescriptorArray* target_descriptors = transition->instance_descriptors();
PropertyDetails details = target_descriptors->GetDetails(descriptor);
if (details.type() == FIELD && details.attributes() == NONE) {
- int field_index = target_descriptors->GetFieldIndex(descriptor);
return isolate()->stub_cache()->ComputeKeyedStoreField(
- name, receiver, field_index, transition, strict_mode);
+ name, receiver, lookup, transition, strict_mode);
}
// fall through.
}
@@ -2023,7 +2070,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
if (raw_function->is_compiled()) return raw_function;
- Handle<JSFunction> function(raw_function);
+ Handle<JSFunction> function(raw_function, isolate);
JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
return *function;
}
@@ -2074,7 +2121,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- StoreIC ic(isolate);
+ StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
return ic.Store(state,
@@ -2150,7 +2197,22 @@ RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) {
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- KeyedStoreIC ic(isolate);
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
+ Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
+ return ic.Store(state,
+ Code::GetStrictMode(extra_ic_state),
+ args.at<Object>(0),
+ args.at<Object>(1),
+ args.at<Object>(2),
+ MISS);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
return ic.Store(state,
@@ -2165,7 +2227,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
NoHandleAllocation na(isolate);
ASSERT(args.length() == 3);
- KeyedStoreIC ic(isolate);
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
Handle<Object> object = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
@@ -2183,7 +2245,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- KeyedStoreIC ic(isolate);
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
return ic.Store(state,
@@ -2668,7 +2730,8 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
HasInlinedSmiCode(address()), x, y);
ICCompareStub stub(op_, new_left, new_right, state);
if (state == KNOWN_OBJECT) {
- stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map()));
+ stub.set_known_map(
+ Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
}
set_target(*stub.GetCode(isolate()));