Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
index 4f5164c66add32423595151cec9029615245ecc9..e49fd66228c3bbcc9d788a4ecc59cb41b193851b 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -849,6 +849,11 @@ class TransformingVisitor extends LeafVisitor { |
} |
} |
+ /// Returns the possible targets of [selector] when invoked on a receiver |
+ /// of type [receiverType]. |
+ Iterable<Element> getAllTargets(TypeMask receiverType, Selector selector) { |
+ return compiler.world.allFunctions.filter(selector, receiverType); |
+ } |
/************************* CALL EXPRESSIONS *************************/ |
@@ -882,8 +887,23 @@ class TransformingVisitor extends LeafVisitor { |
// Equality is special due to its treatment of null values and the |
// fact that Dart-null corresponds to both JS-null and JS-undefined. |
// Please see documentation for IsFalsy, StrictEq, and LooseEq. |
- if (lattice.isDefinitelyNumStringBool(left, allowNull: true) || |
- right.isNullConstant) { |
+ if (left.isNullConstant || right.isNullConstant) { |
asgerf
2015/08/12 09:34:06
The check on left is technically redundant, since
|
+ return replaceWithBinary(BuiltinOperator.Identical, |
+ leftArg, rightArg); |
+ } |
+ // There are several implementations of == that behave like identical. |
+ // Specialize it if we definitely call one of those. |
+ bool behavesLikeIdentical = true; |
+ for (Element target in getAllTargets(left.type, node.selector)) { |
+ ClassElement clazz = target.enclosingClass.declaration; |
+ if (clazz != compiler.world.objectClass && |
+ clazz != backend.jsInterceptorClass && |
+ clazz != backend.jsNullClass) { |
+ behavesLikeIdentical = false; |
+ break; |
+ } |
+ } |
+ if (behavesLikeIdentical) { |
return replaceWithBinary(BuiltinOperator.Identical, |
leftArg, rightArg); |
} |