Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index eea4629d048ca25da6f089495ef9c3643b4aa8d3..458d90d73e676c7165943cbd67d32ab03f425cbb 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -838,6 +838,52 @@ 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(); |
Jakob Kummerow
2016/10/13 11:59:26
nit: you probably want to make the flag non-readon
Igor Sheludko
2016/10/13 13:20:38
We should just remove this flag once you remove th
|
+ |
+ DCHECK(holder->HasFastProperties()); |
+ |
+ // Primitive maps require custom handler compilation. |
+ if (receiver_map->IsPrimitiveMap()) { |
+ return Handle<Object>::null(); |
+ } |
+ |
+ // Switch to custom compiled handler if the prototype chain contains global |
+ // or dictionary objects. |
+ { |
+ Map* current_map = *receiver_map; |
+ Map* holder_map = holder->map(); |
+ while (current_map != holder_map) { |
+ // Only global objects and objects that do not require access |
+ // checks are allowed in stubs. |
+ DCHECK(current_map->IsJSGlobalProxyMap() || |
+ !current_map->is_access_check_needed()); |
+ |
+ if (current_map->IsJSGlobalObjectMap() || |
+ current_map->IsJSGlobalProxyMap() || |
+ current_map->is_dictionary_map()) { |
+ return Handle<Object>::null(); |
+ } |
+ // Go to the next object in the prototype chain. |
+ JSObject* prototype = JSObject::cast(current_map->prototype()); |
Jakob Kummerow
2016/10/13 11:59:26
nit: use a PrototypeIterator please
Igor Sheludko
2016/10/13 13:20:38
Done.
|
+ current_map = prototype->map(); |
+ } |
+ } |
+ |
+ Handle<Cell> validity_cell = |
+ Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
+ DCHECK(!validity_cell.is_null()); |
+ |
+ Handle<Object> handler = SimpleFieldLoad(index); |
+ DCHECK(handler->IsSmi()); |
+ |
+ Factory* factory = isolate()->factory(); |
+ |
+ Handle<WeakCell> holder_cell = factory->NewWeakCell(holder); |
+ return isolate()->factory()->NewTuple3(validity_cell, holder_cell, handler); |
Jakob Kummerow
2016/10/13 11:59:26
nit: s/isolate()->factory()/factory/
Igor Sheludko
2016/10/13 13:20:38
Done.
|
+} |
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
DCHECK(lookup->state() == LookupIterator::ACCESSOR); |
@@ -1142,6 +1188,11 @@ Handle<Object> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { |
if (receiver_is_holder) { |
return SimpleFieldLoad(field); |
} |
+ Handle<Object> handler = |
+ SimpleFieldLoadFromPrototype(field, map, holder); |
+ if (!handler.is_null()) { |
+ return handler; |
+ } |
break; // Custom-compiled handler. |
} |