| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 return initialValue == null; | 971 return initialValue == null; |
| 972 } | 972 } |
| 973 | 973 |
| 974 HType cachedTypeOfThis; | 974 HType cachedTypeOfThis; |
| 975 | 975 |
| 976 HType getTypeOfThis() { | 976 HType getTypeOfThis() { |
| 977 HType result = cachedTypeOfThis; | 977 HType result = cachedTypeOfThis; |
| 978 if (result == null) { | 978 if (result == null) { |
| 979 Element element = localsHandler.closureData.thisElement; | 979 Element element = localsHandler.closureData.thisElement; |
| 980 ClassElement cls = element.enclosingElement.getEnclosingClass(); | 980 ClassElement cls = element.enclosingElement.getEnclosingClass(); |
| 981 // Use the raw type because we don't have the type context for the | |
| 982 // type parameters. | |
| 983 DartType type = cls.rawType; | |
| 984 if (compiler.world.isUsedAsMixin(cls)) { | 981 if (compiler.world.isUsedAsMixin(cls)) { |
| 985 // If the enclosing class is used as a mixin, [:this:] can be | 982 // If the enclosing class is used as a mixin, [:this:] can be |
| 986 // of the class that mixins the enclosing class. These two | 983 // of the class that mixins the enclosing class. These two |
| 987 // classes do not have a subclass relationship, so, for | 984 // classes do not have a subclass relationship, so, for |
| 988 // simplicity, we mark the type as an interface type. | 985 // simplicity, we mark the type as an interface type. |
| 989 result = new HType.nonNullSubtype(type, compiler); | 986 result = new HType.nonNullSubtype(cls, compiler); |
| 990 } else { | 987 } else { |
| 991 result = new HType.nonNullSubclass(type, compiler); | 988 result = new HType.nonNullSubclass(cls, compiler); |
| 992 } | 989 } |
| 993 cachedTypeOfThis = result; | 990 cachedTypeOfThis = result; |
| 994 } | 991 } |
| 995 return result; | 992 return result; |
| 996 } | 993 } |
| 997 | 994 |
| 998 Map<Element, HType> cachedTypesOfCapturedVariables = | 995 Map<Element, HType> cachedTypesOfCapturedVariables = |
| 999 new Map<Element, HType>(); | 996 new Map<Element, HType>(); |
| 1000 | 997 |
| 1001 HType getTypeOfCapturedVariable(Element element) { | 998 HType getTypeOfCapturedVariable(Element element) { |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1654 // Call the JavaScript constructor with the fields as argument. | 1651 // Call the JavaScript constructor with the fields as argument. |
| 1655 List<HInstruction> constructorArguments = <HInstruction>[]; | 1652 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 1656 classElement.forEachInstanceField( | 1653 classElement.forEachInstanceField( |
| 1657 (ClassElement enclosingClass, Element member) { | 1654 (ClassElement enclosingClass, Element member) { |
| 1658 constructorArguments.add(potentiallyCheckType( | 1655 constructorArguments.add(potentiallyCheckType( |
| 1659 fieldValues[member], member.computeType(compiler))); | 1656 fieldValues[member], member.computeType(compiler))); |
| 1660 }, | 1657 }, |
| 1661 includeSuperAndInjectedMembers: true); | 1658 includeSuperAndInjectedMembers: true); |
| 1662 | 1659 |
| 1663 InterfaceType type = classElement.computeType(compiler); | 1660 InterfaceType type = classElement.computeType(compiler); |
| 1664 HType ssaType = new HType.nonNullExact(type, compiler); | 1661 HType ssaType = new HType.nonNullExact(classElement, compiler); |
| 1665 List<DartType> instantiatedTypes; | 1662 List<DartType> instantiatedTypes; |
| 1666 addInlinedInstantiation(type); | 1663 addInlinedInstantiation(type); |
| 1667 if (!currentInlinedInstantiations.isEmpty) { | 1664 if (!currentInlinedInstantiations.isEmpty) { |
| 1668 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 1665 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
| 1669 } | 1666 } |
| 1670 HForeignNew newObject = new HForeignNew(classElement, | 1667 HForeignNew newObject = new HForeignNew(classElement, |
| 1671 ssaType, | 1668 ssaType, |
| 1672 constructorArguments, | 1669 constructorArguments, |
| 1673 instantiatedTypes); | 1670 instantiatedTypes); |
| 1674 add(newObject); | 1671 add(newObject); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 assert(element is VariableElement); | 1798 assert(element is VariableElement); |
| 1802 } | 1799 } |
| 1803 } | 1800 } |
| 1804 | 1801 |
| 1805 HInstruction buildTypeConversion(HInstruction original, | 1802 HInstruction buildTypeConversion(HInstruction original, |
| 1806 DartType type, | 1803 DartType type, |
| 1807 int kind) { | 1804 int kind) { |
| 1808 if (type == null) return original; | 1805 if (type == null) return original; |
| 1809 type = type.unalias(compiler); | 1806 type = type.unalias(compiler); |
| 1810 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { | 1807 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { |
| 1811 HType subtype = new HType.subtype(type, compiler); | 1808 HType subtype = new HType.subtype(type.element, compiler); |
| 1812 HInstruction representations = buildTypeArgumentRepresentations(type); | 1809 HInstruction representations = buildTypeArgumentRepresentations(type); |
| 1813 add(representations); | 1810 add(representations); |
| 1814 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1811 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
| 1815 original, representations); | 1812 original, representations); |
| 1816 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1813 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 1817 HType subtype = original.instructionType; | 1814 HType subtype = original.instructionType; |
| 1818 HInstruction typeVariable = addTypeVariableReference(type); | 1815 HInstruction typeVariable = addTypeVariableReference(type); |
| 1819 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1816 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
| 1820 original, typeVariable); | 1817 original, typeVariable); |
| 1821 } else if (type.kind == TypeKind.FUNCTION) { | 1818 } else if (type.kind == TypeKind.FUNCTION) { |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2488 closureClassElement.forEachMember((_, Element member) { | 2485 closureClassElement.forEachMember((_, Element member) { |
| 2489 // The backendMembers also contains the call method(s). We are only | 2486 // The backendMembers also contains the call method(s). We are only |
| 2490 // interested in the fields. | 2487 // interested in the fields. |
| 2491 if (member.isField()) { | 2488 if (member.isField()) { |
| 2492 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 2489 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
| 2493 assert(capturedLocal != null); | 2490 assert(capturedLocal != null); |
| 2494 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2491 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 2495 } | 2492 } |
| 2496 }); | 2493 }); |
| 2497 | 2494 |
| 2498 HType type = new HType.nonNullExact( | 2495 HType type = new HType.nonNullExact(compiler.functionClass, compiler); |
| 2499 compiler.functionClass.computeType(compiler), | |
| 2500 compiler); | |
| 2501 push(new HForeignNew(closureClassElement, type, capturedVariables)); | 2496 push(new HForeignNew(closureClassElement, type, capturedVariables)); |
| 2502 | 2497 |
| 2503 Element methodElement = nestedClosureData.closureElement; | 2498 Element methodElement = nestedClosureData.closureElement; |
| 2504 if (compiler.backend.methodNeedsRti(methodElement)) { | 2499 if (compiler.backend.methodNeedsRti(methodElement)) { |
| 2505 compiler.backend.registerGenericClosure( | 2500 compiler.backend.registerGenericClosure( |
| 2506 methodElement, compiler.enqueuer.codegen, work.resolutionTree); | 2501 methodElement, compiler.enqueuer.codegen, work.resolutionTree); |
| 2507 } | 2502 } |
| 2508 } | 2503 } |
| 2509 | 2504 |
| 2510 visitFunctionDeclaration(FunctionDeclaration node) { | 2505 visitFunctionDeclaration(FunctionDeclaration node) { |
| (...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3524 new HType.inferredForNode(currentElement, send, compiler); | 3519 new HType.inferredForNode(currentElement, send, compiler); |
| 3525 return inferred.isUnknown() ? backend.fixedArrayType : inferred; | 3520 return inferred.isUnknown() ? backend.fixedArrayType : inferred; |
| 3526 } else if (Elements.isGrowableListConstructorCall( | 3521 } else if (Elements.isGrowableListConstructorCall( |
| 3527 originalElement, send, compiler)) { | 3522 originalElement, send, compiler)) { |
| 3528 isListConstructor = true; | 3523 isListConstructor = true; |
| 3529 HType inferred = | 3524 HType inferred = |
| 3530 new HType.inferredForNode(currentElement, send, compiler); | 3525 new HType.inferredForNode(currentElement, send, compiler); |
| 3531 return inferred.isUnknown() ? backend.extendableArrayType : inferred; | 3526 return inferred.isUnknown() ? backend.extendableArrayType : inferred; |
| 3532 } else if (element.isGenerativeConstructor()) { | 3527 } else if (element.isGenerativeConstructor()) { |
| 3533 ClassElement cls = element.getEnclosingClass(); | 3528 ClassElement cls = element.getEnclosingClass(); |
| 3534 return new HType.nonNullExact(cls.thisType, compiler); | 3529 return new HType.nonNullExact(cls.thisType.element, compiler); |
| 3535 } else { | 3530 } else { |
| 3536 return new HType.inferredReturnTypeForElement( | 3531 return new HType.inferredReturnTypeForElement( |
| 3537 originalElement, compiler); | 3532 originalElement, compiler); |
| 3538 } | 3533 } |
| 3539 } | 3534 } |
| 3540 | 3535 |
| 3541 Element constructor = elements[send]; | 3536 Element constructor = elements[send]; |
| 3542 Selector selector = elements.getSelector(send); | 3537 Selector selector = elements.getSelector(send); |
| 3543 FunctionElement functionElement = constructor; | 3538 FunctionElement functionElement = constructor; |
| 3544 constructor = functionElement.redirectionTarget; | 3539 constructor = functionElement.redirectionTarget; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3827 if (location == null) location = node; | 3822 if (location == null) location = node; |
| 3828 | 3823 |
| 3829 // We prefer to not inline certain operations on indexables, | 3824 // We prefer to not inline certain operations on indexables, |
| 3830 // because the constant folder will handle them better and turn | 3825 // because the constant folder will handle them better and turn |
| 3831 // them into simpler instructions that allow further | 3826 // them into simpler instructions that allow further |
| 3832 // optimizations. | 3827 // optimizations. |
| 3833 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { | 3828 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { |
| 3834 bool isLength = selector.isGetter() | 3829 bool isLength = selector.isGetter() |
| 3835 && selector.name == const SourceString("length"); | 3830 && selector.name == const SourceString("length"); |
| 3836 if (isLength || selector.isIndex()) { | 3831 if (isLength || selector.isIndex()) { |
| 3837 DartType classType = element.getEnclosingClass().computeType(compiler); | 3832 HType type = new HType.nonNullExact( |
| 3838 HType type = new HType.nonNullExact(classType, compiler); | 3833 element.getEnclosingClass(), compiler); |
| 3839 return type.isIndexable(compiler); | 3834 return type.isIndexable(compiler); |
| 3840 } else if (selector.isIndexSet()) { | 3835 } else if (selector.isIndexSet()) { |
| 3841 DartType classType = element.getEnclosingClass().computeType(compiler); | 3836 HType type = new HType.nonNullExact( |
| 3842 HType type = new HType.nonNullExact(classType, compiler); | 3837 element.getEnclosingClass(), compiler); |
| 3843 return type.isMutableIndexable(compiler); | 3838 return type.isMutableIndexable(compiler); |
| 3844 } else { | 3839 } else { |
| 3845 return false; | 3840 return false; |
| 3846 } | 3841 } |
| 3847 } | 3842 } |
| 3848 | 3843 |
| 3849 bool isOptimizableOperation(Selector selector, Element element) { | 3844 bool isOptimizableOperation(Selector selector, Element element) { |
| 3850 ClassElement cls = element.getEnclosingClass(); | 3845 ClassElement cls = element.getEnclosingClass(); |
| 3851 if (isOptimizableOperationOnIndexable(selector, element)) return true; | 3846 if (isOptimizableOperationOnIndexable(selector, element)) return true; |
| 3852 if (!backend.interceptedClasses.contains(cls)) return false; | 3847 if (!backend.interceptedClasses.contains(cls)) return false; |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4495 List<HInstruction> inputs = <HInstruction>[]; | 4490 List<HInstruction> inputs = <HInstruction>[]; |
| 4496 for (Link<Node> link = node.entries.nodes; | 4491 for (Link<Node> link = node.entries.nodes; |
| 4497 !link.isEmpty; | 4492 !link.isEmpty; |
| 4498 link = link.tail) { | 4493 link = link.tail) { |
| 4499 visit(link.head); | 4494 visit(link.head); |
| 4500 inputs.add(pop()); | 4495 inputs.add(pop()); |
| 4501 inputs.add(pop()); | 4496 inputs.add(pop()); |
| 4502 } | 4497 } |
| 4503 HLiteralList keyValuePairs = buildLiteralList(inputs); | 4498 HLiteralList keyValuePairs = buildLiteralList(inputs); |
| 4504 add(keyValuePairs); | 4499 add(keyValuePairs); |
| 4505 HType mapType = new HType.nonNullSubtype( | 4500 HType mapType = new HType.nonNullSubtype(backend.mapLiteralClass, compiler); |
| 4506 backend.mapLiteralClass.computeType(compiler), compiler); | |
| 4507 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); | 4501 pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType); |
| 4508 } | 4502 } |
| 4509 | 4503 |
| 4510 visitLiteralMapEntry(LiteralMapEntry node) { | 4504 visitLiteralMapEntry(LiteralMapEntry node) { |
| 4511 visit(node.value); | 4505 visit(node.value); |
| 4512 visit(node.key); | 4506 visit(node.key); |
| 4513 } | 4507 } |
| 4514 | 4508 |
| 4515 visitNamedArgument(NamedArgument node) { | 4509 visitNamedArgument(NamedArgument node) { |
| 4516 visit(node.expression); | 4510 visit(node.expression); |
| (...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5560 new HSubGraphBlockInformation(elseBranch.graph)); | 5554 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5561 | 5555 |
| 5562 HBasicBlock conditionStartBlock = conditionBranch.block; | 5556 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5563 conditionStartBlock.setBlockFlow(info, joinBlock); | 5557 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5564 SubGraph conditionGraph = conditionBranch.graph; | 5558 SubGraph conditionGraph = conditionBranch.graph; |
| 5565 HIf branch = conditionGraph.end.last; | 5559 HIf branch = conditionGraph.end.last; |
| 5566 assert(branch is HIf); | 5560 assert(branch is HIf); |
| 5567 branch.blockInformation = conditionStartBlock.blockFlow; | 5561 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5568 } | 5562 } |
| 5569 } | 5563 } |
| OLD | NEW |