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; | |
20 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; | 19 import '../js_backend/codegen/task.dart' show CpsFunctionCompiler; |
21 import '../resolution/access_semantics.dart'; | 20 import '../resolution/access_semantics.dart'; |
22 import '../resolution/operators.dart'; | 21 import '../resolution/operators.dart'; |
23 import '../resolution/send_structure.dart'; | 22 import '../resolution/send_structure.dart'; |
24 import '../tree/tree.dart' as ast; | 23 import '../tree/tree.dart' as ast; |
25 import '../types/types.dart'; | 24 import '../types/types.dart'; |
26 import '../types/constants.dart' show computeTypeMask; | 25 import '../types/constants.dart' show computeTypeMask; |
27 import '../universe/universe.dart'; | 26 import '../universe/universe.dart'; |
28 import '../world.dart' show World; | 27 import '../world.dart' show World; |
29 import 'cps_fragment.dart'; | 28 import 'cps_fragment.dart'; |
(...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1603 node.receiverIsNotNull = receiver.isDefinitelyNotNull; | 1602 node.receiverIsNotNull = receiver.isDefinitelyNotNull; |
1604 | 1603 |
1605 if (isInterceptedSelector(node.selector) && | 1604 if (isInterceptedSelector(node.selector) && |
1606 node.receiver.definition == node.arguments[0].definition) { | 1605 node.receiver.definition == node.arguments[0].definition) { |
1607 // The receiver and first argument are the same; that means we already | 1606 // The receiver and first argument are the same; that means we already |
1608 // determined in visitInterceptor that we are targeting a non-interceptor. | 1607 // determined in visitInterceptor that we are targeting a non-interceptor. |
1609 | 1608 |
1610 // Check if any of the possible targets depend on the extra receiver | 1609 // Check if any of the possible targets depend on the extra receiver |
1611 // argument. Mixins do this, and tear-offs always needs the extra receiver | 1610 // argument. Mixins do this, and tear-offs always needs the extra receiver |
1612 // argument because BoundClosure uses it for equality and hash code. | 1611 // 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. | |
1615 bool needsReceiver(Element target) { | 1612 bool needsReceiver(Element target) { |
1616 if (target is! FunctionElement) return false; | 1613 if (target is! FunctionElement) return false; |
1617 FunctionElement function = target; | 1614 FunctionElement function = target; |
1618 return typeSystem.methodUsesReceiverArgument(function) || | 1615 return typeSystem.methodUsesReceiverArgument(function) || |
1619 node.selector.isGetter && !function.isGetter; | 1616 node.selector.isGetter && !function.isGetter; |
1620 } | 1617 } |
1621 if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) { | 1618 if (!getAllTargets(receiver.type, node.selector).any(needsReceiver)) { |
1622 // Replace the extra receiver argument with a dummy value if the | 1619 // Replace the extra receiver argument with a dummy value if the |
1623 // target definitely does not use it. | 1620 // target definitely does not use it. |
1624 ConstantValue constant = new SyntheticConstantValue( | 1621 Constant dummy = makeConstantPrimitive(new IntConstantValue(0)); |
1625 SyntheticConstantKind.DUMMY_INTERCEPTOR, | |
1626 receiver.type); | |
1627 Constant dummy = makeConstantPrimitive(constant); | |
1628 insertLetPrim(node, dummy); | 1622 insertLetPrim(node, dummy); |
1629 node.arguments[0].unlink(); | 1623 node.arguments[0].unlink(); |
1630 node.arguments[0] = new Reference<Primitive>(dummy); | 1624 node.arguments[0] = new Reference<Primitive>(dummy); |
1631 } | 1625 } |
1632 } | 1626 } |
1633 } | 1627 } |
1634 | 1628 |
1635 void visitTypeCast(TypeCast node) { | 1629 void visitTypeCast(TypeCast node) { |
1636 Continuation cont = node.continuation.definition; | 1630 Continuation cont = node.continuation.definition; |
1637 | 1631 |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2475 setValue(node, nonConstant(typeSystem.extendableNativeListType)); | 2469 setValue(node, nonConstant(typeSystem.extendableNativeListType)); |
2476 } | 2470 } |
2477 | 2471 |
2478 void visitLiteralMap(LiteralMap node) { | 2472 void visitLiteralMap(LiteralMap node) { |
2479 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, | 2473 // Constant maps are translated into (Constant MapConstant(...)) IR nodes, |
2480 // and thus LiteralMap nodes are NonConst. | 2474 // and thus LiteralMap nodes are NonConst. |
2481 setValue(node, nonConstant(typeSystem.mapType)); | 2475 setValue(node, nonConstant(typeSystem.mapType)); |
2482 } | 2476 } |
2483 | 2477 |
2484 void visitConstant(Constant node) { | 2478 void visitConstant(Constant node) { |
2485 setValue(node, constantValue(node.value, typeSystem.getTypeOf(node.value))); | 2479 ConstantValue value = 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 factory AbstractValue.constantValue(ConstantValue constant, TypeMask type) { | 2638 AbstractValue.constantValue(ConstantValue constant, TypeMask type) |
2639 if (constant.isDummy || !constant.isConstant) { | 2639 : this._internal(CONSTANT, constant, type); |
2640 return new AbstractValue._internal(NONCONST, null, type); | |
2641 } else { | |
2642 return new AbstractValue._internal(CONSTANT, constant, type); | |
2643 } | |
2644 } | |
2645 | 2640 |
2646 factory AbstractValue.nonConstant(TypeMask type) { | 2641 factory AbstractValue.nonConstant(TypeMask type) { |
2647 if (type.isEmpty) { | 2642 if (type.isEmpty) { |
2648 if (type.isNullable) | 2643 if (type.isNullable) |
2649 return new AbstractValue.constantValue(new NullConstantValue(), type); | 2644 return new AbstractValue.constantValue(new NullConstantValue(), type); |
2650 else | 2645 else |
2651 return new AbstractValue.nothing(); | 2646 return new AbstractValue.nothing(); |
2652 } else { | 2647 } else { |
2653 return new AbstractValue._internal(NONCONST, null, type); | 2648 return new AbstractValue._internal(NONCONST, null, type); |
2654 } | 2649 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2723 } | 2718 } |
2724 | 2719 |
2725 processLetPrim(LetPrim node) { | 2720 processLetPrim(LetPrim node) { |
2726 values.remove(node.primitive); | 2721 values.remove(node.primitive); |
2727 } | 2722 } |
2728 | 2723 |
2729 processLetMutable(LetMutable node) { | 2724 processLetMutable(LetMutable node) { |
2730 values.remove(node.variable); | 2725 values.remove(node.variable); |
2731 } | 2726 } |
2732 } | 2727 } |
OLD | NEW |