| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'optimizers.dart'; | 5 import 'optimizers.dart'; |
| 6 | 6 |
| 7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
| 8 Selectors; | 8 Selectors; |
| 9 import '../compiler.dart' as dart2js show | 9 import '../compiler.dart' as dart2js show |
| 10 Compiler; | 10 Compiler; |
| 11 import '../constants/constant_system.dart'; | 11 import '../constants/constant_system.dart'; |
| 12 import '../constants/values.dart'; | 12 import '../constants/values.dart'; |
| 13 import '../dart_types.dart' as types; | 13 import '../dart_types.dart' as types; |
| 14 import '../diagnostics/invariant.dart' as dart2js show | 14 import '../diagnostics/invariant.dart' as dart2js show |
| 15 InternalErrorFunction; | 15 InternalErrorFunction; |
| 16 import '../elements/elements.dart'; | 16 import '../elements/elements.dart'; |
| 17 import '../io/source_information.dart' show SourceInformation; | 17 import '../io/source_information.dart' show SourceInformation; |
| 18 import '../js_backend/js_backend.dart' show JavaScriptBackend; | 18 import '../js_backend/js_backend.dart' show JavaScriptBackend, |
| 19 SyntheticConstantKind; |
| 19 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; | 20 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; |
| 20 import '../resolution/access_semantics.dart'; | 21 import '../resolution/access_semantics.dart'; |
| 21 import '../resolution/operators.dart'; | 22 import '../resolution/operators.dart'; |
| 22 import '../resolution/send_structure.dart'; | 23 import '../resolution/send_structure.dart'; |
| 23 import '../tree/tree.dart' as ast; | 24 import '../tree/tree.dart' as ast; |
| 24 import '../types/types.dart'; | 25 import '../types/types.dart'; |
| 25 import '../types/constants.dart' show computeTypeMask; | 26 import '../types/constants.dart' show computeTypeMask; |
| 26 import '../universe/universe.dart'; | 27 import '../universe/universe.dart'; |
| 27 import '../world.dart' show World; | 28 import '../world.dart' show World; |
| 28 import 'cps_fragment.dart'; | 29 import 'cps_fragment.dart'; |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 node.receiverIsNotNull = receiver.isDefinitelyNotNull; | 1603 node.receiverIsNotNull = receiver.isDefinitelyNotNull; |
| 1603 | 1604 |
| 1604 if (isInterceptedSelector(node.selector) && | 1605 if (isInterceptedSelector(node.selector) && |
| 1605 node.receiver.definition == node.arguments[0].definition) { | 1606 node.receiver.definition == node.arguments[0].definition) { |
| 1606 // The receiver and first argument are the same; that means we already | 1607 // The receiver and first argument are the same; that means we already |
| 1607 // determined in visitInterceptor that we are targeting a non-interceptor. | 1608 // determined in visitInterceptor that we are targeting a non-interceptor. |
| 1608 | 1609 |
| 1609 // Check if any of the possible targets depend on the extra receiver | 1610 // Check if any of the possible targets depend on the extra receiver |
| 1610 // argument. Mixins do this, and tear-offs always needs the extra receiver | 1611 // argument. Mixins do this, and tear-offs always needs the extra receiver |
| 1611 // argument because BoundClosure uses it for equality and hash code. | 1612 // argument because BoundClosure uses it for equality and hash code. |
| 1613 // TODO(15933): Make automatically generated property extraction |
| 1614 // closures work with the dummy receiver optimization. |
| 1612 bool needsReceiver(Element target) { | 1615 bool needsReceiver(Element target) { |
| 1613 if (target is! FunctionElement) return false; | 1616 if (target is! FunctionElement) return false; |
| 1614 FunctionElement function = target; | 1617 FunctionElement function = target; |
| 1615 return typeSystem.methodUsesReceiverArgument(function) || | 1618 return typeSystem.methodUsesReceiverArgument(function) || |
| 1616 node.selector.isGetter && !function.isGetter; | 1619 node.selector.isGetter && !function.isGetter; |
| 1617 } | 1620 } |
| 1618 if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) { | 1621 if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) { |
| 1619 // Replace the extra receiver argument with a dummy value if the | 1622 // Replace the extra receiver argument with a dummy value if the |
| 1620 // target definitely does not use it. | 1623 // target definitely does not use it. |
| 1621 Constant dummy = makeConstantPrimitive(new IntConstantValue(0)); | 1624 ConstantValue constant = new SyntheticConstantValue( |
| 1625 SyntheticConstantKind.DUMMY_INTERCEPTOR, |
| 1626 receiver.type); |
| 1627 Constant dummy = makeConstantPrimitive(constant); |
| 1622 insertLetPrim(node, dummy); | 1628 insertLetPrim(node, dummy); |
| 1623 node.arguments[0].unlink(); | 1629 node.arguments[0].unlink(); |
| 1624 node.arguments[0] = new Reference<Primitive>(dummy); | 1630 node.arguments[0] = new Reference<Primitive>(dummy); |
| 1625 } | 1631 } |
| 1626 } | 1632 } |
| 1627 } | 1633 } |
| 1628 | 1634 |
| 1629 void visitTypeCast(TypeCast node) { | 1635 void visitTypeCast(TypeCast node) { |
| 1630 Continuation cont = node.continuation.definition; | 1636 Continuation cont = node.continuation.definition; |
| 1631 | 1637 |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 setValue(node, nonConstant(typeSystem.extendableNativeListType)); | 2475 setValue(node, nonConstant(typeSystem.extendableNativeListType)); |
| 2470 } | 2476 } |
| 2471 | 2477 |
| 2472 void visitLiteralMap(LiteralMap node) { | 2478 void visitLiteralMap(LiteralMap node) { |
| 2473 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, | 2479 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, |
| 2474 // and thus LiteralMap nodes are NonConst. | 2480 // and thus LiteralMap nodes are NonConst. |
| 2475 setValue(node, nonConstant(typeSystem.mapType)); | 2481 setValue(node, nonConstant(typeSystem.mapType)); |
| 2476 } | 2482 } |
| 2477 | 2483 |
| 2478 void visitConstant(Constant node) { | 2484 void visitConstant(Constant node) { |
| 2479 ConstantValue value = node.value; | 2485 setValue(node, constantValue(node.value, typeSystem.getTypeOf(node.value))); |
| 2480 if (value.isDummy || !value.isConstant) { | |
| 2481 // TODO(asgerf): Explain how this happens and why we don't want them. | |
| 2482 setValue(node, nonConstant(typeSystem.getTypeOf(value))); | |
| 2483 } else { | |
| 2484 setValue(node, constantValue(value, typeSystem.getTypeOf(value))); | |
| 2485 } | |
| 2486 } | 2486 } |
| 2487 | 2487 |
| 2488 void visitCreateFunction(CreateFunction node) { | 2488 void visitCreateFunction(CreateFunction node) { |
| 2489 throw 'CreateFunction is not used'; | 2489 throw 'CreateFunction is not used'; |
| 2490 } | 2490 } |
| 2491 | 2491 |
| 2492 void visitGetMutable(GetMutable node) { | 2492 void visitGetMutable(GetMutable node) { |
| 2493 setValue(node, getValue(node.variable.definition)); | 2493 setValue(node, getValue(node.variable.definition)); |
| 2494 } | 2494 } |
| 2495 | 2495 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 final TypeMask type; | 2628 final TypeMask type; |
| 2629 | 2629 |
| 2630 AbstractValue._internal(this.kind, this.constant, this.type) { | 2630 AbstractValue._internal(this.kind, this.constant, this.type) { |
| 2631 assert(kind != CONSTANT || constant != null); | 2631 assert(kind != CONSTANT || constant != null); |
| 2632 assert(constant is! SyntheticConstantValue); | 2632 assert(constant is! SyntheticConstantValue); |
| 2633 } | 2633 } |
| 2634 | 2634 |
| 2635 AbstractValue.nothing() | 2635 AbstractValue.nothing() |
| 2636 : this._internal(NOTHING, null, new TypeMask.nonNullEmpty()); | 2636 : this._internal(NOTHING, null, new TypeMask.nonNullEmpty()); |
| 2637 | 2637 |
| 2638 AbstractValue.constantValue(ConstantValue constant, TypeMask type) | 2638 factory AbstractValue.constantValue(ConstantValue constant, TypeMask type) { |
| 2639 : this._internal(CONSTANT, constant, type); | 2639 if (constant.isDummy || !constant.isConstant) { |
| 2640 return new AbstractValue._internal(NONCONST, null, type); |
| 2641 } else { |
| 2642 return new AbstractValue._internal(CONSTANT, constant, type); |
| 2643 } |
| 2644 } |
| 2640 | 2645 |
| 2641 factory AbstractValue.nonConstant(TypeMask type) { | 2646 factory AbstractValue.nonConstant(TypeMask type) { |
| 2642 if (type.isEmpty) { | 2647 if (type.isEmpty) { |
| 2643 if (type.isNullable) | 2648 if (type.isNullable) |
| 2644 return new AbstractValue.constantValue(new NullConstantValue(), type); | 2649 return new AbstractValue.constantValue(new NullConstantValue(), type); |
| 2645 else | 2650 else |
| 2646 return new AbstractValue.nothing(); | 2651 return new AbstractValue.nothing(); |
| 2647 } else { | 2652 } else { |
| 2648 return new AbstractValue._internal(NONCONST, null, type); | 2653 return new AbstractValue._internal(NONCONST, null, type); |
| 2649 } | 2654 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2718 } | 2723 } |
| 2719 | 2724 |
| 2720 processLetPrim(LetPrim node) { | 2725 processLetPrim(LetPrim node) { |
| 2721 values.remove(node.primitive); | 2726 values.remove(node.primitive); |
| 2722 } | 2727 } |
| 2723 | 2728 |
| 2724 processLetMutable(LetMutable node) { | 2729 processLetMutable(LetMutable node) { |
| 2725 values.remove(node.variable); | 2730 values.remove(node.variable); |
| 2726 } | 2731 } |
| 2727 } | 2732 } |
| OLD | NEW |