Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index cfa740b1051c76355cec051a0e06665e6b1a44d7..d036b343d83c90b602686287c463bc4b6855b2e0 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -857,18 +857,15 @@ Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { |
return stub.GetCode(); |
} |
-Handle<Object> LoadIC::SimpleFieldLoadFromPrototype(FieldIndex index, |
- Handle<Map> receiver_map, |
- Handle<JSObject> holder) { |
- if (!FLAG_tf_load_ic_stub) return Handle<Object>::null(); |
- |
+bool LoadIC::IsPrototypeValidityCellCheckEnough(Handle<Map> receiver_map, |
+ Handle<JSObject> holder) { |
DCHECK(holder->HasFastProperties()); |
// The following kinds of receiver maps require custom handler compilation. |
if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap() || |
receiver_map->IsJSGlobalObjectMap() || |
receiver_map->is_dictionary_map()) { |
- return Handle<Object>::null(); |
+ return false; |
} |
// Switch to custom compiled handler if the prototype chain contains global |
@@ -879,21 +876,27 @@ Handle<Object> LoadIC::SimpleFieldLoadFromPrototype(FieldIndex index, |
Map* current_map = current->map(); |
if (current_map->IsJSGlobalObjectMap() || |
current_map->IsJSGlobalProxyMap() || current_map->is_dictionary_map()) { |
- return Handle<Object>::null(); |
+ return false; |
} |
// Only objects that do not require access checks are allowed in stubs. |
DCHECK(!current_map->is_access_check_needed()); |
} |
- TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); |
+ return true; |
+} |
+ |
+Handle<Object> LoadIC::SimpleLoadFromPrototype(Handle<Map> receiver_map, |
+ Handle<JSObject> holder, |
+ Handle<Object> smi_handler) { |
+ DCHECK(IsPrototypeValidityCellCheckEnough(receiver_map, holder)); |
+ |
Handle<Cell> validity_cell = |
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
DCHECK(!validity_cell.is_null()); |
- Handle<Object> handler(SmiHandler::MakeLoadFieldHandler(isolate(), index)); |
Factory* factory = isolate()->factory(); |
Handle<WeakCell> holder_cell = factory->NewWeakCell(holder); |
- return factory->NewTuple3(validity_cell, holder_cell, handler); |
+ return factory->NewTuple3(validity_cell, holder_cell, smi_handler); |
} |
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
@@ -1196,28 +1199,37 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
// -------------- Fields -------------- |
if (lookup->property_details().type() == DATA) { |
FieldIndex field = lookup->GetFieldIndex(); |
+ Handle<Object> smi_handler = SimpleFieldLoad(field); |
if (receiver_is_holder) { |
- return SimpleFieldLoad(field); |
+ return smi_handler; |
} |
- Handle<Object> handler = |
- SimpleFieldLoadFromPrototype(field, map, holder); |
- if (!handler.is_null()) { |
- return handler; |
+ if (FLAG_tf_load_ic_stub && |
+ IsPrototypeValidityCellCheckEnough(map, holder)) { |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); |
+ return SimpleLoadFromPrototype(map, holder, smi_handler); |
} |
break; // Custom-compiled handler. |
} |
// -------------- Constant properties -------------- |
DCHECK(lookup->property_details().type() == DATA_CONSTANT); |
- if (receiver_is_holder) { |
- if (FLAG_tf_load_ic_stub) { |
+ if (FLAG_tf_load_ic_stub) { |
+ Handle<Object> smi_handler = SmiHandler::MakeLoadConstantHandler( |
+ isolate(), lookup->GetConstantIndex()); |
+ if (receiver_is_holder) { |
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); |
- return SmiHandler::MakeLoadConstantHandler( |
- isolate(), lookup->GetConstantIndex()); |
+ return smi_handler; |
+ } |
+ if (IsPrototypeValidityCellCheckEnough(map, holder)) { |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH); |
+ return SimpleLoadFromPrototype(map, holder, smi_handler); |
+ } |
+ } else { |
+ if (receiver_is_holder) { |
+ TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |
+ LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); |
+ return stub.GetCode(); |
} |
- TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |
- LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); |
- return stub.GetCode(); |
} |
break; // Custom-compiled handler. |
} |