| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:collection' show Queue; | 6 import 'dart:collection' show Queue; |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 9 import '../common/tasks.dart' show CompilerTask; | 9 import '../common/tasks.dart' show CompilerTask; |
| 10 import '../constants/constant_system.dart'; | 10 import '../constants/constant_system.dart'; |
| (...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 // Create an artificial type mask to make sure only | 1782 // Create an artificial type mask to make sure only |
| 1783 // [node.element] will be enqueued. We're not using the receiver | 1783 // [node.element] will be enqueued. We're not using the receiver |
| 1784 // type because our optimizations might end up in a state where the | 1784 // type because our optimizations might end up in a state where the |
| 1785 // invoke dynamic knows more than the receiver. | 1785 // invoke dynamic knows more than the receiver. |
| 1786 ClassEntity enclosing = node.element.enclosingClass; | 1786 ClassEntity enclosing = node.element.enclosingClass; |
| 1787 if (_closedWorld.isInstantiated(enclosing)) { | 1787 if (_closedWorld.isInstantiated(enclosing)) { |
| 1788 return _closedWorld.commonMasks.createNonNullExact(enclosing); | 1788 return _closedWorld.commonMasks.createNonNullExact(enclosing); |
| 1789 } else { | 1789 } else { |
| 1790 // The element is mixed in so a non-null subtype mask is the most | 1790 // The element is mixed in so a non-null subtype mask is the most |
| 1791 // precise we have. | 1791 // precise we have. |
| 1792 assert(invariant(node, _closedWorld.isUsedAsMixin(enclosing), | 1792 assert( |
| 1793 message: "Element ${node.element} from $enclosing expected " | 1793 _closedWorld.isUsedAsMixin(enclosing), |
| 1794 failedAt( |
| 1795 node, |
| 1796 "Element ${node.element} from $enclosing expected " |
| 1794 "to be mixed in.")); | 1797 "to be mixed in.")); |
| 1795 return _closedWorld.commonMasks.createNonNullSubtype(enclosing); | 1798 return _closedWorld.commonMasks.createNonNullSubtype(enclosing); |
| 1796 } | 1799 } |
| 1797 } | 1800 } |
| 1798 // If [JSInvocationMirror._invokeOn] is enabled, and this call | 1801 // If [JSInvocationMirror._invokeOn] is enabled, and this call |
| 1799 // might hit a `noSuchMethod`, we register an untyped selector. | 1802 // might hit a `noSuchMethod`, we register an untyped selector. |
| 1800 return _closedWorld.extendMaskIfReachesAll(selector, mask); | 1803 return _closedWorld.extendMaskIfReachesAll(selector, mask); |
| 1801 } | 1804 } |
| 1802 | 1805 |
| 1803 void registerMethodInvoke(HInvokeDynamic node) { | 1806 void registerMethodInvoke(HInvokeDynamic node) { |
| 1804 Selector selector = node.selector; | 1807 Selector selector = node.selector; |
| 1805 | 1808 |
| 1806 // If we don't know what we're calling or if we are calling a getter, | 1809 // If we don't know what we're calling or if we are calling a getter, |
| 1807 // we need to register that fact that we may be calling a closure | 1810 // we need to register that fact that we may be calling a closure |
| 1808 // with the same arguments. | 1811 // with the same arguments. |
| 1809 MemberEntity target = node.element; | 1812 MemberEntity target = node.element; |
| 1810 if (target == null || target.isGetter) { | 1813 if (target == null || target.isGetter) { |
| 1811 // TODO(kasperl): If we have a typed selector for the call, we | 1814 // TODO(kasperl): If we have a typed selector for the call, we |
| 1812 // may know something about the types of closures that need | 1815 // may know something about the types of closures that need |
| 1813 // the specific closure call method. | 1816 // the specific closure call method. |
| 1814 Selector call = new Selector.callClosureFrom(selector); | 1817 Selector call = new Selector.callClosureFrom(selector); |
| 1815 _registry.registerDynamicUse(new DynamicUse(call, null)); | 1818 _registry.registerDynamicUse(new DynamicUse(call, null)); |
| 1816 } | 1819 } |
| 1817 if (target != null) { | 1820 if (target != null) { |
| 1818 // This is a dynamic invocation which we have found to have a single | 1821 // This is a dynamic invocation which we have found to have a single |
| 1819 // target but for some reason haven't inlined. We are _still_ accessing | 1822 // target but for some reason haven't inlined. We are _still_ accessing |
| 1820 // the target dynamically but we don't need to enqueue more than target | 1823 // the target dynamically but we don't need to enqueue more than target |
| 1821 // for this to work. | 1824 // for this to work. |
| 1822 assert(invariant(node, selector.applies(target), | 1825 assert(selector.applies(target), |
| 1823 message: '$selector does not apply to $target')); | 1826 failedAt(node, '$selector does not apply to $target')); |
| 1824 _registry.registerStaticUse( | 1827 _registry.registerStaticUse( |
| 1825 new StaticUse.directInvoke(target, selector.callStructure)); | 1828 new StaticUse.directInvoke(target, selector.callStructure)); |
| 1826 } else { | 1829 } else { |
| 1827 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); | 1830 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); |
| 1828 _registry.registerDynamicUse(new DynamicUse(selector, mask)); | 1831 _registry.registerDynamicUse(new DynamicUse(selector, mask)); |
| 1829 } | 1832 } |
| 1830 } | 1833 } |
| 1831 | 1834 |
| 1832 void registerSetter(HInvokeDynamic node) { | 1835 void registerSetter(HInvokeDynamic node) { |
| 1833 if (node.element != null) { | 1836 if (node.element != null) { |
| (...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3040 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { | 3043 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { |
| 3041 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); | 3044 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); |
| 3042 }); | 3045 }); |
| 3043 } | 3046 } |
| 3044 | 3047 |
| 3045 @override | 3048 @override |
| 3046 void visitRef(HRef node) { | 3049 void visitRef(HRef node) { |
| 3047 visit(node.value); | 3050 visit(node.value); |
| 3048 } | 3051 } |
| 3049 } | 3052 } |
| OLD | NEW |