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(); |
} |