| Index: pkg/compiler/lib/src/ssa/codegen_helpers.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
|
| index 5a0f55803394c8bc279e2ea8f3fea59c293a7c39..dca34c5016f91460465e5e1c30a635756294c06f 100644
|
| --- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
|
| +++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
|
| @@ -96,49 +96,61 @@ class SsaInstructionSelection extends HBaseVisitor {
|
|
|
| HInstruction visitInvokeDynamic(HInvokeDynamic node) {
|
| if (node.isInterceptedCall) {
|
| - // Calls of the form
|
| - //
|
| - // a.foo$1(a, x)
|
| - //
|
| - // where the interceptor calling convention is used come from recognizing
|
| - // that 'a' is a 'self-interceptor'. If the selector matches only methods
|
| - // that ignore the explicit receiver parameter, replace occurences of the
|
| - // receiver argument with a dummy receiver '0':
|
| - //
|
| - // a.foo$1(a, x) ---> a.foo$1(0, x)
|
| - //
|
| - // This often reduces the number of references to 'a' to one, allowing 'a'
|
| - // to be generated at use to avoid a temporary, e.g.
|
| - //
|
| - // t1 = b.get$thing();
|
| - // t1.foo$1(t1, x)
|
| - // --->
|
| - // b.get$thing().foo$1(0, x)
|
| - //
|
| - Selector selector = node.selector;
|
| - TypeMask mask = node.mask;
|
| + tryReplaceInterceptorWithDummy(node, node.selector, node.mask);
|
| + }
|
| + return node;
|
| + }
|
| +
|
| + HInstruction visitInvokeSuper(HInvokeSuper node) {
|
| + if (node.isInterceptedCall) {
|
| + TypeMask mask = node.getDartReceiver(compiler).instructionType;
|
| + tryReplaceInterceptorWithDummy(node, node.selector, mask);
|
| + }
|
| + return node;
|
| + }
|
| +
|
| + void tryReplaceInterceptorWithDummy(
|
| + HInvoke node, Selector selector, TypeMask mask) {
|
| + // Calls of the form
|
| + //
|
| + // a.foo$1(a, x)
|
| + //
|
| + // where the interceptor calling convention is used come from recognizing
|
| + // that 'a' is a 'self-interceptor'. If the selector matches only methods
|
| + // that ignore the explicit receiver parameter, replace occurences of the
|
| + // receiver argument with a dummy receiver '0':
|
| + //
|
| + // a.foo$1(a, x) ---> a.foo$1(0, x)
|
| + //
|
| + // This often reduces the number of references to 'a' to one, allowing 'a'
|
| + // to be generated at use to avoid a temporary, e.g.
|
| + //
|
| + // t1 = b.get$thing();
|
| + // t1.foo$1(t1, x)
|
| + // --->
|
| + // b.get$thing().foo$1(0, x)
|
| + //
|
| +
|
| + // TODO(15933): Make automatically generated property extraction closures
|
| + // work with the dummy receiver optimization.
|
| + if (selector.isGetter) return;
|
| +
|
| + // This assignment of inputs is uniform for HInvokeDynamic and HInvokeSuper.
|
| + HInstruction interceptor = node.inputs[0];
|
| + HInstruction receiverArgument = node.inputs[1];
|
| +
|
| + if (interceptor.nonCheck() == receiverArgument.nonCheck()) {
|
| if (backend.isInterceptedSelector(selector) &&
|
| !backend.isInterceptedMixinSelector(selector, mask)) {
|
| - HInstruction interceptor = node.inputs[0];
|
| - HInstruction receiverArgument = node.inputs[1];
|
| -
|
| - if (interceptor.nonCheck() == receiverArgument.nonCheck()) {
|
| - // TODO(15933): Make automatically generated property extraction
|
| - // closures work with the dummy receiver optimization.
|
| - if (!selector.isGetter) {
|
| - ConstantValue constant = new SyntheticConstantValue(
|
| - SyntheticConstantKind.DUMMY_INTERCEPTOR,
|
| - receiverArgument.instructionType);
|
| - HConstant dummy = graph.addConstant(constant, compiler);
|
| - receiverArgument.usedBy.remove(node);
|
| - node.inputs[1] = dummy;
|
| - dummy.usedBy.add(node);
|
| - }
|
| - }
|
| + ConstantValue constant = new SyntheticConstantValue(
|
| + SyntheticConstantKind.DUMMY_INTERCEPTOR,
|
| + receiverArgument.instructionType);
|
| + HConstant dummy = graph.addConstant(constant, compiler);
|
| + receiverArgument.usedBy.remove(node);
|
| + node.inputs[1] = dummy;
|
| + dummy.usedBy.add(node);
|
| }
|
| }
|
| -
|
| - return node;
|
| }
|
|
|
| HInstruction visitFieldSet(HFieldSet setter) {
|
|
|