Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index 642f4325b41f1cbe9751da6b596a7c7eb4048344..fe474cdf956f27c4685e28bb90f241ba2c6b8f6f 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -541,35 +541,33 @@ void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) { |
OnTypeFeedbackChanged(isolate(), get_host()); |
} |
- |
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
- Handle<Code> handler) { |
+ Handle<Object> handler) { |
DCHECK(UseVector()); |
if (kind() == Code::LOAD_IC) { |
LoadICNexus* nexus = casted_nexus<LoadICNexus>(); |
nexus->ConfigureMonomorphic(map, handler); |
} else if (kind() == Code::LOAD_GLOBAL_IC) { |
LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); |
- nexus->ConfigureHandlerMode(handler); |
+ nexus->ConfigureHandlerMode(Handle<Code>::cast(handler)); |
} else if (kind() == Code::KEYED_LOAD_IC) { |
KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); |
- nexus->ConfigureMonomorphic(name, map, handler); |
+ nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler)); |
} else if (kind() == Code::STORE_IC) { |
StoreICNexus* nexus = casted_nexus<StoreICNexus>(); |
- nexus->ConfigureMonomorphic(map, handler); |
+ nexus->ConfigureMonomorphic(map, Handle<Code>::cast(handler)); |
} else { |
DCHECK(kind() == Code::KEYED_STORE_IC); |
KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); |
- nexus->ConfigureMonomorphic(name, map, handler); |
+ nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler)); |
} |
vector_set_ = true; |
OnTypeFeedbackChanged(isolate(), get_host()); |
} |
- |
void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, |
- CodeHandleList* handlers) { |
+ List<Handle<Object>>* handlers) { |
DCHECK(UseVector()); |
if (kind() == Code::LOAD_IC) { |
LoadICNexus* nexus = casted_nexus<LoadICNexus>(); |
@@ -686,13 +684,15 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
return true; |
} |
- |
-bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { |
- if (!code->is_handler()) return false; |
+bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code) { |
+ DCHECK(code->IsSmi() || code->IsCode()); |
+ if (!code->IsSmi() && !Code::cast(*code)->is_handler()) { |
+ return false; |
+ } |
if (is_keyed() && state() != RECOMPUTE_HANDLER) return false; |
Handle<Map> map = receiver_map(); |
MapHandleList maps; |
- CodeHandleList handlers; |
+ List<Handle<Object>> handlers; |
TargetMaps(&maps); |
int number_of_maps = maps.length(); |
@@ -747,16 +747,16 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { |
return true; |
} |
- |
-void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { |
- DCHECK(handler->is_handler()); |
+void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) { |
+ DCHECK(handler->IsSmi() || |
+ (handler->IsCode() && Handle<Code>::cast(handler)->is_handler())); |
ConfigureVectorState(name, receiver_map(), handler); |
} |
void IC::CopyICToMegamorphicCache(Handle<Name> name) { |
MapHandleList maps; |
- CodeHandleList handlers; |
+ List<Handle<Object>> handlers; |
TargetMaps(&maps); |
if (!nexus()->FindHandlers(&handlers, maps.length())) return; |
for (int i = 0; i < maps.length(); i++) { |
@@ -780,8 +780,8 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { |
return transitioned_map == target_map; |
} |
- |
-void IC::PatchCache(Handle<Name> name, Handle<Code> code) { |
+void IC::PatchCache(Handle<Name> name, Handle<Object> code) { |
+ DCHECK(code->IsCode() || (kind() == Code::LOAD_IC && code->IsSmi())); |
switch (state()) { |
case UNINITIALIZED: |
case PREMONOMORPHIC: |
@@ -849,8 +849,11 @@ Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, |
: isolate->builtins()->KeyedStoreIC_Megamorphic(); |
} |
- |
-Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { |
+Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { |
+ if (kind() == Code::LOAD_IC && FLAG_tf_load_ic_stub) { |
+ return handle(Smi::FromInt(index.GetLoadByFieldOffset()), isolate()); |
+ } |
+ DCHECK(kind() == Code::KEYED_LOAD_IC || !FLAG_tf_load_ic_stub); |
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); |
LoadFieldStub stub(isolate(), index); |
return stub.GetCode(); |
@@ -905,7 +908,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { |
return; |
} |
- Handle<Code> code; |
+ Handle<Object> code; |
if (lookup->state() == LookupIterator::JSPROXY || |
lookup->state() == LookupIterator::ACCESS_CHECK) { |
code = slow_stub(); |
@@ -980,15 +983,31 @@ StubCache* IC::stub_cache() { |
return nullptr; |
} |
-void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { |
- stub_cache()->Set(name, map, code); |
+void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* code) { |
+ if (code->IsSmi()) { |
+ // TODO(jkummerow): Support Smis in the code cache. |
+ Handle<Map> map_handle(map, isolate()); |
+ Handle<Name> name_handle(name, isolate()); |
+ FieldIndex index = |
+ FieldIndex::ForLoadByFieldOffset(map, Smi::cast(code)->value()); |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); |
+ LoadFieldStub stub(isolate(), index); |
+ Code* handler = *stub.GetCode(); |
+ stub_cache()->Set(*name_handle, *map_handle, handler); |
+ return; |
+ } |
+ DCHECK(code->IsCode()); |
+ stub_cache()->Set(name, map, Code::cast(code)); |
} |
- |
-Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { |
+Handle<Object> IC::ComputeHandler(LookupIterator* lookup, |
+ Handle<Object> value) { |
// Try to find a globally shared handler stub. |
- Handle<Code> code = GetMapIndependentHandler(lookup); |
- if (!code.is_null()) return code; |
+ Handle<Object> handler_or_index = GetMapIndependentHandler(lookup); |
+ if (!handler_or_index.is_null()) { |
+ DCHECK(handler_or_index->IsCode() || handler_or_index->IsSmi()); |
+ return handler_or_index; |
+ } |
// Otherwise check the map's handler cache for a map-specific handler, and |
// compile one if the cache comes up empty. |
@@ -1007,12 +1026,12 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { |
stub_holder_map = receiver_map(); |
} |
- code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), |
- flag); |
+ Handle<Code> code = PropertyHandlerCompiler::Find( |
+ lookup->name(), stub_holder_map, kind(), flag); |
// Use the cached value if it exists, and if it is different from the |
// handler that just missed. |
if (!code.is_null()) { |
- Handle<Code> handler; |
+ Handle<Object> handler; |
if (maybe_handler_.ToHandle(&handler)) { |
if (!handler.is_identical_to(code)) { |
TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); |
@@ -1044,7 +1063,7 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { |
return code; |
} |
-Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
+Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
Handle<Object> receiver = lookup->GetReceiver(); |
if (receiver->IsString() && |
Name::Equals(isolate()->factory()->length_string(), lookup->name())) { |
@@ -1388,7 +1407,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) { |
return; |
} |
- CodeHandleList handlers(target_receiver_maps.length()); |
+ List<Handle<Object>> handlers(target_receiver_maps.length()); |
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement); |
ElementHandlerCompiler compiler(isolate()); |
compiler.CompileElementHandlers(&target_receiver_maps, &handlers); |
@@ -1605,7 +1624,8 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, |
if (!use_ic) { |
TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
} |
- Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
+ Handle<Code> code = |
+ use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub(); |
PatchCache(lookup->name(), code); |
TRACE_IC("StoreIC", lookup->name()); |
@@ -1627,7 +1647,7 @@ static Handle<Code> PropertyCellStoreHandler( |
return code; |
} |
-Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { |
+Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { |
DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |
// This is currently guaranteed by checks in StoreIC::Store. |