Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: pkg/compiler/lib/src/ssa/codegen.dart

Issue 1182913003: Split TypedSelector into Selector and TypeMask. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/ssa/codegen_helpers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of ssa; 5 part of ssa;
6 6
7 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 final SourceInformationFactory sourceInformationFactory; 10 final SourceInformationFactory sourceInformationFactory;
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 String methodName = backend.namer.instanceMethodName(node.element); 1543 String methodName = backend.namer.instanceMethodName(node.element);
1544 List<js.Expression> arguments = visitArguments(node.inputs); 1544 List<js.Expression> arguments = visitArguments(node.inputs);
1545 push(js.propertyCall(object, methodName, arguments), node); 1545 push(js.propertyCall(object, methodName, arguments), node);
1546 registry.registerStaticUse(node.element); 1546 registry.registerStaticUse(node.element);
1547 } 1547 }
1548 1548
1549 void visitOneShotInterceptor(HOneShotInterceptor node) { 1549 void visitOneShotInterceptor(HOneShotInterceptor node) {
1550 List<js.Expression> arguments = visitArguments(node.inputs); 1550 List<js.Expression> arguments = visitArguments(node.inputs);
1551 var isolate = new js.VariableUse( 1551 var isolate = new js.VariableUse(
1552 backend.namer.globalObjectFor(backend.interceptorsLibrary)); 1552 backend.namer.globalObjectFor(backend.interceptorsLibrary));
1553 Selector selector = getOptimizedSelectorFor(node, node.selector); 1553 Selector selector = node.selector;
1554 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1554 String methodName = backend.registerOneShotInterceptor(selector); 1555 String methodName = backend.registerOneShotInterceptor(selector);
1555 push(js.propertyCall(isolate, methodName, arguments), node); 1556 push(js.propertyCall(isolate, methodName, arguments), node);
1556 if (selector.isGetter) { 1557 if (selector.isGetter) {
1557 registerGetter(node); 1558 registerGetter(node);
1558 } else if (selector.isSetter) { 1559 } else if (selector.isSetter) {
1559 registerSetter(node); 1560 registerSetter(node);
1560 } else { 1561 } else {
1561 registerMethodInvoke(node); 1562 registerMethodInvoke(node);
1562 } 1563 }
1563 registry.registerUseInterceptor(); 1564 registry.registerUseInterceptor();
1564 } 1565 }
1565 1566
1566 Selector getOptimizedSelectorFor(HInvokeDynamic node, Selector selector) { 1567 TypeMask getOptimizedSelectorFor(HInvokeDynamic node,
1568 Selector selector,
1569 TypeMask mask) {
1567 if (node.element != null) { 1570 if (node.element != null) {
1568 // Create an artificial type mask to make sure only 1571 // Create an artificial type mask to make sure only
1569 // [node.element] will be enqueued. We're not using the receiver 1572 // [node.element] will be enqueued. We're not using the receiver
1570 // type because our optimizations might end up in a state where the 1573 // type because our optimizations might end up in a state where the
1571 // invoke dynamic knows more than the receiver. 1574 // invoke dynamic knows more than the receiver.
1572 ClassElement enclosing = node.element.enclosingClass; 1575 ClassElement enclosing = node.element.enclosingClass;
1573 TypeMask receiverType = 1576 return
1574 new TypeMask.nonNullExact(enclosing.declaration, compiler.world); 1577 new TypeMask.nonNullExact(enclosing.declaration, compiler.world);
1575 return new TypedSelector(receiverType, selector, compiler.world);
1576 } 1578 }
1577 // If [JSInvocationMirror._invokeOn] is enabled, and this call 1579 // If [JSInvocationMirror._invokeOn] is enabled, and this call
1578 // might hit a `noSuchMethod`, we register an untyped selector. 1580 // might hit a `noSuchMethod`, we register an untyped selector.
1579 return selector.extendIfReachesAll(compiler); 1581 return compiler.world.extendMaskIfReachesAll(selector, mask);
1580 } 1582 }
1581 1583
1582 void registerMethodInvoke(HInvokeDynamic node) { 1584 void registerMethodInvoke(HInvokeDynamic node) {
1583 Selector selector = getOptimizedSelectorFor(node, node.selector); 1585 Selector selector = node.selector;
1586 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1584 1587
1585 // If we don't know what we're calling or if we are calling a getter, 1588 // If we don't know what we're calling or if we are calling a getter,
1586 // we need to register that fact that we may be calling a closure 1589 // we need to register that fact that we may be calling a closure
1587 // with the same arguments. 1590 // with the same arguments.
1588 Element target = node.element; 1591 Element target = node.element;
1589 if (target == null || target.isGetter) { 1592 if (target == null || target.isGetter) {
1590 // TODO(kasperl): If we have a typed selector for the call, we 1593 // TODO(kasperl): If we have a typed selector for the call, we
1591 // may know something about the types of closures that need 1594 // may know something about the types of closures that need
1592 // the specific closure call method. 1595 // the specific closure call method.
1593 Selector call = new Selector.callClosureFrom(selector); 1596 Selector call = new Selector.callClosureFrom(selector);
1594 registry.registerDynamicInvocation(call); 1597 registry.registerDynamicInvocation(
1598 new UniverseSelector(call, null));
1595 } 1599 }
1596 registry.registerDynamicInvocation(selector); 1600 registry.registerDynamicInvocation(
1601 new UniverseSelector(selector, mask));
1597 } 1602 }
1598 1603
1599 void registerSetter(HInvokeDynamic node) { 1604 void registerSetter(HInvokeDynamic node) {
1600 Selector selector = getOptimizedSelectorFor(node, node.selector); 1605 Selector selector = node.selector;
1601 registry.registerDynamicSetter(selector); 1606 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1607 registry.registerDynamicSetter(
1608 new UniverseSelector(selector, mask));
1602 } 1609 }
1603 1610
1604 void registerGetter(HInvokeDynamic node) { 1611 void registerGetter(HInvokeDynamic node) {
1605 Selector selector = getOptimizedSelectorFor(node, node.selector); 1612 Selector selector = node.selector;
1606 registry.registerDynamicGetter(selector); 1613 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1614 registry.registerDynamicGetter(
1615 new UniverseSelector(selector, mask));
1607 } 1616 }
1608 1617
1609 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 1618 visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
1610 use(node.receiver); 1619 use(node.receiver);
1611 String name = backend.namer.invocationName(node.selector); 1620 String name = backend.namer.invocationName(node.selector);
1612 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node); 1621 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node);
1613 registerSetter(node); 1622 registerSetter(node);
1614 } 1623 }
1615 1624
1616 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 1625 visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
1617 use(node.receiver); 1626 use(node.receiver);
1618 String name = backend.namer.invocationName(node.selector); 1627 String name = backend.namer.invocationName(node.selector);
1619 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node); 1628 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node);
1620 registerGetter(node); 1629 registerGetter(node);
1621 } 1630 }
1622 1631
1623 visitInvokeClosure(HInvokeClosure node) { 1632 visitInvokeClosure(HInvokeClosure node) {
1624 Selector call = new Selector.callClosureFrom(node.selector); 1633 Selector call = new Selector.callClosureFrom(node.selector);
1625 use(node.receiver); 1634 use(node.receiver);
1626 push(js.propertyCall(pop(), 1635 push(js.propertyCall(pop(),
1627 backend.namer.invocationName(call), 1636 backend.namer.invocationName(call),
1628 visitArguments(node.inputs)), 1637 visitArguments(node.inputs)),
1629 node); 1638 node);
1630 registry.registerDynamicInvocation(call); 1639 registry.registerDynamicInvocation(
1640 new UniverseSelector(call, null));
1631 } 1641 }
1632 1642
1633 visitInvokeStatic(HInvokeStatic node) { 1643 visitInvokeStatic(HInvokeStatic node) {
1634 Element element = node.element; 1644 Element element = node.element;
1635 List<DartType> instantiatedTypes = node.instantiatedTypes; 1645 List<DartType> instantiatedTypes = node.instantiatedTypes;
1636 1646
1637 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) { 1647 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) {
1638 instantiatedTypes.forEach((type) { 1648 instantiatedTypes.forEach((type) {
1639 registry.registerInstantiatedType(type); 1649 registry.registerInstantiatedType(type);
1640 }); 1650 });
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 Selector selector = node.selector; 1701 Selector selector = node.selector;
1692 1702
1693 if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) { 1703 if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) {
1694 String methodName; 1704 String methodName;
1695 if (selector.isGetter) { 1705 if (selector.isGetter) {
1696 // If the selector we need to register a typed getter to the 1706 // If the selector we need to register a typed getter to the
1697 // [world]. The emitter needs to know if it needs to emit a 1707 // [world]. The emitter needs to know if it needs to emit a
1698 // bound closure for a method. 1708 // bound closure for a method.
1699 TypeMask receiverType = 1709 TypeMask receiverType =
1700 new TypeMask.nonNullExact(superClass, compiler.world); 1710 new TypeMask.nonNullExact(superClass, compiler.world);
1701 selector = new TypedSelector(receiverType, selector, compiler.world);
1702 // TODO(floitsch): we know the target. We shouldn't register a 1711 // TODO(floitsch): we know the target. We shouldn't register a
1703 // dynamic getter. 1712 // dynamic getter.
1704 registry.registerDynamicGetter(selector); 1713 registry.registerDynamicGetter(
1714 new UniverseSelector(selector, receiverType));
1705 registry.registerGetterForSuperMethod(node.element); 1715 registry.registerGetterForSuperMethod(node.element);
1706 methodName = backend.namer.invocationName(selector); 1716 methodName = backend.namer.invocationName(selector);
1707 } else { 1717 } else {
1708 assert(invariant(node, compiler.hasIncrementalSupport)); 1718 assert(invariant(node, compiler.hasIncrementalSupport));
1709 methodName = backend.namer.instanceMethodName(superMethod); 1719 methodName = backend.namer.instanceMethodName(superMethod);
1710 } 1720 }
1711 push(js.js('#.#.call(#)', 1721 push(js.js('#.#.call(#)',
1712 [backend.emitter.prototypeAccess(superClass, 1722 [backend.emitter.prototypeAccess(superClass,
1713 hasBeenInstantiated: true), 1723 hasBeenInstantiated: true),
1714 methodName, visitArguments(node.inputs, start: 0)]), 1724 methodName, visitArguments(node.inputs, start: 0)]),
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 js.PropertyAccess accessHelper(String name) { 2735 js.PropertyAccess accessHelper(String name) {
2726 Element helper = backend.findHelper(name); 2736 Element helper = backend.findHelper(name);
2727 if (helper == null) { 2737 if (helper == null) {
2728 // For mocked-up tests. 2738 // For mocked-up tests.
2729 return js.js('(void 0).$name'); 2739 return js.js('(void 0).$name');
2730 } 2740 }
2731 registry.registerStaticUse(helper); 2741 registry.registerStaticUse(helper);
2732 return backend.emitter.staticFunctionAccess(helper); 2742 return backend.emitter.staticFunctionAccess(helper);
2733 } 2743 }
2734 } 2744 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/ssa/codegen_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698