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

Unified Diff: src/ic/ic.cc

Issue 754303003: Flesh out vector ic state query and set mechanisms. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Patch one. Created 6 years, 1 month 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
Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 0c38c2b74112b24eb3893147cf0abaf931f554af..cde608ac9c059dbf74c3131618499351597276e8 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,11 @@ 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 (target->kind() == Code::CALL_IC ||
+ (FLAG_vector_ics && (target->kind() == Code::LOAD_IC ||
Jakob Kummerow 2014/11/26 15:14:14 Can you re-use UseVector() here instead of duplica
mvstanton 2014/11/27 13:09:26 Done.
+ target->kind() == Code::KEYED_LOAD_IC))) {
+ return;
+ }
Isolate* isolate = target->GetHeap()->isolate();
State old_state = UNINITIALIZED;
@@ -514,8 +523,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 +548,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 +560,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 +586,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 +594,15 @@ void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
}
+void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
+ if (IsCleared(nexus)) return;
+ // Determine our state.
Jakob Kummerow 2014/11/26 15:14:15 nit: I don't think this comment adds much value.
mvstanton 2014/11/27 13:09:26 Done.
+ nexus->ConfigurePremonomorphic();
+ State state = nexus->StateFromFeedback();
Jakob Kummerow 2014/11/26 15:14:14 Save the previous state before calling ConfigurePr
mvstanton 2014/11/27 13:09:26 doh! good catch, thanks!
+ 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 +653,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 +731,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 +840,23 @@ 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()) {
+ DCHECK(kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC);
Jakob Kummerow 2014/11/26 15:14:15 You can drop this DCHECK; ConfigureVectorState() c
mvstanton 2014/11/27 13:09:26 Done.
+ 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 +867,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 +925,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 +976,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 +1003,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 +1050,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 +1080,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;
}
@@ -1233,6 +1352,12 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
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 target();
Jakob Kummerow 2014/11/26 15:14:15 Consider "return Handle<Code>::null();" to make it
mvstanton 2014/11/27 13:09:26 I think this use of target() solved a problem for
+ }
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
}
@@ -1247,6 +1372,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 target();
+ }
return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
}
@@ -1258,6 +1389,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 target();
+ }
return generic_stub();
}
@@ -1265,9 +1400,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 target();
+ }
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 target();
+ }
+
return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
}
@@ -1303,11 +1454,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 +2312,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 (args.length() == 4) {
+ DCHECK(FLAG_vector_ics);
Jakob Kummerow 2014/11/26 15:14:14 I think I'd swap this around: if (FLAG_vector_ics
mvstanton 2014/11/27 13:09:26 Cool. This is a relic of a time in the work when b
+ 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 +2339,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 (args.length() == 4) {
+ DCHECK(FLAG_vector_ics);
Jakob Kummerow 2014/11/26 15:14:15 again
mvstanton 2014/11/27 13:09:26 Done.
+ 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 +2366,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 (args.length() == 4) {
+ DCHECK(FLAG_vector_ics);
Jakob Kummerow 2014/11/26 15:14:14 again
mvstanton 2014/11/27 13:09:26 Done.
+ 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 +2877,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 +2959,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 (args.length() == 4) {
+ DCHECK(FLAG_vector_ics);
Jakob Kummerow 2014/11/26 15:14:14 again
mvstanton 2014/11/27 13:09:26 Done.
+ 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;
}

Powered by Google App Engine
This is Rietveld 408576698