Chromium Code Reviews| Index: src/compiler/js-native-context-specialization.cc |
| diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc |
| index 71597d4683ab8e9d0284d8865f1527843f0ff245..750b75725903be87dfa754348928cbdfdfdd6305 100644 |
| --- a/src/compiler/js-native-context-specialization.cc |
| +++ b/src/compiler/js-native-context-specialization.cc |
| @@ -569,37 +569,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { |
| Handle<JSObject> holder; |
| if (access_info.holder().ToHandle(&holder)) { |
| this_value = jsgraph()->Constant(holder); |
| - for (auto i = access_info.receiver_type()->Classes(); !i.Done(); |
| - i.Advance()) { |
| - Handle<Map> map = i.Current(); |
| - PrototypeIterator j(map); |
| - while (true) { |
| - // Check that the {prototype} still has the same map. For stable |
| - // maps, we can add a stability dependency on the prototype map; |
| - // for everything else we need to perform a map check at runtime. |
| - Handle<JSReceiver> prototype = |
| - PrototypeIterator::GetCurrent<JSReceiver>(j); |
| - if (prototype->map()->is_stable()) { |
| - dependencies()->AssumeMapStable( |
| - handle(prototype->map(), isolate())); |
| - } else { |
| - Node* prototype_map = this_effect = graph()->NewNode( |
| - simplified()->LoadField(AccessBuilder::ForMap()), |
| - jsgraph()->Constant(prototype), this_effect, this_control); |
| - Node* check = graph()->NewNode( |
| - simplified()->ReferenceEqual(Type::Internal()), prototype_map, |
| - jsgraph()->Constant(handle(prototype->map(), isolate()))); |
| - Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
| - check, this_control); |
| - exit_controls.push_back( |
| - graph()->NewNode(common()->IfFalse(), branch)); |
| - this_control = graph()->NewNode(common()->IfTrue(), branch); |
| - } |
| - // Stop once we get to the holder. |
| - if (prototype.is_identical_to(holder)) break; |
| - j.Advance(); |
| - } |
| - } |
| + AssumePrototypesStable(receiver_type, holder); |
| } |
| // Generate the actual property access. |
| @@ -782,37 +752,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { |
| // Determine actual holder and perform prototype chain checks. |
| Handle<JSObject> holder; |
| if (access_info.holder().ToHandle(&holder)) { |
| - for (auto i = access_info.receiver_type()->Classes(); !i.Done(); |
| - i.Advance()) { |
| - Handle<Map> map = i.Current(); |
| - PrototypeIterator j(map); |
| - while (true) { |
| - // Check that the {prototype} still has the same map. For stable |
| - // maps, we can add a stability dependency on the prototype map; |
| - // for everything else we need to perform a map check at runtime. |
| - Handle<JSReceiver> prototype = |
| - PrototypeIterator::GetCurrent<JSReceiver>(j); |
| - if (prototype->map()->is_stable()) { |
| - dependencies()->AssumeMapStable( |
| - handle(prototype->map(), isolate())); |
| - } else { |
| - Node* prototype_map = this_effect = graph()->NewNode( |
| - simplified()->LoadField(AccessBuilder::ForMap()), |
| - jsgraph()->Constant(prototype), this_effect, this_control); |
| - Node* check = graph()->NewNode( |
| - simplified()->ReferenceEqual(Type::Internal()), prototype_map, |
| - jsgraph()->Constant(handle(prototype->map(), isolate()))); |
| - Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
| - check, this_control); |
| - exit_controls.push_back( |
| - graph()->NewNode(common()->IfFalse(), branch)); |
| - this_control = graph()->NewNode(common()->IfTrue(), branch); |
| - } |
| - // Stop once we get to the holder. |
| - if (prototype.is_identical_to(holder)) break; |
| - j.Advance(); |
| - } |
| - } |
| + AssumePrototypesStable(receiver_type, holder); |
| } |
|
Toon Verwaest
2015/10/23 13:45:40
What Object.prototype.x? Object.prototype has a nu
Benedikt Meurer
2015/10/23 13:56:26
NotFound case is not implemented.
|
| // Generate the actual property access. |
| @@ -951,6 +891,25 @@ bool JSNativeContextSpecialization::LookupInScriptContextTable( |
| } |
| +void JSNativeContextSpecialization::AssumePrototypesStable( |
| + Type* receiver_type, Handle<JSObject> holder) { |
| + // Determine actual holder and perform prototype chain checks. |
| + for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) { |
| + Handle<Map> const map = i.Current(); |
| + for (PrototypeIterator j(map);; j.Advance()) { |
|
Jarin
2015/10/23 13:09:34
Does not it make sense to dcheck that we are not a
|
| + // Check that the {prototype} still has the same map. All prototype |
| + // maps are guaranteed to be stable, so it's sufficient to add a |
| + // stability dependency here. |
| + Handle<JSReceiver> const prototype = |
| + PrototypeIterator::GetCurrent<JSReceiver>(j); |
| + dependencies()->AssumeMapStable(handle(prototype->map(), isolate())); |
| + // Stop once we get to the holder. |
| + if (prototype.is_identical_to(holder)) break; |
| + } |
| + } |
| +} |
| + |
| + |
| Graph* JSNativeContextSpecialization::graph() const { |
| return jsgraph()->graph(); |
| } |