Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(964)

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 2943293002: [turbofan] Do constant-folding of JSHasInPrototypeChain early. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/js-typed-lowering.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 48421c9b442b4bc6d8399fa4341707c4dc1a9b2b..742660ffb271b83393c44e1b55c17b4b12863505 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -76,6 +76,8 @@ Reduction JSNativeContextSpecialization::Reduce(Node* node) {
return ReduceJSGetSuperConstructor(node);
case IrOpcode::kJSInstanceOf:
return ReduceJSInstanceOf(node);
+ case IrOpcode::kJSHasInPrototypeChain:
+ return ReduceJSHasInPrototypeChain(node);
case IrOpcode::kJSOrdinaryHasInstance:
return ReduceJSOrdinaryHasInstance(node);
case IrOpcode::kJSLoadContext:
@@ -257,6 +259,80 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
return NoChange();
}
+JSNativeContextSpecialization::InferHasInPrototypeChainResult
+JSNativeContextSpecialization::InferHasInPrototypeChain(
+ Node* receiver, Node* effect, Handle<HeapObject> prototype) {
+ ZoneHandleSet<Map> receiver_maps;
+ NodeProperties::InferReceiverMapsResult result =
+ NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps);
+ if (result == NodeProperties::kNoReceiverMaps) return kMayBeInPrototypeChain;
+
+ // Check if either all or none of the {receiver_maps} have the given
+ // {prototype} in their prototype chain.
+ bool all = true;
+ bool none = true;
+ for (size_t i = 0; i < receiver_maps.size(); ++i) {
+ Handle<Map> receiver_map = receiver_maps[i];
+ if (receiver_map->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE) {
+ return kMayBeInPrototypeChain;
+ }
+ if (result == NodeProperties::kUnreliableReceiverMaps) {
+ // In case of an unreliable {result} we need to ensure that all
+ // {receiver_maps} are stable, because otherwise we cannot trust
+ // the {receiver_maps} information, since arbitrary side-effects
+ // may have happened.
+ if (!receiver_map->is_stable()) {
+ return kMayBeInPrototypeChain;
+ }
+ }
+ for (PrototypeIterator j(receiver_map);; j.Advance()) {
+ if (j.IsAtEnd()) {
+ all = false;
+ break;
+ }
+ Handle<HeapObject> const current =
+ PrototypeIterator::GetCurrent<HeapObject>(j);
+ if (current.is_identical_to(prototype)) {
+ none = false;
+ break;
+ }
+ if (!current->map()->is_stable() ||
+ current->map()->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE) {
+ return kMayBeInPrototypeChain;
+ }
+ }
+ }
+ DCHECK_IMPLIES(all, !none);
+ DCHECK_IMPLIES(none, !all);
+
+ if (all) return kIsInPrototypeChain;
+ if (none) return kIsNotInPrototypeChain;
+ return kMayBeInPrototypeChain;
+}
+
+Reduction JSNativeContextSpecialization::ReduceJSHasInPrototypeChain(
+ Node* node) {
+ DCHECK_EQ(IrOpcode::kJSHasInPrototypeChain, node->opcode());
+ Node* value = NodeProperties::GetValueInput(node, 0);
+ Node* prototype = NodeProperties::GetValueInput(node, 1);
+ Node* effect = NodeProperties::GetEffectInput(node);
+
+ // Check if we can constant-fold the prototype chain walk
+ // for the given {value} and the {prototype}.
+ HeapObjectMatcher m(prototype);
+ if (m.HasValue()) {
+ InferHasInPrototypeChainResult result =
+ InferHasInPrototypeChain(value, effect, m.Value());
+ if (result != kMayBeInPrototypeChain) {
+ Node* value = jsgraph()->BooleanConstant(result == kIsInPrototypeChain);
+ ReplaceWithValue(node, value);
+ return Replace(value);
+ }
+ }
+
+ return NoChange();
+}
+
Reduction JSNativeContextSpecialization::ReduceJSOrdinaryHasInstance(
Node* node) {
DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode());
@@ -302,7 +378,8 @@ Reduction JSNativeContextSpecialization::ReduceJSOrdinaryHasInstance(
NodeProperties::ReplaceValueInput(node, object, 0);
NodeProperties::ReplaceValueInput(node, prototype, 1);
NodeProperties::ChangeOp(node, javascript()->HasInPrototypeChain());
- return Changed(node);
+ Reduction const reduction = ReduceJSHasInPrototypeChain(node);
+ return reduction.Changed() ? reduction : Changed(node);
}
}
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/js-typed-lowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698