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

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

Issue 2314703002: Split World usage into open, inference, and closed world. (Closed)
Patch Set: Updated cf. comments Created 4 years, 3 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/kernel/accessors.dart ('k') | pkg/compiler/lib/src/ssa/codegen.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 import 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:js_runtime/shared/embedded_names.dart'; 7 import 'package:js_runtime/shared/embedded_names.dart';
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 * 547 *
548 * However, inlining can only be performed when the target function can be 548 * However, inlining can only be performed when the target function can be
549 * resolved statically. The defaults can therefore be included at this point. 549 * resolved statically. The defaults can therefore be included at this point.
550 * 550 *
551 * The [providedArguments] list contains first all positional arguments, then 551 * The [providedArguments] list contains first all positional arguments, then
552 * the provided named arguments (the named arguments that are defined in the 552 * the provided named arguments (the named arguments that are defined in the
553 * [selector]) in a specific order (see [addDynamicSendArgumentsToList]). 553 * [selector]) in a specific order (see [addDynamicSendArgumentsToList]).
554 */ 554 */
555 List<HInstruction> completeDynamicSendArgumentsList(Selector selector, 555 List<HInstruction> completeDynamicSendArgumentsList(Selector selector,
556 FunctionElement function, List<HInstruction> providedArguments) { 556 FunctionElement function, List<HInstruction> providedArguments) {
557 assert(selector.applies(function, compiler.world)); 557 assert(selector.applies(function, compiler.closedWorld));
558 FunctionSignature signature = function.functionSignature; 558 FunctionSignature signature = function.functionSignature;
559 List<HInstruction> compiledArguments = new List<HInstruction>( 559 List<HInstruction> compiledArguments = new List<HInstruction>(
560 signature.parameterCount + 1); // Plus one for receiver. 560 signature.parameterCount + 1); // Plus one for receiver.
561 561
562 compiledArguments[0] = providedArguments[0]; // Receiver. 562 compiledArguments[0] = providedArguments[0]; // Receiver.
563 int index = 1; 563 int index = 1;
564 for (; index <= signature.requiredParameterCount; index++) { 564 for (; index <= signature.requiredParameterCount; index++) {
565 compiledArguments[index] = providedArguments[index]; 565 compiledArguments[index] = providedArguments[index];
566 } 566 }
567 if (!signature.optionalParametersAreNamed) { 567 if (!signature.optionalParametersAreNamed) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 bool meetsHardConstraints() { 641 bool meetsHardConstraints() {
642 if (compiler.options.disableInlining) return false; 642 if (compiler.options.disableInlining) return false;
643 643
644 assert(invariant( 644 assert(invariant(
645 currentNode != null ? currentNode : element, 645 currentNode != null ? currentNode : element,
646 selector != null || 646 selector != null ||
647 Elements.isStaticOrTopLevel(element) || 647 Elements.isStaticOrTopLevel(element) ||
648 element.isGenerativeConstructorBody, 648 element.isGenerativeConstructorBody,
649 message: "Missing selector for inlining of $element.")); 649 message: "Missing selector for inlining of $element."));
650 if (selector != null) { 650 if (selector != null) {
651 if (!selector.applies(function, compiler.world)) return false; 651 if (!selector.applies(function, compiler.closedWorld)) return false;
652 if (mask != null && !mask.canHit(function, selector, compiler.world)) { 652 if (mask != null &&
653 !mask.canHit(function, selector, compiler.closedWorld)) {
653 return false; 654 return false;
654 } 655 }
655 } 656 }
656 657
657 if (backend.isJsInterop(element)) return false; 658 if (backend.isJsInterop(element)) return false;
658 659
659 // Don't inline operator== methods if the parameter can be null. 660 // Don't inline operator== methods if the parameter can be null.
660 if (element.name == '==') { 661 if (element.name == '==') {
661 if (element.enclosingClass != coreClasses.objectClass && 662 if (element.enclosingClass != coreClasses.objectClass &&
662 providedArguments[1].canBeNull()) { 663 providedArguments[1].canBeNull()) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 return graph.addConstant(getConstantForNode(node), compiler); 888 return graph.addConstant(getConstantForNode(node), compiler);
888 } 889 }
889 890
890 /** 891 /**
891 * Documentation wanted -- johnniwinther 892 * Documentation wanted -- johnniwinther
892 * 893 *
893 * Invariant: [functionElement] must be an implementation element. 894 * Invariant: [functionElement] must be an implementation element.
894 */ 895 */
895 HGraph buildMethod(FunctionElement functionElement) { 896 HGraph buildMethod(FunctionElement functionElement) {
896 assert(invariant(functionElement, functionElement.isImplementation)); 897 assert(invariant(functionElement, functionElement.isImplementation));
897 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); 898 graph.calledInLoop = compiler.closedWorld.isCalledInLoop(functionElement);
898 ast.FunctionExpression function = resolvedAst.node; 899 ast.FunctionExpression function = resolvedAst.node;
899 assert(function != null); 900 assert(function != null);
900 assert(elements.getFunctionDefinition(function) != null); 901 assert(elements.getFunctionDefinition(function) != null);
901 openFunction(functionElement, function); 902 openFunction(functionElement, function);
902 String name = functionElement.name; 903 String name = functionElement.name;
903 if (backend.isJsInterop(functionElement)) { 904 if (backend.isJsInterop(functionElement)) {
904 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 905 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
905 sourceInformationBuilder.buildGeneric(function))); 906 sourceInformationBuilder.buildGeneric(function)));
906 var value = pop(); 907 var value = pop();
907 closeAndGotoExit(new HReturn( 908 closeAndGotoExit(new HReturn(
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 assert(invariant( 1476 assert(invariant(
1476 member, isNativeUpgradeFactory || compiler.compilationFailed)); 1477 member, isNativeUpgradeFactory || compiler.compilationFailed));
1477 } else { 1478 } else {
1478 fields.add(member); 1479 fields.add(member);
1479 DartType type = localsHandler.substInContext(member.type); 1480 DartType type = localsHandler.substInContext(member.type);
1480 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); 1481 constructorArguments.add(potentiallyCheckOrTrustType(value, type));
1481 } 1482 }
1482 }, includeSuperAndInjectedMembers: true); 1483 }, includeSuperAndInjectedMembers: true);
1483 1484
1484 InterfaceType type = classElement.thisType; 1485 InterfaceType type = classElement.thisType;
1485 TypeMask ssaType = 1486 TypeMask ssaType = new TypeMask.nonNullExact(
1486 new TypeMask.nonNullExact(classElement.declaration, compiler.world); 1487 classElement.declaration, compiler.closedWorld);
1487 List<DartType> instantiatedTypes; 1488 List<DartType> instantiatedTypes;
1488 addInlinedInstantiation(type); 1489 addInlinedInstantiation(type);
1489 if (!currentInlinedInstantiations.isEmpty) { 1490 if (!currentInlinedInstantiations.isEmpty) {
1490 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); 1491 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
1491 } 1492 }
1492 1493
1493 HInstruction newObject; 1494 HInstruction newObject;
1494 if (!isNativeUpgradeFactory) { 1495 if (!isNativeUpgradeFactory) {
1495 newObject = new HCreate( 1496 newObject = new HCreate(
1496 classElement, constructorArguments, ssaType, instantiatedTypes); 1497 classElement, constructorArguments, ssaType, instantiatedTypes);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 }); 1590 });
1590 } 1591 }
1591 1592
1592 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. 1593 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
1593 tryInlineMethod(body, null, null, bodyCallInputs, function)) { 1594 tryInlineMethod(body, null, null, bodyCallInputs, function)) {
1594 pop(); 1595 pop();
1595 } else { 1596 } else {
1596 HInvokeConstructorBody invoke = new HInvokeConstructorBody( 1597 HInvokeConstructorBody invoke = new HInvokeConstructorBody(
1597 body.declaration, bodyCallInputs, backend.nonNullType); 1598 body.declaration, bodyCallInputs, backend.nonNullType);
1598 invoke.sideEffects = 1599 invoke.sideEffects =
1599 compiler.world.getSideEffectsOfElement(constructor); 1600 compiler.closedWorld.getSideEffectsOfElement(constructor);
1600 add(invoke); 1601 add(invoke);
1601 } 1602 }
1602 } 1603 }
1603 if (inliningStack.isEmpty) { 1604 if (inliningStack.isEmpty) {
1604 closeAndGotoExit(new HReturn(newObject, 1605 closeAndGotoExit(new HReturn(newObject,
1605 sourceInformationBuilder.buildImplicitReturn(functionElement))); 1606 sourceInformationBuilder.buildImplicitReturn(functionElement)));
1606 return closeFunction(); 1607 return closeFunction();
1607 } else { 1608 } else {
1608 localsHandler.updateLocal(returnLocal, newObject); 1609 localsHandler.updateLocal(returnLocal, newObject);
1609 return null; 1610 return null;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 HInstruction buildTypeConversion( 1732 HInstruction buildTypeConversion(
1732 HInstruction original, DartType type, int kind) { 1733 HInstruction original, DartType type, int kind) {
1733 if (type == null) return original; 1734 if (type == null) return original;
1734 // GENERIC_METHODS: The following statement was added for parsing and 1735 // GENERIC_METHODS: The following statement was added for parsing and
1735 // ignoring method type variables; must be generalized for full support of 1736 // ignoring method type variables; must be generalized for full support of
1736 // generic methods. 1737 // generic methods.
1737 type = type.dynamifyMethodTypeVariableType; 1738 type = type.dynamifyMethodTypeVariableType;
1738 type = type.unaliased; 1739 type = type.unaliased;
1739 assert(assertTypeInContext(type, original)); 1740 assert(assertTypeInContext(type, original));
1740 if (type.isInterfaceType && !type.treatAsRaw) { 1741 if (type.isInterfaceType && !type.treatAsRaw) {
1741 TypeMask subtype = new TypeMask.subtype(type.element, compiler.world); 1742 TypeMask subtype =
1743 new TypeMask.subtype(type.element, compiler.closedWorld);
1742 HInstruction representations = buildTypeArgumentRepresentations(type); 1744 HInstruction representations = buildTypeArgumentRepresentations(type);
1743 add(representations); 1745 add(representations);
1744 return new HTypeConversion.withTypeRepresentation( 1746 return new HTypeConversion.withTypeRepresentation(
1745 type, kind, subtype, original, representations); 1747 type, kind, subtype, original, representations);
1746 } else if (type.isTypeVariable) { 1748 } else if (type.isTypeVariable) {
1747 TypeMask subtype = original.instructionType; 1749 TypeMask subtype = original.instructionType;
1748 HInstruction typeVariable = addTypeVariableReference(type); 1750 HInstruction typeVariable = addTypeVariableReference(type);
1749 return new HTypeConversion.withTypeRepresentation( 1751 return new HTypeConversion.withTypeRepresentation(
1750 type, kind, subtype, original, typeVariable); 1752 type, kind, subtype, original, typeVariable);
1751 } else if (type.isFunctionType) { 1753 } else if (type.isFunctionType) {
(...skipping 20 matching lines...) Expand all
1772 HInstruction _trustType(HInstruction original, DartType type) { 1774 HInstruction _trustType(HInstruction original, DartType type) {
1773 assert(compiler.options.trustTypeAnnotations); 1775 assert(compiler.options.trustTypeAnnotations);
1774 assert(type != null); 1776 assert(type != null);
1775 type = localsHandler.substInContext(type); 1777 type = localsHandler.substInContext(type);
1776 type = type.unaliased; 1778 type = type.unaliased;
1777 if (type.isDynamic) return original; 1779 if (type.isDynamic) return original;
1778 if (!type.isInterfaceType) return original; 1780 if (!type.isInterfaceType) return original;
1779 if (type.isObject) return original; 1781 if (type.isObject) return original;
1780 // The type element is either a class or the void element. 1782 // The type element is either a class or the void element.
1781 Element element = type.element; 1783 Element element = type.element;
1782 TypeMask mask = new TypeMask.subtype(element, compiler.world); 1784 TypeMask mask = new TypeMask.subtype(element, compiler.closedWorld);
1783 return new HTypeKnown.pinned(mask, original); 1785 return new HTypeKnown.pinned(mask, original);
1784 } 1786 }
1785 1787
1786 HInstruction _checkType(HInstruction original, DartType type, int kind) { 1788 HInstruction _checkType(HInstruction original, DartType type, int kind) {
1787 assert(compiler.options.enableTypeAssertions); 1789 assert(compiler.options.enableTypeAssertions);
1788 assert(type != null); 1790 assert(type != null);
1789 type = localsHandler.substInContext(type); 1791 type = localsHandler.substInContext(type);
1790 HInstruction other = buildTypeConversion(original, type, kind); 1792 HInstruction other = buildTypeConversion(original, type, kind);
1791 registry?.registerTypeUse(new TypeUse.isCheck(type)); 1793 registry?.registerTypeUse(new TypeUse.isCheck(type));
1792 return other; 1794 return other;
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
2417 2419
2418 List<HInstruction> capturedVariables = <HInstruction>[]; 2420 List<HInstruction> capturedVariables = <HInstruction>[];
2419 closureClassElement.closureFields.forEach((ClosureFieldElement field) { 2421 closureClassElement.closureFields.forEach((ClosureFieldElement field) {
2420 Local capturedLocal = 2422 Local capturedLocal =
2421 nestedClosureData.getLocalVariableForClosureField(field); 2423 nestedClosureData.getLocalVariableForClosureField(field);
2422 assert(capturedLocal != null); 2424 assert(capturedLocal != null);
2423 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2425 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2424 }); 2426 });
2425 2427
2426 TypeMask type = 2428 TypeMask type =
2427 new TypeMask.nonNullExact(closureClassElement, compiler.world); 2429 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld);
2428 push(new HCreate(closureClassElement, capturedVariables, type) 2430 push(new HCreate(closureClassElement, capturedVariables, type)
2429 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); 2431 ..sourceInformation = sourceInformationBuilder.buildCreate(node));
2430 2432
2431 Element methodElement = nestedClosureData.closureElement; 2433 Element methodElement = nestedClosureData.closureElement;
2432 registry?.registerInstantiatedClosure(methodElement); 2434 registry?.registerInstantiatedClosure(methodElement);
2433 } 2435 }
2434 2436
2435 visitFunctionDeclaration(ast.FunctionDeclaration node) { 2437 visitFunctionDeclaration(ast.FunctionDeclaration node) {
2436 assert(isReachable); 2438 assert(isReachable);
2437 visit(node.function); 2439 visit(node.function);
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 graph.addDeferredConstant(value, prefix, sourceInformation, compiler); 2691 graph.addDeferredConstant(value, prefix, sourceInformation, compiler);
2690 } else { 2692 } else {
2691 instruction = graph.addConstant(value, compiler, 2693 instruction = graph.addConstant(value, compiler,
2692 sourceInformation: sourceInformation); 2694 sourceInformation: sourceInformation);
2693 } 2695 }
2694 stack.add(instruction); 2696 stack.add(instruction);
2695 // The inferrer may have found a better type than the constant 2697 // The inferrer may have found a better type than the constant
2696 // handler in the case of lists, because the constant handler 2698 // handler in the case of lists, because the constant handler
2697 // does not look at elements in the list. 2699 // does not look at elements in the list.
2698 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler); 2700 TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler);
2699 if (!type.containsAll(compiler.world) && !instruction.isConstantNull()) { 2701 if (!type.containsAll(compiler.closedWorld) &&
2702 !instruction.isConstantNull()) {
2700 // TODO(13429): The inferrer should know that an element 2703 // TODO(13429): The inferrer should know that an element
2701 // cannot be null. 2704 // cannot be null.
2702 instruction.instructionType = type.nonNullable(); 2705 instruction.instructionType = type.nonNullable();
2703 } 2706 }
2704 } 2707 }
2705 2708
2706 @override 2709 @override
2707 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) { 2710 void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
2708 generateIsDeferredLoadedCheckIfNeeded(prefix, node); 2711 generateIsDeferredLoadedCheckIfNeeded(prefix, node);
2709 } 2712 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); 3038 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType);
3036 HInstruction call = pop(); 3039 HInstruction call = pop();
3037 return new HIs.variable(type, expression, call, backend.boolType); 3040 return new HIs.variable(type, expression, call, backend.boolType);
3038 } else if (RuntimeTypes.hasTypeArguments(type)) { 3041 } else if (RuntimeTypes.hasTypeArguments(type)) {
3039 ClassElement element = type.element; 3042 ClassElement element = type.element;
3040 Element helper = helpers.checkSubtype; 3043 Element helper = helpers.checkSubtype;
3041 HInstruction representations = buildTypeArgumentRepresentations(type); 3044 HInstruction representations = buildTypeArgumentRepresentations(type);
3042 add(representations); 3045 add(representations);
3043 js.Name operator = backend.namer.operatorIs(element); 3046 js.Name operator = backend.namer.operatorIs(element);
3044 HInstruction isFieldName = addConstantStringFromName(operator); 3047 HInstruction isFieldName = addConstantStringFromName(operator);
3045 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) 3048 HInstruction asFieldName = compiler.closedWorld
3049 .hasAnyStrictSubtype(element)
3046 ? addConstantStringFromName(backend.namer.substitutionName(element)) 3050 ? addConstantStringFromName(backend.namer.substitutionName(element))
3047 : graph.addConstantNull(compiler); 3051 : graph.addConstantNull(compiler);
3048 List<HInstruction> inputs = <HInstruction>[ 3052 List<HInstruction> inputs = <HInstruction>[
3049 expression, 3053 expression,
3050 isFieldName, 3054 isFieldName,
3051 representations, 3055 representations,
3052 asFieldName 3056 asFieldName
3053 ]; 3057 ];
3054 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); 3058 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType);
3055 HInstruction call = pop(); 3059 HInstruction call = pop();
3056 return new HIs.compound(type, expression, call, backend.boolType); 3060 return new HIs.compound(type, expression, call, backend.boolType);
3057 } else { 3061 } else {
3058 if (backend.hasDirectCheckFor(type)) { 3062 if (backend.hasDirectCheckFor(type)) {
3059 return new HIs.direct(type, expression, backend.boolType); 3063 return new HIs.direct(type, expression, backend.boolType);
3060 } 3064 }
3061 // The interceptor is not always needed. It is removed by optimization 3065 // The interceptor is not always needed. It is removed by optimization
3062 // when the receiver type or tested type permit. 3066 // when the receiver type or tested type permit.
3063 return new HIs.raw( 3067 return new HIs.raw(
3064 type, expression, invokeInterceptor(expression), backend.boolType); 3068 type, expression, invokeInterceptor(expression), backend.boolType);
3065 } 3069 }
3066 } 3070 }
3067 3071
3068 HInstruction buildFunctionType(FunctionType type) { 3072 HInstruction buildFunctionType(FunctionType type) {
3069 type.accept(new TypeBuilder(compiler.world), this); 3073 type.accept(new TypeBuilder(compiler.closedWorld), this);
3070 return pop(); 3074 return pop();
3071 } 3075 }
3072 3076
3073 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { 3077 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) {
3074 CallStructure callStructure = elements.getSelector(node).callStructure; 3078 CallStructure callStructure = elements.getSelector(node).callStructure;
3075 if (callStructure.namedArgumentCount == 0) { 3079 if (callStructure.namedArgumentCount == 0) {
3076 addGenericSendArgumentsToList(node.arguments, list); 3080 addGenericSendArgumentsToList(node.arguments, list);
3077 } else { 3081 } else {
3078 // Visit positional arguments and add them to the list. 3082 // Visit positional arguments and add them to the list.
3079 Link<ast.Node> arguments = node.arguments; 3083 Link<ast.Node> arguments = node.arguments;
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs)); 3680 push(buildInvokeSuper(Selectors.noSuchMethod_, element, inputs));
3677 } 3681 }
3678 3682
3679 /// Generate a call to a super method or constructor. 3683 /// Generate a call to a super method or constructor.
3680 void generateSuperInvoke(ast.Send node, FunctionElement function, 3684 void generateSuperInvoke(ast.Send node, FunctionElement function,
3681 SourceInformation sourceInformation) { 3685 SourceInformation sourceInformation) {
3682 // TODO(5347): Try to avoid the need for calling [implementation] before 3686 // TODO(5347): Try to avoid the need for calling [implementation] before
3683 // calling [makeStaticArgumentList]. 3687 // calling [makeStaticArgumentList].
3684 Selector selector = elements.getSelector(node); 3688 Selector selector = elements.getSelector(node);
3685 assert(invariant( 3689 assert(invariant(
3686 node, selector.applies(function.implementation, compiler.world), 3690 node, selector.applies(function.implementation, compiler.closedWorld),
3687 message: "$selector does not apply to ${function.implementation}")); 3691 message: "$selector does not apply to ${function.implementation}"));
3688 List<HInstruction> inputs = makeStaticArgumentList( 3692 List<HInstruction> inputs = makeStaticArgumentList(
3689 selector.callStructure, node.arguments, function.implementation); 3693 selector.callStructure, node.arguments, function.implementation);
3690 push(buildInvokeSuper(selector, function, inputs, sourceInformation)); 3694 push(buildInvokeSuper(selector, function, inputs, sourceInformation));
3691 } 3695 }
3692 3696
3693 /// Access the value from the super [element]. 3697 /// Access the value from the super [element].
3694 void handleSuperGet(ast.Send node, Element element) { 3698 void handleSuperGet(ast.Send node, Element element) {
3695 Selector selector = elements.getSelector(node); 3699 Selector selector = elements.getSelector(node);
3696 SourceInformation sourceInformation = 3700 SourceInformation sourceInformation =
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
3841 } 3845 }
3842 3846
3843 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) { 3847 void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) {
3844 Selector selector = elements.getSelector(node); 3848 Selector selector = elements.getSelector(node);
3845 List<HInstruction> inputs = <HInstruction>[]; 3849 List<HInstruction> inputs = <HInstruction>[];
3846 addGenericSendArgumentsToList(arguments.nodes, inputs); 3850 addGenericSendArgumentsToList(arguments.nodes, inputs);
3847 generateSuperNoSuchMethodSend(node, selector, inputs); 3851 generateSuperNoSuchMethodSend(node, selector, inputs);
3848 } 3852 }
3849 3853
3850 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { 3854 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
3851 ClassWorld classWorld = compiler.world; 3855 ClassWorld classWorld = compiler.closedWorld;
3852 if (classWorld.isUsedAsMixin(cls)) return true; 3856 if (classWorld.isUsedAsMixin(cls)) return true;
3853 3857
3854 return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) { 3858 return compiler.closedWorld.anyStrictSubclassOf(cls,
3859 (ClassElement subclass) {
3855 return !rti.isTrivialSubstitution(subclass, cls); 3860 return !rti.isTrivialSubstitution(subclass, cls);
3856 }); 3861 });
3857 } 3862 }
3858 3863
3859 /** 3864 /**
3860 * Generate code to extract the type argument from the object. 3865 * Generate code to extract the type argument from the object.
3861 */ 3866 */
3862 HInstruction readTypeVariable(TypeVariableType variable, 3867 HInstruction readTypeVariable(TypeVariableType variable,
3863 {SourceInformation sourceInformation}) { 3868 {SourceInformation sourceInformation}) {
3864 assert(sourceElement.isInstanceMember); 3869 assert(sourceElement.isInstanceMember);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 Elements.isGrowableListConstructorCall(elements[send], send, compiler); 4031 Elements.isGrowableListConstructorCall(elements[send], send, compiler);
4027 4032
4028 TypeMask computeType(element) { 4033 TypeMask computeType(element) {
4029 Element originalElement = elements[send]; 4034 Element originalElement = elements[send];
4030 if (isFixedListConstructorCall || 4035 if (isFixedListConstructorCall ||
4031 Elements.isFilledListConstructorCall( 4036 Elements.isFilledListConstructorCall(
4032 originalElement, send, compiler)) { 4037 originalElement, send, compiler)) {
4033 isFixedList = true; 4038 isFixedList = true;
4034 TypeMask inferred = 4039 TypeMask inferred =
4035 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); 4040 TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
4036 return inferred.containsAll(compiler.world) 4041 return inferred.containsAll(compiler.closedWorld)
4037 ? backend.fixedArrayType 4042 ? backend.fixedArrayType
4038 : inferred; 4043 : inferred;
4039 } else if (isGrowableListConstructorCall) { 4044 } else if (isGrowableListConstructorCall) {
4040 TypeMask inferred = 4045 TypeMask inferred =
4041 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); 4046 TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
4042 return inferred.containsAll(compiler.world) 4047 return inferred.containsAll(compiler.closedWorld)
4043 ? backend.extendableArrayType 4048 ? backend.extendableArrayType
4044 : inferred; 4049 : inferred;
4045 } else if (Elements.isConstructorOfTypedArraySubclass( 4050 } else if (Elements.isConstructorOfTypedArraySubclass(
4046 originalElement, compiler)) { 4051 originalElement, compiler)) {
4047 isFixedList = true; 4052 isFixedList = true;
4048 TypeMask inferred = 4053 TypeMask inferred =
4049 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); 4054 TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
4050 ClassElement cls = element.enclosingClass; 4055 ClassElement cls = element.enclosingClass;
4051 assert(backend.isNative(cls.thisType.element)); 4056 assert(backend.isNative(cls.thisType.element));
4052 return inferred.containsAll(compiler.world) 4057 return inferred.containsAll(compiler.closedWorld)
4053 ? new TypeMask.nonNullExact(cls.thisType.element, compiler.world) 4058 ? new TypeMask.nonNullExact(
4059 cls.thisType.element, compiler.closedWorld)
4054 : inferred; 4060 : inferred;
4055 } else if (element.isGenerativeConstructor) { 4061 } else if (element.isGenerativeConstructor) {
4056 ClassElement cls = element.enclosingClass; 4062 ClassElement cls = element.enclosingClass;
4057 if (cls.isAbstract) { 4063 if (cls.isAbstract) {
4058 // An error will be thrown. 4064 // An error will be thrown.
4059 return new TypeMask.nonNullEmpty(); 4065 return new TypeMask.nonNullEmpty();
4060 } else { 4066 } else {
4061 return new TypeMask.nonNullExact( 4067 return new TypeMask.nonNullExact(
4062 cls.thisType.element, compiler.world); 4068 cls.thisType.element, compiler.closedWorld);
4063 } 4069 }
4064 } else { 4070 } else {
4065 return TypeMaskFactory.inferredReturnTypeForElement( 4071 return TypeMaskFactory.inferredReturnTypeForElement(
4066 originalElement, compiler); 4072 originalElement, compiler);
4067 } 4073 }
4068 } 4074 }
4069 4075
4070 Element constructor = elements[send]; 4076 Element constructor = elements[send];
4071 CallStructure callStructure = elements.getSelector(send).callStructure; 4077 CallStructure callStructure = elements.getSelector(send).callStructure;
4072 ConstructorElement constructorDeclaration = constructor; 4078 ConstructorElement constructorDeclaration = constructor;
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
4676 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask, 4682 void pushInvokeDynamic(ast.Node node, Selector selector, TypeMask mask,
4677 List<HInstruction> arguments, 4683 List<HInstruction> arguments,
4678 {SourceInformation sourceInformation}) { 4684 {SourceInformation sourceInformation}) {
4679 // We prefer to not inline certain operations on indexables, 4685 // We prefer to not inline certain operations on indexables,
4680 // because the constant folder will handle them better and turn 4686 // because the constant folder will handle them better and turn
4681 // them into simpler instructions that allow further 4687 // them into simpler instructions that allow further
4682 // optimizations. 4688 // optimizations.
4683 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { 4689 bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
4684 bool isLength = selector.isGetter && selector.name == "length"; 4690 bool isLength = selector.isGetter && selector.name == "length";
4685 if (isLength || selector.isIndex) { 4691 if (isLength || selector.isIndex) {
4686 return compiler.world.isSubtypeOf( 4692 return compiler.closedWorld.isSubtypeOf(
4687 element.enclosingClass.declaration, helpers.jsIndexableClass); 4693 element.enclosingClass.declaration, helpers.jsIndexableClass);
4688 } else if (selector.isIndexSet) { 4694 } else if (selector.isIndexSet) {
4689 return compiler.world.isSubtypeOf(element.enclosingClass.declaration, 4695 return compiler.closedWorld.isSubtypeOf(
4696 element.enclosingClass.declaration,
4690 helpers.jsMutableIndexableClass); 4697 helpers.jsMutableIndexableClass);
4691 } else { 4698 } else {
4692 return false; 4699 return false;
4693 } 4700 }
4694 } 4701 }
4695 4702
4696 bool isOptimizableOperation(Selector selector, Element element) { 4703 bool isOptimizableOperation(Selector selector, Element element) {
4697 ClassElement cls = element.enclosingClass; 4704 ClassElement cls = element.enclosingClass;
4698 if (isOptimizableOperationOnIndexable(selector, element)) return true; 4705 if (isOptimizableOperationOnIndexable(selector, element)) return true;
4699 if (!backend.interceptedClasses.contains(cls)) return false; 4706 if (!backend.interceptedClasses.contains(cls)) return false;
4700 if (selector.isOperator) return true; 4707 if (selector.isOperator) return true;
4701 if (selector.isSetter) return true; 4708 if (selector.isSetter) return true;
4702 if (selector.isIndex) return true; 4709 if (selector.isIndex) return true;
4703 if (selector.isIndexSet) return true; 4710 if (selector.isIndexSet) return true;
4704 if (element == helpers.jsArrayAdd || 4711 if (element == helpers.jsArrayAdd ||
4705 element == helpers.jsArrayRemoveLast || 4712 element == helpers.jsArrayRemoveLast ||
4706 element == helpers.jsStringSplit) { 4713 element == helpers.jsStringSplit) {
4707 return true; 4714 return true;
4708 } 4715 }
4709 return false; 4716 return false;
4710 } 4717 }
4711 4718
4712 Element element = compiler.world.locateSingleElement(selector, mask); 4719 Element element = compiler.closedWorld.locateSingleElement(selector, mask);
4713 if (element != null && 4720 if (element != null &&
4714 !element.isField && 4721 !element.isField &&
4715 !(element.isGetter && selector.isCall) && 4722 !(element.isGetter && selector.isCall) &&
4716 !(element.isFunction && selector.isGetter) && 4723 !(element.isFunction && selector.isGetter) &&
4717 !isOptimizableOperation(selector, element)) { 4724 !isOptimizableOperation(selector, element)) {
4718 if (tryInlineMethod(element, selector, mask, arguments, node)) { 4725 if (tryInlineMethod(element, selector, mask, arguments, node)) {
4719 return; 4726 return;
4720 } 4727 }
4721 } 4728 }
4722 4729
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
4849 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. 4856 // TODO(johnniwinther): Use [sourceInformation] instead of [location].
4850 if (tryInlineMethod(element, null, null, arguments, location, 4857 if (tryInlineMethod(element, null, null, arguments, location,
4851 instanceType: instanceType)) { 4858 instanceType: instanceType)) {
4852 return; 4859 return;
4853 } 4860 }
4854 4861
4855 if (typeMask == null) { 4862 if (typeMask == null) {
4856 typeMask = 4863 typeMask =
4857 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 4864 TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
4858 } 4865 }
4859 bool targetCanThrow = !compiler.world.getCannotThrow(element); 4866 bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element);
4860 // TODO(5346): Try to avoid the need for calling [declaration] before 4867 // TODO(5346): Try to avoid the need for calling [declaration] before
4861 var instruction; 4868 var instruction;
4862 if (backend.isJsInterop(element)) { 4869 if (backend.isJsInterop(element)) {
4863 instruction = 4870 instruction =
4864 invokeJsInteropFunction(element, arguments, sourceInformation); 4871 invokeJsInteropFunction(element, arguments, sourceInformation);
4865 } else { 4872 } else {
4866 // creating an [HInvokeStatic]. 4873 // creating an [HInvokeStatic].
4867 instruction = new HInvokeStatic(element.declaration, arguments, typeMask, 4874 instruction = new HInvokeStatic(element.declaration, arguments, typeMask,
4868 targetCanThrow: targetCanThrow) 4875 targetCanThrow: targetCanThrow)
4869 ..sourceInformation = sourceInformation; 4876 ..sourceInformation = sourceInformation;
4870 if (currentInlinedInstantiations.isNotEmpty) { 4877 if (currentInlinedInstantiations.isNotEmpty) {
4871 instruction.instantiatedTypes = 4878 instruction.instantiatedTypes =
4872 new List<DartType>.from(currentInlinedInstantiations); 4879 new List<DartType>.from(currentInlinedInstantiations);
4873 } 4880 }
4874 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); 4881 instruction.sideEffects =
4882 compiler.closedWorld.getSideEffectsOfElement(element);
4875 } 4883 }
4876 if (location == null) { 4884 if (location == null) {
4877 push(instruction); 4885 push(instruction);
4878 } else { 4886 } else {
4879 pushWithPosition(instruction, location); 4887 pushWithPosition(instruction, location);
4880 } 4888 }
4881 } 4889 }
4882 4890
4883 HInstruction buildInvokeSuper( 4891 HInstruction buildInvokeSuper(
4884 Selector selector, Element element, List<HInstruction> arguments, 4892 Selector selector, Element element, List<HInstruction> arguments,
(...skipping 13 matching lines...) Expand all
4898 TypeMask type; 4906 TypeMask type;
4899 if (!element.isGetter && selector.isGetter) { 4907 if (!element.isGetter && selector.isGetter) {
4900 type = TypeMaskFactory.inferredTypeForElement(element, compiler); 4908 type = TypeMaskFactory.inferredTypeForElement(element, compiler);
4901 } else { 4909 } else {
4902 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 4910 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
4903 } 4911 }
4904 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass, 4912 HInstruction instruction = new HInvokeSuper(element, currentNonClosureClass,
4905 selector, inputs, type, sourceInformation, 4913 selector, inputs, type, sourceInformation,
4906 isSetter: selector.isSetter || selector.isIndexSet); 4914 isSetter: selector.isSetter || selector.isIndexSet);
4907 instruction.sideEffects = 4915 instruction.sideEffects =
4908 compiler.world.getSideEffectsOfSelector(selector, null); 4916 compiler.closedWorld.getSideEffectsOfSelector(selector, null);
4909 return instruction; 4917 return instruction;
4910 } 4918 }
4911 4919
4912 void handleComplexOperatorSend( 4920 void handleComplexOperatorSend(
4913 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) { 4921 ast.SendSet node, HInstruction receiver, Link<ast.Node> arguments) {
4914 HInstruction rhs; 4922 HInstruction rhs;
4915 if (node.isPrefix || node.isPostfix) { 4923 if (node.isPrefix || node.isPostfix) {
4916 rhs = graph.addConstantInt(1, compiler); 4924 rhs = graph.addConstantInt(1, compiler);
4917 } else { 4925 } else {
4918 visit(arguments.head); 4926 visit(arguments.head);
4919 assert(arguments.tail.isEmpty); 4927 assert(arguments.tail.isEmpty);
4920 rhs = pop(); 4928 rhs = pop();
4921 } 4929 }
4922 visitBinarySend( 4930 visitBinarySend(
4923 receiver, 4931 receiver,
4924 rhs, 4932 rhs,
4925 elements.getOperatorSelectorInComplexSendSet(node), 4933 elements.getOperatorSelectorInComplexSendSet(node),
4926 elements.getOperatorTypeMaskInComplexSendSet(node), 4934 elements.getOperatorTypeMaskInComplexSendSet(node),
4927 node, 4935 node,
4928 sourceInformation: 4936 sourceInformation:
4929 sourceInformationBuilder.buildGeneric(node.assignmentOperator)); 4937 sourceInformationBuilder.buildGeneric(node.assignmentOperator));
4930 } 4938 }
4931 4939
4932 void handleSuperSendSet(ast.SendSet node) { 4940 void handleSuperSendSet(ast.SendSet node) {
4933 Element element = elements[node]; 4941 Element element = elements[node];
4934 List<HInstruction> setterInputs = <HInstruction>[]; 4942 List<HInstruction> setterInputs = <HInstruction>[];
4935 void generateSuperSendSet() { 4943 void generateSuperSendSet() {
4936 Selector setterSelector = elements.getSelector(node); 4944 Selector setterSelector = elements.getSelector(node);
4937 if (Elements.isUnresolved(element) || 4945 if (Elements.isUnresolved(element) ||
4938 !setterSelector.applies(element, compiler.world)) { 4946 !setterSelector.applies(element, compiler.closedWorld)) {
4939 generateSuperNoSuchMethodSend(node, setterSelector, setterInputs); 4947 generateSuperNoSuchMethodSend(node, setterSelector, setterInputs);
4940 pop(); 4948 pop();
4941 } else { 4949 } else {
4942 add(buildInvokeSuper(setterSelector, element, setterInputs)); 4950 add(buildInvokeSuper(setterSelector, element, setterInputs));
4943 } 4951 }
4944 } 4952 }
4945 4953
4946 if (identical(node.assignmentOperator.source, '=')) { 4954 if (identical(node.assignmentOperator.source, '=')) {
4947 addDynamicSendArgumentsToList(node, setterInputs); 4955 addDynamicSendArgumentsToList(node, setterInputs);
4948 generateSuperSendSet(); 4956 generateSuperSendSet();
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
5901 visit(node.expression); 5909 visit(node.expression);
5902 HInstruction yielded = pop(); 5910 HInstruction yielded = pop();
5903 add(new HYield(yielded, node.hasStar)); 5911 add(new HYield(yielded, node.hasStar));
5904 } 5912 }
5905 5913
5906 visitAwait(ast.Await node) { 5914 visitAwait(ast.Await node) {
5907 visit(node.expression); 5915 visit(node.expression);
5908 HInstruction awaited = pop(); 5916 HInstruction awaited = pop();
5909 // TODO(herhut): Improve this type. 5917 // TODO(herhut): Improve this type.
5910 push(new HAwait(awaited, 5918 push(new HAwait(awaited,
5911 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); 5919 new TypeMask.subclass(coreClasses.objectClass, compiler.closedWorld)));
5912 } 5920 }
5913 5921
5914 visitTypeAnnotation(ast.TypeAnnotation node) { 5922 visitTypeAnnotation(ast.TypeAnnotation node) {
5915 reporter.internalError(node, 'Visiting type annotation in SSA builder.'); 5923 reporter.internalError(node, 'Visiting type annotation in SSA builder.');
5916 } 5924 }
5917 5925
5918 visitVariableDefinitions(ast.VariableDefinitions node) { 5926 visitVariableDefinitions(ast.VariableDefinitions node) {
5919 assert(isReachable); 5927 assert(isReachable);
5920 for (Link<ast.Node> link = node.definitions.nodes; 5928 for (Link<ast.Node> link = node.definitions.nodes;
5921 !link.isEmpty; 5929 !link.isEmpty;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
5962 visit(link.head); 5970 visit(link.head);
5963 inputs.add(pop()); 5971 inputs.add(pop());
5964 } 5972 }
5965 instruction = buildLiteralList(inputs); 5973 instruction = buildLiteralList(inputs);
5966 add(instruction); 5974 add(instruction);
5967 instruction = setRtiIfNeeded(instruction, node); 5975 instruction = setRtiIfNeeded(instruction, node);
5968 } 5976 }
5969 5977
5970 TypeMask type = 5978 TypeMask type =
5971 TypeMaskFactory.inferredForNode(sourceElement, node, compiler); 5979 TypeMaskFactory.inferredForNode(sourceElement, node, compiler);
5972 if (!type.containsAll(compiler.world)) instruction.instructionType = type; 5980 if (!type.containsAll(compiler.closedWorld))
5981 instruction.instructionType = type;
5973 stack.add(instruction); 5982 stack.add(instruction);
5974 } 5983 }
5975 5984
5976 visitConditional(ast.Conditional node) { 5985 visitConditional(ast.Conditional node) {
5977 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); 5986 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node);
5978 brancher.handleConditional(() => visit(node.condition), 5987 brancher.handleConditional(() => visit(node.condition),
5979 () => visit(node.thenExpression), () => visit(node.elseExpression)); 5988 () => visit(node.thenExpression), () => visit(node.elseExpression));
5980 } 5989 }
5981 5990
5982 visitStringInterpolation(ast.StringInterpolation node) { 5991 visitStringInterpolation(ast.StringInterpolation node) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
6062 [expression, graph.addConstantNull(compiler)]); 6071 [expression, graph.addConstantNull(compiler)]);
6063 streamIterator = pop(); 6072 streamIterator = pop();
6064 6073
6065 void buildInitializer() {} 6074 void buildInitializer() {}
6066 6075
6067 HInstruction buildCondition() { 6076 HInstruction buildCondition() {
6068 Selector selector = Selectors.moveNext; 6077 Selector selector = Selectors.moveNext;
6069 TypeMask mask = elements.getMoveNextTypeMask(node); 6078 TypeMask mask = elements.getMoveNextTypeMask(node);
6070 pushInvokeDynamic(node, selector, mask, [streamIterator]); 6079 pushInvokeDynamic(node, selector, mask, [streamIterator]);
6071 HInstruction future = pop(); 6080 HInstruction future = pop();
6072 push(new HAwait(future, 6081 push(new HAwait(
6073 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); 6082 future,
6083 new TypeMask.subclass(
6084 coreClasses.objectClass, compiler.closedWorld)));
6074 return popBoolified(); 6085 return popBoolified();
6075 } 6086 }
6076 6087
6077 void buildBody() { 6088 void buildBody() {
6078 Selector call = Selectors.current; 6089 Selector call = Selectors.current;
6079 TypeMask callMask = elements.getCurrentTypeMask(node); 6090 TypeMask callMask = elements.getCurrentTypeMask(node);
6080 pushInvokeDynamic(node, call, callMask, [streamIterator]); 6091 pushInvokeDynamic(node, call, callMask, [streamIterator]);
6081 6092
6082 ast.Node identifier = node.declaredIdentifier; 6093 ast.Node identifier = node.declaredIdentifier;
6083 Element variable = elements.getForInVariable(node); 6094 Element variable = elements.getForInVariable(node);
(...skipping 16 matching lines...) Expand all
6100 } 6111 }
6101 6112
6102 void buildUpdate() {} 6113 void buildUpdate() {}
6103 ; 6114 ;
6104 6115
6105 buildProtectedByFinally(() { 6116 buildProtectedByFinally(() {
6106 handleLoop( 6117 handleLoop(
6107 node, buildInitializer, buildCondition, buildUpdate, buildBody); 6118 node, buildInitializer, buildCondition, buildUpdate, buildBody);
6108 }, () { 6119 }, () {
6109 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); 6120 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
6110 push(new HAwait(pop(), 6121 push(new HAwait(
6111 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); 6122 pop(),
6123 new TypeMask.subclass(
6124 coreClasses.objectClass, compiler.closedWorld)));
6112 pop(); 6125 pop();
6113 }); 6126 });
6114 } 6127 }
6115 6128
6116 visitSyncForIn(ast.SyncForIn node) { 6129 visitSyncForIn(ast.SyncForIn node) {
6117 // The 'get iterator' selector for this node has the inferred receiver type. 6130 // The 'get iterator' selector for this node has the inferred receiver type.
6118 // If the receiver supports JavaScript indexing we generate an indexing loop 6131 // If the receiver supports JavaScript indexing we generate an indexing loop
6119 // instead of allocating an iterator object. 6132 // instead of allocating an iterator object.
6120 6133
6121 // This scheme recognizes for-in on direct lists. It does not recognize all 6134 // This scheme recognizes for-in on direct lists. It does not recognize all
6122 // uses of ArrayIterator. They still occur when the receiver is an Iterable 6135 // uses of ArrayIterator. They still occur when the receiver is an Iterable
6123 // with a `get iterator` method that delegate to another Iterable and the 6136 // with a `get iterator` method that delegate to another Iterable and the
6124 // method is inlined. We would require full scalar replacement in that 6137 // method is inlined. We would require full scalar replacement in that
6125 // case. 6138 // case.
6126 6139
6127 TypeMask mask = elements.getIteratorTypeMask(node); 6140 TypeMask mask = elements.getIteratorTypeMask(node);
6128 6141
6129 ClassWorld classWorld = compiler.world; 6142 ClassWorld classWorld = compiler.closedWorld;
6130 if (mask != null && 6143 if (mask != null &&
6131 mask.satisfies(helpers.jsIndexableClass, classWorld) && 6144 mask.satisfies(helpers.jsIndexableClass, classWorld) &&
6132 // String is indexable but not iterable. 6145 // String is indexable but not iterable.
6133 !mask.satisfies(helpers.jsStringClass, classWorld)) { 6146 !mask.satisfies(helpers.jsStringClass, classWorld)) {
6134 return buildSyncForInIndexable(node, mask); 6147 return buildSyncForInIndexable(node, mask);
6135 } 6148 }
6136 buildSyncForInIterator(node); 6149 buildSyncForInIterator(node);
6137 } 6150 }
6138 6151
6139 buildSyncForInIterator(ast.SyncForIn node) { 6152 buildSyncForInIterator(ast.SyncForIn node) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
6397 } 6410 }
6398 6411
6399 // If rti is needed and the map literal has no type parameters, 6412 // If rti is needed and the map literal has no type parameters,
6400 // 'constructor' is a static function that forwards the call to the factory 6413 // 'constructor' is a static function that forwards the call to the factory
6401 // constructor without type parameters. 6414 // constructor without type parameters.
6402 assert(constructor is ConstructorElement || constructor is FunctionElement); 6415 assert(constructor is ConstructorElement || constructor is FunctionElement);
6403 6416
6404 // The instruction type will always be a subtype of the mapLiteralClass, but 6417 // The instruction type will always be a subtype of the mapLiteralClass, but
6405 // type inference might discover a more specific type, or find nothing (in 6418 // type inference might discover a more specific type, or find nothing (in
6406 // dart2js unit tests). 6419 // dart2js unit tests).
6407 TypeMask mapType = 6420 TypeMask mapType = new TypeMask.nonNullSubtype(
6408 new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world); 6421 helpers.mapLiteralClass, compiler.closedWorld);
6409 TypeMask returnTypeMask = 6422 TypeMask returnTypeMask =
6410 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler); 6423 TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler);
6411 TypeMask instructionType = 6424 TypeMask instructionType =
6412 mapType.intersection(returnTypeMask, compiler.world); 6425 mapType.intersection(returnTypeMask, compiler.closedWorld);
6413 6426
6414 addInlinedInstantiation(expectedType); 6427 addInlinedInstantiation(expectedType);
6415 pushInvokeStatic(node, constructor, inputs, 6428 pushInvokeStatic(node, constructor, inputs,
6416 typeMask: instructionType, instanceType: expectedType); 6429 typeMask: instructionType, instanceType: expectedType);
6417 removeInlinedInstantiation(expectedType); 6430 removeInlinedInstantiation(expectedType);
6418 } 6431 }
6419 6432
6420 visitLiteralMapEntry(ast.LiteralMapEntry node) { 6433 visitLiteralMapEntry(ast.LiteralMapEntry node) {
6421 visit(node.value); 6434 visit(node.value);
6422 visit(node.key); 6435 visit(node.key);
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
7230 if (expression.canBePrimitive(compiler)) { 7243 if (expression.canBePrimitive(compiler)) {
7231 append(stringify(node, expression)); 7244 append(stringify(node, expression));
7232 return; 7245 return;
7233 } 7246 }
7234 7247
7235 // If the `toString` method is guaranteed to return a string we can call it 7248 // If the `toString` method is guaranteed to return a string we can call it
7236 // directly. 7249 // directly.
7237 Selector selector = Selectors.toString_; 7250 Selector selector = Selectors.toString_;
7238 TypeMask type = TypeMaskFactory.inferredTypeForSelector( 7251 TypeMask type = TypeMaskFactory.inferredTypeForSelector(
7239 selector, expression.instructionType, compiler); 7252 selector, expression.instructionType, compiler);
7240 if (type.containsOnlyString(compiler.world)) { 7253 if (type.containsOnlyString(compiler.closedWorld)) {
7241 builder.pushInvokeDynamic(node, selector, expression.instructionType, 7254 builder.pushInvokeDynamic(node, selector, expression.instructionType,
7242 <HInstruction>[expression]); 7255 <HInstruction>[expression]);
7243 append(builder.pop()); 7256 append(builder.pop());
7244 return; 7257 return;
7245 } 7258 }
7246 7259
7247 append(stringify(node, expression)); 7260 append(stringify(node, expression));
7248 } 7261 }
7249 7262
7250 void visitStringInterpolation(ast.StringInterpolation node) { 7263 void visitStringInterpolation(ast.StringInterpolation node) {
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
7545 const _LoopTypeVisitor(); 7558 const _LoopTypeVisitor();
7546 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; 7559 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
7547 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; 7560 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
7548 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 7561 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
7549 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 7562 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
7550 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 7563 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
7551 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 7564 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
7552 int visitSwitchStatement(ast.SwitchStatement node) => 7565 int visitSwitchStatement(ast.SwitchStatement node) =>
7553 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 7566 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
7554 } 7567 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/accessors.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698