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 |