Chromium Code Reviews| 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. |
| } |