| Index: pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
|
| index a22b94d05834802705cdd553967bc85b7c4284fc..d8213e2ca289cebe0d47db8d2d71574239ae4c80 100644
|
| --- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
|
| +++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
|
| @@ -110,50 +110,30 @@ class SsaSimplifyInterceptors extends HBaseVisitor
|
| return graph.thisInstruction;
|
| }
|
|
|
| - ClassElement constantInterceptor = tryComputeConstantInterceptorFromType(
|
| - input.instructionType, interceptedClasses);
|
| -
|
| - if (constantInterceptor == null) return null;
|
| -
|
| - // If we just happen to be in an instance method of the constant
|
| - // interceptor, `this` is a shorter alias.
|
| - if (constantInterceptor == work.element.enclosingClass &&
|
| - graph.thisInstruction != null) {
|
| - return graph.thisInstruction;
|
| - }
|
| -
|
| - ConstantValue constant =
|
| - new InterceptorConstantValue(constantInterceptor.thisType);
|
| - return graph.addConstant(constant, compiler);
|
| - }
|
| -
|
| - ClassElement tryComputeConstantInterceptorFromType(
|
| - TypeMask type,
|
| - Set<ClassElement> interceptedClasses) {
|
| -
|
| + ClassElement constantInterceptor;
|
| ClassWorld classWorld = compiler.world;
|
| JavaScriptBackend backend = compiler.backend;
|
| - if (type.isNullable) {
|
| - if (type.isEmpty) {
|
| - return backend.jsNullClass;
|
| + if (input.canBeNull()) {
|
| + if (input.isNull()) {
|
| + constantInterceptor = backend.jsNullClass;
|
| }
|
| - } else if (type.containsOnlyInt(classWorld)) {
|
| - return backend.jsIntClass;
|
| - } else if (type.containsOnlyDouble(classWorld)) {
|
| - return backend.jsDoubleClass;
|
| - } else if (type.containsOnlyBool(classWorld)) {
|
| - return backend.jsBoolClass;
|
| - } else if (type.containsOnlyString(classWorld)) {
|
| - return backend.jsStringClass;
|
| - } else if (type.satisfies(backend.jsArrayClass, classWorld)) {
|
| - return backend.jsArrayClass;
|
| - } else if (type.containsOnlyNum(classWorld) &&
|
| + } else if (input.isInteger(compiler)) {
|
| + constantInterceptor = backend.jsIntClass;
|
| + } else if (input.isDouble(compiler)) {
|
| + constantInterceptor = backend.jsDoubleClass;
|
| + } else if (input.isBoolean(compiler)) {
|
| + constantInterceptor = backend.jsBoolClass;
|
| + } else if (input.isString(compiler)) {
|
| + constantInterceptor = backend.jsStringClass;
|
| + } else if (input.isArray(compiler)) {
|
| + constantInterceptor = backend.jsArrayClass;
|
| + } else if (input.isNumber(compiler) &&
|
| !interceptedClasses.contains(backend.jsIntClass) &&
|
| !interceptedClasses.contains(backend.jsDoubleClass)) {
|
| // If the method being intercepted is not defined in [int] or [double] we
|
| // can safely use the number interceptor. This is because none of the
|
| // [int] or [double] methods are called from a method defined on [num].
|
| - return backend.jsNumberClass;
|
| + constantInterceptor = backend.jsNumberClass;
|
| } else {
|
| // Try to find constant interceptor for a native class. If the receiver
|
| // is constrained to a leaf native class, we can use the class's
|
| @@ -166,13 +146,24 @@ class SsaSimplifyInterceptors extends HBaseVisitor
|
| // for a subclass or call methods defined on a subclass. Provided the
|
| // code is completely insensitive to the specific instance subclasses, we
|
| // can use the non-leaf class directly.
|
| - ClassElement element = type.singleClass(classWorld);
|
| + ClassElement element = input.instructionType.singleClass(classWorld);
|
| if (element != null && element.isNative) {
|
| - return element;
|
| + constantInterceptor = element;
|
| }
|
| }
|
|
|
| - return null;
|
| + if (constantInterceptor == null) return null;
|
| +
|
| + // If we just happen to be in an instance method of the constant
|
| + // interceptor, `this` is a shorter alias.
|
| + if (constantInterceptor == work.element.enclosingClass &&
|
| + graph.thisInstruction != null) {
|
| + return graph.thisInstruction;
|
| + }
|
| +
|
| + ConstantValue constant =
|
| + new InterceptorConstantValue(constantInterceptor.thisType);
|
| + return graph.addConstant(constant, compiler);
|
| }
|
|
|
| HInstruction findDominator(Iterable<HInstruction> instructions) {
|
| @@ -285,32 +276,6 @@ class SsaSimplifyInterceptors extends HBaseVisitor
|
| return false;
|
| }
|
|
|
| - // Do we have an 'almost constant' interceptor? The receiver could be
|
| - // `null` but not any other JavaScript falsy value, `null` values cause
|
| - // `NoSuchMethodError`s, and if the receiver was not null we would have a
|
| - // constant interceptor `C`. Then we can use `(receiver && C)` for the
|
| - // interceptor.
|
| - if (receiver.canBeNull() && !node.isConditionalConstantInterceptor) {
|
| - if (!interceptedClasses.contains(backend.jsNullClass)) {
|
| - // Can use `(receiver && C)` only if receiver is either null or truthy.
|
| - if (!(receiver.canBePrimitiveNumber(compiler) ||
|
| - receiver.canBePrimitiveBoolean(compiler) ||
|
| - receiver.canBePrimitiveString(compiler))) {
|
| - ClassElement interceptorClass = tryComputeConstantInterceptorFromType(
|
| - receiver.instructionType.nonNullable(), interceptedClasses);
|
| - if (interceptorClass != null) {
|
| - HInstruction constantInstruction =
|
| - graph.addConstant(
|
| - new InterceptorConstantValue(interceptorClass.thisType),
|
| - compiler);
|
| - node.conditionalConstantInterceptor = constantInstruction;
|
| - constantInstruction.usedBy.add(node);
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| // Try creating a one-shot interceptor or optimized is-check
|
| if (compiler.hasIncrementalSupport) return false;
|
| if (node.usedBy.length != 1) return false;
|
|
|