| Index: src/ic/ic.cc
|
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
| index 0c38c2b74112b24eb3893147cf0abaf931f554af..02a564892f722ad546945f7419bf1d55167ab14e 100644
|
| --- a/src/ic/ic.cc
|
| +++ b/src/ic/ic.cc
|
| @@ -258,7 +258,11 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
| Handle<String> name) {
|
| if (!IsNameCompatibleWithPrototypeFailure(name)) return false;
|
| Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate());
|
| - maybe_handler_ = target()->FindHandlerForMap(*receiver_map);
|
| + if (UseVector()) {
|
| + maybe_handler_ = nexus()->FindHandlerForMap(receiver_map);
|
| + } else {
|
| + maybe_handler_ = target()->FindHandlerForMap(*receiver_map);
|
| + }
|
|
|
| // The current map wasn't handled yet. There's no reason to stay monomorphic,
|
| // *unless* we're moving from a deprecated map to its replacement, or
|
| @@ -310,7 +314,8 @@ bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) {
|
| 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();
|
| + Name* stub_name =
|
| + UseVector() ? nexus()->FindFirstName() : target()->FindFirstName();
|
| if (*name != stub_name) return false;
|
| }
|
|
|
| @@ -452,7 +457,7 @@ void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host,
|
| void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
| // Type vector based ICs update these statistics at a different time because
|
| // they don't always patch on state change.
|
| - if (target->kind() == Code::CALL_IC) return;
|
| + if (ICUseVector(target->kind())) return;
|
|
|
| Isolate* isolate = target->GetHeap()->isolate();
|
| State old_state = UNINITIALIZED;
|
| @@ -514,8 +519,10 @@ void IC::Clear(Isolate* isolate, Address address,
|
|
|
| switch (target->kind()) {
|
| case Code::LOAD_IC:
|
| + if (FLAG_vector_ics) return;
|
| return LoadIC::Clear(isolate, address, target, constant_pool);
|
| case Code::KEYED_LOAD_IC:
|
| + if (FLAG_vector_ics) return;
|
| return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
|
| case Code::STORE_IC:
|
| return StoreIC::Clear(isolate, address, target, constant_pool);
|
| @@ -537,23 +544,9 @@ void IC::Clear(Isolate* isolate, Address address,
|
| }
|
|
|
|
|
| -template <class Nexus>
|
| -void IC::Clear(Isolate* isolate, Code::Kind kind, Code* host, Nexus* nexus) {
|
| - switch (kind) {
|
| - case Code::CALL_IC:
|
| - return CallIC::Clear(isolate, host, nexus);
|
| - default:
|
| - UNREACHABLE();
|
| - }
|
| -}
|
| -
|
| -
|
| -// Force instantiation of template instances for vector-based IC clearing.
|
| -template void IC::Clear(Isolate*, Code::Kind, Code*, CallICNexus*);
|
| -
|
| -
|
| void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
|
| ConstantPoolArray* constant_pool) {
|
| + DCHECK(!FLAG_vector_ics);
|
| if (IsCleared(target)) return;
|
|
|
| // Make sure to also clear the map used in inline fast cases. If we
|
| @@ -563,6 +556,17 @@ void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
|
| }
|
|
|
|
|
| +void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) {
|
| + if (IsCleared(nexus)) return;
|
| + // Make sure to also clear the map used in inline fast cases. If we
|
| + // do not clear these maps, cached code can keep objects alive
|
| + // through the embedded maps.
|
| + State state = nexus->StateFromFeedback();
|
| + nexus->ConfigurePremonomorphic();
|
| + OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
|
| +}
|
| +
|
| +
|
| void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
|
| // Determine our state.
|
| Object* feedback = nexus->vector()->Get(nexus->slot());
|
| @@ -578,6 +582,7 @@ void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
|
|
|
| void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
|
| ConstantPoolArray* constant_pool) {
|
| + DCHECK(!FLAG_vector_ics);
|
| if (IsCleared(target)) return;
|
| Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
|
| target->extra_ic_state());
|
| @@ -585,6 +590,14 @@ void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
|
| }
|
|
|
|
|
| +void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
|
| + if (IsCleared(nexus)) return;
|
| + State state = nexus->StateFromFeedback();
|
| + nexus->ConfigurePremonomorphic();
|
| + OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
|
| +}
|
| +
|
| +
|
| void StoreIC::Clear(Isolate* isolate, Address address, Code* target,
|
| ConstantPoolArray* constant_pool) {
|
| if (IsCleared(target)) return;
|
| @@ -635,6 +648,71 @@ static bool MigrateDeprecated(Handle<Object> object) {
|
| }
|
|
|
|
|
| +void IC::ConfigureVectorState(IC::State new_state) {
|
| + DCHECK(UseVector());
|
| + if (kind() == Code::LOAD_IC) {
|
| + LoadICNexus* nexus = casted_nexus<LoadICNexus>();
|
| + if (new_state == PREMONOMORPHIC) {
|
| + nexus->ConfigurePremonomorphic();
|
| + } else if (new_state == MEGAMORPHIC) {
|
| + nexus->ConfigureMegamorphic();
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| + } else if (kind() == Code::KEYED_LOAD_IC) {
|
| + KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
| + if (new_state == GENERIC) {
|
| + nexus->ConfigureGeneric();
|
| + } else if (new_state == PREMONOMORPHIC) {
|
| + nexus->ConfigurePremonomorphic();
|
| + } else if (new_state == MEGAMORPHIC) {
|
| + nexus->ConfigureMegamorphic();
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| +
|
| + OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
|
| + new_state);
|
| +}
|
| +
|
| +
|
| +void IC::ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
|
| + Handle<Code> handler) {
|
| + DCHECK(UseVector());
|
| + if (kind() == Code::LOAD_IC) {
|
| + LoadICNexus* nexus = casted_nexus<LoadICNexus>();
|
| + nexus->ConfigureMonomorphic(type, handler);
|
| + } else {
|
| + DCHECK(kind() == Code::KEYED_LOAD_IC);
|
| + KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
| + nexus->ConfigureMonomorphic(name, type, handler);
|
| + }
|
| +
|
| + OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
|
| + MONOMORPHIC);
|
| +}
|
| +
|
| +
|
| +void IC::ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
|
| + CodeHandleList* handlers) {
|
| + DCHECK(UseVector());
|
| + if (kind() == Code::LOAD_IC) {
|
| + LoadICNexus* nexus = casted_nexus<LoadICNexus>();
|
| + nexus->ConfigurePolymorphic(types, handlers);
|
| + } else {
|
| + DCHECK(kind() == Code::KEYED_LOAD_IC);
|
| + KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
|
| + nexus->ConfigurePolymorphic(name, types, handlers);
|
| + }
|
| +
|
| + OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
|
| + POLYMORPHIC);
|
| +}
|
| +
|
| +
|
| MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
|
| // If the object is undefined or null it's illegal to try to get any
|
| // of its properties; throw a TypeError in that case.
|
| @@ -648,7 +726,11 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
|
| if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
|
| // Rewrite to the generic keyed load stub.
|
| if (FLAG_use_ic) {
|
| - set_target(*KeyedLoadIC::generic_stub(isolate()));
|
| + if (UseVector()) {
|
| + ConfigureVectorState(GENERIC);
|
| + } else {
|
| + set_target(*KeyedLoadIC::generic_stub(isolate()));
|
| + }
|
| TRACE_IC("LoadIC", name);
|
| TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
|
| }
|
| @@ -753,14 +835,22 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
|
|
|
| if (number_of_valid_types >= 4) return false;
|
| if (number_of_types == 0) return false;
|
| - if (!target()->FindHandlers(&handlers, types.length())) return false;
|
| + if (UseVector()) {
|
| + if (!nexus()->FindHandlers(&handlers, types.length())) return false;
|
| + } else {
|
| + if (!target()->FindHandlers(&handlers, types.length())) return false;
|
| + }
|
|
|
| number_of_valid_types++;
|
| if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false;
|
| Handle<Code> ic;
|
| if (number_of_valid_types == 1) {
|
| - ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code,
|
| - extra_ic_state());
|
| + if (UseVector()) {
|
| + ConfigureVectorState(name, receiver_type(), code);
|
| + } else {
|
| + ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code,
|
| + extra_ic_state());
|
| + }
|
| } else {
|
| if (handler_to_overwrite >= 0) {
|
| handlers.Set(handler_to_overwrite, code);
|
| @@ -771,11 +861,17 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
|
| types.Add(type);
|
| handlers.Add(code);
|
| }
|
| - ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers,
|
| - number_of_valid_types, name,
|
| - extra_ic_state());
|
| +
|
| + if (UseVector()) {
|
| + ConfigureVectorState(name, &types, &handlers);
|
| + } else {
|
| + ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers,
|
| + number_of_valid_types, name,
|
| + extra_ic_state());
|
| + }
|
| }
|
| - set_target(*ic);
|
| +
|
| + if (!UseVector()) set_target(*ic);
|
| return true;
|
| }
|
|
|
| @@ -823,9 +919,13 @@ template Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map,
|
|
|
| void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) {
|
| DCHECK(handler->is_handler());
|
| - Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
|
| - kind(), name, receiver_type(), handler, extra_ic_state());
|
| - set_target(*ic);
|
| + if (UseVector()) {
|
| + ConfigureVectorState(name, receiver_type(), handler);
|
| + } else {
|
| + Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
|
| + kind(), name, receiver_type(), handler, extra_ic_state());
|
| + set_target(*ic);
|
| + }
|
| }
|
|
|
|
|
| @@ -870,7 +970,11 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
|
| // same key.
|
| CopyICToMegamorphicCache(name);
|
| }
|
| - set_target(*megamorphic_stub());
|
| + if (UseVector()) {
|
| + ConfigureVectorState(MEGAMORPHIC);
|
| + } else {
|
| + set_target(*megamorphic_stub());
|
| + }
|
| // Fall through.
|
| case MEGAMORPHIC:
|
| UpdateMegamorphicCache(*receiver_type(), *name, *code);
|
| @@ -893,6 +997,10 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
|
|
|
| Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
|
| ExtraICState extra_state) {
|
| + if (FLAG_vector_ics) {
|
| + return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
|
| + }
|
| +
|
| return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state);
|
| }
|
|
|
| @@ -936,6 +1044,7 @@ Handle<Code> LoadIC::megamorphic_stub() {
|
|
|
| Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
|
| ExtraICState extra_state) {
|
| + DCHECK(!FLAG_vector_ics);
|
| return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
|
| }
|
|
|
| @@ -965,7 +1074,11 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
|
| 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.
|
| - set_target(*pre_monomorphic_stub());
|
| + if (UseVector()) {
|
| + ConfigureVectorState(PREMONOMORPHIC);
|
| + } else {
|
| + set_target(*pre_monomorphic_stub());
|
| + }
|
| TRACE_IC("LoadIC", lookup->name());
|
| return;
|
| }
|
| @@ -1228,11 +1341,19 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
|
|
|
|
|
| Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| + Handle<Code> null_handle;
|
| Handle<Map> receiver_map(receiver->map(), isolate());
|
| MapHandleList target_receiver_maps;
|
| TargetMaps(&target_receiver_maps);
|
|
|
| +
|
| if (target_receiver_maps.length() == 0) {
|
| + if (FLAG_vector_ics) {
|
| + Handle<Code> handler =
|
| + PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
|
| + ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler);
|
| + return null_handle;
|
| + }
|
| return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
|
| }
|
|
|
| @@ -1247,6 +1368,12 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| IsMoreGeneralElementsKindTransition(
|
| target_receiver_maps.at(0)->elements_kind(),
|
| Handle<JSObject>::cast(receiver)->GetElementsKind())) {
|
| + if (FLAG_vector_ics) {
|
| + Handle<Code> handler =
|
| + PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
|
| + ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler);
|
| + return null_handle;
|
| + }
|
| return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
|
| }
|
|
|
| @@ -1258,6 +1385,10 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| // If the miss wasn't due to an unseen map, a polymorphic stub
|
| // won't help, use the generic stub.
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
|
| + if (FLAG_vector_ics) {
|
| + ConfigureVectorState(GENERIC);
|
| + return null_handle;
|
| + }
|
| return generic_stub();
|
| }
|
|
|
| @@ -1265,9 +1396,25 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
|
| // version of the IC.
|
| if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
| TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
|
| + if (FLAG_vector_ics) {
|
| + ConfigureVectorState(GENERIC);
|
| + return null_handle;
|
| + }
|
| return generic_stub();
|
| }
|
|
|
| + if (FLAG_vector_ics) {
|
| + CodeHandleList handlers(target_receiver_maps.length());
|
| + ElementHandlerCompiler compiler(isolate());
|
| + compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
|
| + TypeHandleList types(target_receiver_maps.length());
|
| + for (int i = 0; i < target_receiver_maps.length(); i++) {
|
| + types.Add(HeapType::Class(target_receiver_maps.at(i), isolate()));
|
| + }
|
| + ConfigureVectorState(Handle<Name>::null(), &types, &handlers);
|
| + return null_handle;
|
| + }
|
| +
|
| return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
|
| }
|
|
|
| @@ -1303,11 +1450,14 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
|
| }
|
|
|
| if (!is_target_set()) {
|
| - Code* generic = *generic_stub();
|
| - if (*stub == generic) {
|
| - TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
|
| + if (!FLAG_vector_ics) {
|
| + Code* generic = *generic_stub();
|
| + if (*stub == generic) {
|
| + TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
|
| + }
|
| +
|
| + set_target(*stub);
|
| }
|
| - set_target(*stub);
|
| TRACE_IC("LoadIC", key);
|
| }
|
|
|
| @@ -2158,13 +2308,25 @@ RUNTIME_FUNCTION(CallIC_Customization_Miss) {
|
| RUNTIME_FUNCTION(LoadIC_Miss) {
|
| TimerEventScope<TimerEventIcMiss> timer(isolate);
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 2);
|
| - LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| Handle<Object> receiver = args.at<Object>(0);
|
| Handle<Name> key = args.at<Name>(1);
|
| - ic.UpdateState(receiver, key);
|
| Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| +
|
| + if (FLAG_vector_ics) {
|
| + DCHECK(args.length() == 4);
|
| + Handle<Smi> slot = args.at<Smi>(2);
|
| + Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
|
| + FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
| + LoadICNexus nexus(vector, vector_slot);
|
| + LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + } else {
|
| + DCHECK(args.length() == 2);
|
| + LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + }
|
| return *result;
|
| }
|
|
|
| @@ -2173,13 +2335,26 @@ RUNTIME_FUNCTION(LoadIC_Miss) {
|
| RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
|
| TimerEventScope<TimerEventIcMiss> timer(isolate);
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 2);
|
| - KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| Handle<Object> receiver = args.at<Object>(0);
|
| Handle<Object> key = args.at<Object>(1);
|
| - ic.UpdateState(receiver, key);
|
| Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| +
|
| + if (FLAG_vector_ics) {
|
| + DCHECK(args.length() == 4);
|
| + Handle<Smi> slot = args.at<Smi>(2);
|
| + Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
|
| + FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
| + KeyedLoadICNexus nexus(vector, vector_slot);
|
| + KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + } else {
|
| + DCHECK(args.length() == 2);
|
| + KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + }
|
| +
|
| return *result;
|
| }
|
|
|
| @@ -2187,13 +2362,26 @@ RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
|
| RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) {
|
| TimerEventScope<TimerEventIcMiss> timer(isolate);
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 2);
|
| - KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
| Handle<Object> receiver = args.at<Object>(0);
|
| Handle<Object> key = args.at<Object>(1);
|
| - ic.UpdateState(receiver, key);
|
| Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| +
|
| + if (FLAG_vector_ics) {
|
| + DCHECK(args.length() == 4);
|
| + Handle<Smi> slot = args.at<Smi>(2);
|
| + Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
|
| + FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
| + KeyedLoadICNexus nexus(vector, vector_slot);
|
| + KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + } else {
|
| + DCHECK(args.length() == 2);
|
| + KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + }
|
| +
|
| return *result;
|
| }
|
|
|
| @@ -2685,7 +2873,7 @@ static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
|
| // If the load is non-contextual, just return the undefined result.
|
| // Note that both keyed and non-keyed loads may end up here.
|
| HandleScope scope(isolate);
|
| - LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
| + LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
|
| if (ic.contextual_mode() != CONTEXTUAL) {
|
| return isolate->heap()->undefined_value();
|
| }
|
| @@ -2767,13 +2955,26 @@ RUNTIME_FUNCTION(LoadElementWithInterceptor) {
|
| RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) {
|
| TimerEventScope<TimerEventIcMiss> timer(isolate);
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 2);
|
| - LoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
| Handle<Object> receiver = args.at<Object>(0);
|
| Handle<Name> key = args.at<Name>(1);
|
| - ic.UpdateState(receiver, key);
|
| Handle<Object> result;
|
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| +
|
| + if (FLAG_vector_ics) {
|
| + DCHECK(args.length() == 4);
|
| + Handle<Smi> slot = args.at<Smi>(2);
|
| + Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
|
| + FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
|
| + LoadICNexus nexus(vector, vector_slot);
|
| + LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + } else {
|
| + DCHECK(args.length() == 2);
|
| + LoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
| + ic.UpdateState(receiver, key);
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
|
| + }
|
| +
|
| return *result;
|
| }
|
|
|
|
|