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

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

Issue 1398393002: Decouple SSA builder from codegen-work-item (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
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 SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 final SsaCodeGeneratorTask generator; 8 final SsaCodeGeneratorTask generator;
9 final SsaBuilderTask builder; 9 final SsaBuilderTask builder;
10 final SsaOptimizerTask optimizer; 10 final SsaOptimizerTask optimizer;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 : emitter = backend.emitter, 59 : emitter = backend.emitter,
60 backend = backend, 60 backend = backend,
61 super(backend.compiler); 61 super(backend.compiler);
62 62
63 DiagnosticReporter get reporter => compiler.reporter; 63 DiagnosticReporter get reporter => compiler.reporter;
64 64
65 HGraph build(CodegenWorkItem work) { 65 HGraph build(CodegenWorkItem work) {
66 return measure(() { 66 return measure(() {
67 Element element = work.element.implementation; 67 Element element = work.element.implementation;
68 return reporter.withCurrentElement(element, () { 68 return reporter.withCurrentElement(element, () {
69 HInstruction.idCounter = 0;
70 SsaBuilder builder = 69 SsaBuilder builder =
71 new SsaBuilder( 70 new SsaBuilder(work.element.implementation,
72 backend, work, emitter.nativeEmitter, 71 work.resolutionTree, work.compilationContext, work.registry,
72 backend, emitter.nativeEmitter,
73 sourceInformationFactory); 73 sourceInformationFactory);
74 HGraph graph; 74 HGraph graph = builder.build();
75 ElementKind kind = element.kind; 75
76 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 76 // Default arguments are handled elsewhere, but we must ensure
77 graph = compileConstructor(builder, work); 77 // that the default values are computed during codegen.
78 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 78 if (!identical(element.kind, ElementKind.FIELD)) {
79 kind == ElementKind.FUNCTION ||
80 kind == ElementKind.GETTER ||
81 kind == ElementKind.SETTER) {
82 graph = builder.buildMethod(element);
83 } else if (kind == ElementKind.FIELD) {
84 if (element.isInstanceMember) {
85 assert(compiler.enableTypeAssertions);
86 graph = builder.buildCheckedSetter(element);
87 } else {
88 graph = builder.buildLazyInitializer(element);
89 }
90 } else {
91 reporter.internalError(element, 'Unexpected element kind $kind.');
92 }
93 assert(graph.isValid());
94 if (!identical(kind, ElementKind.FIELD)) {
95 FunctionElement function = element; 79 FunctionElement function = element;
96 FunctionSignature signature = function.functionSignature; 80 FunctionSignature signature = function.functionSignature;
97 signature.forEachOptionalParameter((ParameterElement parameter) { 81 signature.forEachOptionalParameter((ParameterElement parameter) {
98 // This ensures the default value will be computed. 82 // This ensures the default value will be computed.
99 ConstantValue constant = 83 ConstantValue constant =
100 backend.constants.getConstantValueForVariable(parameter); 84 backend.constants.getConstantValueForVariable(parameter);
101 CodegenRegistry registry = work.registry; 85 work.registry.registerCompileTimeConstant(constant);
102 registry.registerCompileTimeConstant(constant);
103 }); 86 });
104 } 87 }
105 if (compiler.tracer.isEnabled) { 88 if (compiler.tracer.isEnabled) {
106 String name; 89 String name;
107 if (element.isClassMember) { 90 if (element.isClassMember) {
108 String className = element.enclosingClass.name; 91 String className = element.enclosingClass.name;
109 String memberName = element.name; 92 String memberName = element.name;
110 name = "$className.$memberName"; 93 name = "$className.$memberName";
111 if (element.isGenerativeConstructorBody) { 94 if (element.isGenerativeConstructorBody) {
112 name = "$name (body)"; 95 name = "$name (body)";
113 } 96 }
114 } else { 97 } else {
115 name = "${element.name}"; 98 name = "${element.name}";
116 } 99 }
117 compiler.tracer.traceCompilation( 100 compiler.tracer.traceCompilation(
118 name, work.compilationContext); 101 name, work.compilationContext);
119 compiler.tracer.traceGraph('builder', graph); 102 compiler.tracer.traceGraph('builder', graph);
120 } 103 }
121 return graph; 104 return graph;
122 }); 105 });
123 }); 106 });
124 } 107 }
125 108
126 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) {
127 return builder.buildFactory(work.element);
128 }
129 } 109 }
130 110
131 /** 111 /**
132 * Keeps track of locals (including parameters and phis) when building. The 112 * Keeps track of locals (including parameters and phis) when building. The
133 * 'this' reference is treated as parameter and hence handled by this class, 113 * 'this' reference is treated as parameter and hence handled by this class,
134 * too. 114 * too.
135 */ 115 */
136 class LocalsHandler { 116 class LocalsHandler {
137 /** 117 /**
138 * The values of locals that can be directly accessed (without redirections 118 * The values of locals that can be directly accessed (without redirections
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 * This class builds SSA nodes for functions represented in AST. 971 * This class builds SSA nodes for functions represented in AST.
992 */ 972 */
993 class SsaBuilder extends ast.Visitor 973 class SsaBuilder extends ast.Visitor
994 with BaseImplementationOfCompoundsMixin, 974 with BaseImplementationOfCompoundsMixin,
995 BaseImplementationOfSetIfNullsMixin, 975 BaseImplementationOfSetIfNullsMixin,
996 SendResolverMixin, 976 SendResolverMixin,
997 SemanticSendResolvedMixin, 977 SemanticSendResolvedMixin,
998 NewBulkMixin, 978 NewBulkMixin,
999 ErrorBulkMixin 979 ErrorBulkMixin
1000 implements SemanticSendVisitor { 980 implements SemanticSendVisitor {
981
982 /// The element for which this SSA builder is being used.
983 final Element target;
984
985 /// Reference to resolved elements in [target]'s AST.
986 TreeElements elements;
987
988 /// Used to report information about inlining (which occurs while building the
989 /// SSA graph), when dump-info is enabled.
990 final InfoReporter infoReporter;
991
992 /// If not null, the builder will store in [context] data that is used later
993 /// during the optimization phases.
994 final JavaScriptItemCompilationContext context;
995
996 /// Registry used to enqueue work during codegen, may be null to avoid
997 /// enqueing any work.
998 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be
999 // able to return the impact as a result after building and avoid enqueing
1000 // things here. Later the codegen task can decide whether to enqueue
1001 // something. In the past this didn't matter as much because the SSA graph was
1002 // used only for codegen, but currently we want to experiment using it for
1003 // code-analysis too.
1004 final CodegenRegistry registry;
1001 final Compiler compiler; 1005 final Compiler compiler;
1002 final JavaScriptBackend backend; 1006 final JavaScriptBackend backend;
1003 final ConstantSystem constantSystem; 1007 final ConstantSystem constantSystem;
1004 final CodegenWorkItem work;
1005 final RuntimeTypes rti; 1008 final RuntimeTypes rti;
1006 TreeElements elements; 1009
1007 SourceInformationBuilder sourceInformationBuilder; 1010 SourceInformationBuilder sourceInformationBuilder;
1011
1008 bool inLazyInitializerExpression = false; 1012 bool inLazyInitializerExpression = false;
1009 1013
1014 // TODO(sigmund): make all comments /// instead of /* */
1010 /* This field is used by the native handler. */ 1015 /* This field is used by the native handler. */
1011 final NativeEmitter nativeEmitter; 1016 final NativeEmitter nativeEmitter;
1012 1017
1018 /// Holds the resulting SSA graph.
1013 final HGraph graph = new HGraph(); 1019 final HGraph graph = new HGraph();
1014 1020
1015 /** 1021 /**
1016 * The current block to add instructions to. Might be null, if we are 1022 * The current block to add instructions to. Might be null, if we are
1017 * visiting dead code, but see [isReachable]. 1023 * visiting dead code, but see [isReachable].
1018 */ 1024 */
1019 HBasicBlock _current; 1025 HBasicBlock _current;
1020 1026
1021 HBasicBlock get current => _current; 1027 HBasicBlock get current => _current;
1022 1028
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 // We build the Ssa graph by simulating a stack machine. 1088 // We build the Ssa graph by simulating a stack machine.
1083 List<HInstruction> stack = <HInstruction>[]; 1089 List<HInstruction> stack = <HInstruction>[];
1084 1090
1085 /// Returns `true` if the current element is an `async` function. 1091 /// Returns `true` if the current element is an `async` function.
1086 bool get isBuildingAsyncFunction { 1092 bool get isBuildingAsyncFunction {
1087 Element element = sourceElement; 1093 Element element = sourceElement;
1088 return (element is FunctionElement && 1094 return (element is FunctionElement &&
1089 element.asyncMarker == AsyncMarker.ASYNC); 1095 element.asyncMarker == AsyncMarker.ASYNC);
1090 } 1096 }
1091 1097
1092 SsaBuilder(JavaScriptBackend backend, 1098 // TODO(sigmund): make most args optional
1093 CodegenWorkItem work, 1099 SsaBuilder(this.target, this.elements, this.context, this.registry,
1094 this.nativeEmitter, 1100 JavaScriptBackend backend, this.nativeEmitter,
1095 SourceInformationStrategy sourceInformationFactory) 1101 SourceInformationStrategy sourceInformationFactory)
1096 : this.compiler = backend.compiler, 1102 : this.compiler = backend.compiler,
1103 this.infoReporter = backend.compiler.dumpInfoTask,
1097 this.backend = backend, 1104 this.backend = backend,
1098 this.constantSystem = backend.constantSystem, 1105 this.constantSystem = backend.constantSystem,
1099 this.work = work, 1106 this.rti = backend.rti {
1100 this.rti = backend.rti, 1107 graph.element = target;
1101 this.elements = work.resolutionTree { 1108 localsHandler = new LocalsHandler(this, target, null);
1102 graph.element = work.element; 1109 sourceElementStack.add(target);
1103 localsHandler = new LocalsHandler(this, work.element, null); 1110 sourceInformationBuilder = sourceInformationFactory.createBuilderForContext(
1104 sourceElementStack.add(work.element); 1111 target.implementation);
Johnni Winther 2015/10/13 07:26:27 Seems to be the invariant that [target] is already
Siggi Cherem (dart-lang) 2015/10/13 16:30:44 Good point. done
1105 sourceInformationBuilder =
1106 sourceInformationFactory.createBuilderForContext(
1107 work.element.implementation);
1108 } 1112 }
1109 1113
1110 BackendHelpers get helpers => backend.helpers; 1114 BackendHelpers get helpers => backend.helpers;
1111 1115
1112 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; 1116 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder;
1113 1117
1114 DiagnosticReporter get reporter => compiler.reporter; 1118 DiagnosticReporter get reporter => compiler.reporter;
1115 1119
1116 @override 1120 @override
1117 SemanticSendVisitor get sendVisitor => this; 1121 SemanticSendVisitor get sendVisitor => this;
1118 1122
1119 @override 1123 @override
1120 void visitNode(ast.Node node) { 1124 void visitNode(ast.Node node) {
1121 internalError(node, "Unhandled node: $node"); 1125 internalError(node, "Unhandled node: $node");
1122 } 1126 }
1123 1127
1124 @override 1128 @override
1125 void apply(ast.Node node, [_]) { 1129 void apply(ast.Node node, [_]) {
1126 node.accept(this); 1130 node.accept(this);
1127 } 1131 }
1128 1132
1129 CodegenRegistry get registry => work.registry;
1130
1131 /// Returns the current source element. 1133 /// Returns the current source element.
1132 /// 1134 ///
1133 /// The returned element is a declaration element. 1135 /// The returned element is a declaration element.
1134 // TODO(johnniwinther): Check that all usages of sourceElement agree on 1136 // TODO(johnniwinther): Check that all usages of sourceElement agree on
1135 // implementation/declaration distinction. 1137 // implementation/declaration distinction.
1136 Element get sourceElement => sourceElementStack.last; 1138 Element get sourceElement => sourceElementStack.last;
1137 1139
1138 bool get _checkOrTrustTypes => 1140 bool get _checkOrTrustTypes =>
1139 compiler.enableTypeAssertions || compiler.trustTypeAnnotations; 1141 compiler.enableTypeAssertions || compiler.trustTypeAnnotations;
1140 1142
1143 /// Build the graph for [target].
1144 HGraph build() {
1145 assert(invariant(target, target.isImplementation));
1146 HInstruction.idCounter = 0;
1147 ElementKind kind = target.kind;
1148 // TODO(sigmund): remove `result` and return graph directly, need to ensure
1149 // that it can never be null (see result in buildFactory for instance).
1150 var result;
1151 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
1152 result = buildFactory(target);
1153 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
1154 kind == ElementKind.FUNCTION ||
1155 kind == ElementKind.GETTER ||
1156 kind == ElementKind.SETTER) {
1157 result = buildMethod(target);
1158 } else if (kind == ElementKind.FIELD) {
1159 if (target.isInstanceMember) {
1160 assert(compiler.enableTypeAssertions);
1161 result = buildCheckedSetter(target);
1162 } else {
1163 result = buildLazyInitializer(target);
1164 }
1165 } else {
1166 reporter.internalError(target, 'Unexpected element kind $kind.');
1167 }
1168 assert(result.isValid());
1169 return result;
1170 }
1171
1172
1141 HBasicBlock addNewBlock() { 1173 HBasicBlock addNewBlock() {
1142 HBasicBlock block = graph.addNewBlock(); 1174 HBasicBlock block = graph.addNewBlock();
1143 // If adding a new block during building of an expression, it is due to 1175 // If adding a new block during building of an expression, it is due to
1144 // conditional expressions or short-circuit logical operators. 1176 // conditional expressions or short-circuit logical operators.
1145 return block; 1177 return block;
1146 } 1178 }
1147 1179
1148 void open(HBasicBlock block) { 1180 void open(HBasicBlock block) {
1149 block.open(); 1181 block.open();
1150 current = block; 1182 current = block;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 emitReturn(graph.addConstantNull(compiler), null); 1505 emitReturn(graph.addConstantNull(compiler), null);
1474 } else { 1506 } else {
1475 doInline(function); 1507 doInline(function);
1476 } 1508 }
1477 }); 1509 });
1478 leaveInlinedMethod(); 1510 leaveInlinedMethod();
1479 } 1511 }
1480 1512
1481 if (meetsHardConstraints() && heuristicSayGoodToGo()) { 1513 if (meetsHardConstraints() && heuristicSayGoodToGo()) {
1482 doInlining(); 1514 doInlining();
1483 registry.registerInlining( 1515 infoReporter?.reportInlined(element, target);
Siggi Cherem (dart-lang) 2015/10/13 16:30:44 Note: I had to change this before submitting: The
1484 element,
1485 compiler.currentElement);
1486 return true; 1516 return true;
1487 } 1517 }
1488 1518
1489 return false; 1519 return false;
1490 } 1520 }
1491 1521
1492 bool get allInlinedFunctionsCalledOnce { 1522 bool get allInlinedFunctionsCalledOnce {
1493 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; 1523 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
1494 } 1524 }
1495 1525
(...skipping 30 matching lines...) Expand all
1526 Element get currentNonClosureClass { 1556 Element get currentNonClosureClass {
1527 ClassElement cls = sourceElement.enclosingClass; 1557 ClassElement cls = sourceElement.enclosingClass;
1528 if (cls != null && cls.isClosure) { 1558 if (cls != null && cls.isClosure) {
1529 var closureClass = cls; 1559 var closureClass = cls;
1530 return closureClass.methodElement.enclosingClass; 1560 return closureClass.methodElement.enclosingClass;
1531 } else { 1561 } else {
1532 return cls; 1562 return cls;
1533 } 1563 }
1534 } 1564 }
1535 1565
1536 /**
1537 * Returns whether this builder is building code for [element].
1538 */
1539 bool isBuildingFor(Element element) {
1540 return work.element == element;
1541 }
1542
1543 /// A stack of [DartType]s the have been seen during inlining of factory 1566 /// A stack of [DartType]s the have been seen during inlining of factory
1544 /// constructors. These types are preserved in [HInvokeStatic]s and 1567 /// constructors. These types are preserved in [HInvokeStatic]s and
1545 /// [HForeignNew]s inside the inline code and registered during code 1568 /// [HForeignNew]s inside the inline code and registered during code
1546 /// generation for these nodes. 1569 /// generation for these nodes.
1547 // TODO(karlklose): consider removing this and keeping the (substituted) 1570 // TODO(karlklose): consider removing this and keeping the (substituted)
1548 // types of the type variables in an environment (like the [LocalsHandler]). 1571 // types of the type variables in an environment (like the [LocalsHandler]).
1549 final List<DartType> currentInlinedInstantiations = <DartType>[]; 1572 final List<DartType> currentInlinedInstantiations = <DartType>[];
1550 1573
1551 final List<AstInliningState> inliningStack = <AstInliningState>[]; 1574 final List<AstInliningState> inliningStack = <AstInliningState>[];
1552 1575
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 /** 1625 /**
1603 * Documentation wanted -- johnniwinther 1626 * Documentation wanted -- johnniwinther
1604 * 1627 *
1605 * Invariant: [functionElement] must be an implementation element. 1628 * Invariant: [functionElement] must be an implementation element.
1606 */ 1629 */
1607 HGraph buildMethod(FunctionElement functionElement) { 1630 HGraph buildMethod(FunctionElement functionElement) {
1608 assert(invariant(functionElement, functionElement.isImplementation)); 1631 assert(invariant(functionElement, functionElement.isImplementation));
1609 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); 1632 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
1610 ast.FunctionExpression function = functionElement.node; 1633 ast.FunctionExpression function = functionElement.node;
1611 assert(function != null); 1634 assert(function != null);
1612 assert(!function.modifiers.isExternal); 1635 assert(invariant(functionElement, !function.modifiers.isExternal));
1613 assert(elements.getFunctionDefinition(function) != null); 1636 assert(elements.getFunctionDefinition(function) != null);
1614 openFunction(functionElement, function); 1637 openFunction(functionElement, function);
1615 String name = functionElement.name; 1638 String name = functionElement.name;
1616 // If [functionElement] is `operator==` we explicitely add a null check at 1639 // If [functionElement] is `operator==` we explicitely add a null check at
1617 // the beginning of the method. This is to avoid having call sites do the 1640 // the beginning of the method. This is to avoid having call sites do the
1618 // null check. 1641 // null check.
1619 if (name == '==') { 1642 if (name == '==') {
1620 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 1643 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
1621 handleIf( 1644 handleIf(
1622 function, 1645 function,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 // If the method is intercepted, we want the actual receiver 1696 // If the method is intercepted, we want the actual receiver
1674 // to be the first parameter. 1697 // to be the first parameter.
1675 graph.entry.addBefore(graph.entry.last, parameter); 1698 graph.entry.addBefore(graph.entry.last, parameter);
1676 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); 1699 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type);
1677 add(new HFieldSet(field, thisInstruction, value)); 1700 add(new HFieldSet(field, thisInstruction, value));
1678 return closeFunction(); 1701 return closeFunction();
1679 } 1702 }
1680 1703
1681 HGraph buildLazyInitializer(VariableElement variable) { 1704 HGraph buildLazyInitializer(VariableElement variable) {
1682 inLazyInitializerExpression = true; 1705 inLazyInitializerExpression = true;
1706 assert(invariant(variable, variable.initializer != null,
1707 message: "Non-constant variable $variable has no initializer."));
1683 ast.VariableDefinitions node = variable.node; 1708 ast.VariableDefinitions node = variable.node;
1684 openFunction(variable, node); 1709 openFunction(variable, node);
1685 assert(invariant(variable, variable.initializer != null,
1686 message: "Non-constant variable $variable has no initializer."));
1687 visit(variable.initializer); 1710 visit(variable.initializer);
1688 HInstruction value = pop(); 1711 HInstruction value = pop();
1689 value = potentiallyCheckOrTrustType(value, variable.type); 1712 value = potentiallyCheckOrTrustType(value, variable.type);
1690 ast.SendSet sendSet = node.definitions.nodes.head; 1713 ast.SendSet sendSet = node.definitions.nodes.head;
1691 closeAndGotoExit(new HReturn(value, 1714 closeAndGotoExit(new HReturn(value,
1692 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator))); 1715 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)));
1693 return closeFunction(); 1716 return closeFunction();
1694 } 1717 }
1695 1718
1696 /** 1719 /**
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 if (element == compiler.objectClass) return original; 2554 if (element == compiler.objectClass) return original;
2532 TypeMask mask = new TypeMask.subtype(element, compiler.world); 2555 TypeMask mask = new TypeMask.subtype(element, compiler.world);
2533 return new HTypeKnown.pinned(mask, original); 2556 return new HTypeKnown.pinned(mask, original);
2534 } 2557 }
2535 2558
2536 HInstruction _checkType(HInstruction original, DartType type, int kind) { 2559 HInstruction _checkType(HInstruction original, DartType type, int kind) {
2537 assert(compiler.enableTypeAssertions); 2560 assert(compiler.enableTypeAssertions);
2538 assert(type != null); 2561 assert(type != null);
2539 type = localsHandler.substInContext(type); 2562 type = localsHandler.substInContext(type);
2540 HInstruction other = buildTypeConversion(original, type, kind); 2563 HInstruction other = buildTypeConversion(original, type, kind);
2541 registry.registerIsCheck(type); 2564 registry?.registerIsCheck(type);
2542 return other; 2565 return other;
2543 } 2566 }
2544 2567
2545 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, 2568 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type,
2546 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 2569 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
2547 if (type == null) return original; 2570 if (type == null) return original;
2548 HInstruction checkedOrTrusted = original; 2571 HInstruction checkedOrTrusted = original;
2549 if (compiler.trustTypeAnnotations) { 2572 if (compiler.trustTypeAnnotations) {
2550 checkedOrTrusted = _trustType(original, type); 2573 checkedOrTrusted = _trustType(original, type);
2551 } else if (compiler.enableTypeAssertions) { 2574 } else if (compiler.enableTypeAssertions) {
(...skipping 10 matching lines...) Expand all
2562 analyzeTypeArgument(localsHandler.substInContext(subtype)); 2585 analyzeTypeArgument(localsHandler.substInContext(subtype));
2563 HInstruction supertypeInstruction = 2586 HInstruction supertypeInstruction =
2564 analyzeTypeArgument(localsHandler.substInContext(supertype)); 2587 analyzeTypeArgument(localsHandler.substInContext(supertype));
2565 HInstruction messageInstruction = 2588 HInstruction messageInstruction =
2566 graph.addConstantString(new ast.DartString.literal(message), compiler); 2589 graph.addConstantString(new ast.DartString.literal(message), compiler);
2567 Element element = helpers.assertIsSubtype; 2590 Element element = helpers.assertIsSubtype;
2568 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction, 2591 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
2569 messageInstruction]; 2592 messageInstruction];
2570 HInstruction assertIsSubtype = new HInvokeStatic( 2593 HInstruction assertIsSubtype = new HInvokeStatic(
2571 element, inputs, subtypeInstruction.instructionType); 2594 element, inputs, subtypeInstruction.instructionType);
2572 registry.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); 2595 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
2573 add(assertIsSubtype); 2596 add(assertIsSubtype);
2574 } 2597 }
2575 2598
2576 HGraph closeFunction() { 2599 HGraph closeFunction() {
2577 // TODO(kasperl): Make this goto an implicit return. 2600 // TODO(kasperl): Make this goto an implicit return.
2578 if (!isAborted()) closeAndGotoExit(new HGoto()); 2601 if (!isAborted()) closeAndGotoExit(new HGoto());
2579 graph.finalize(); 2602 graph.finalize();
2580 return graph; 2603 return graph;
2581 } 2604 }
2582 2605
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 ClosureClassMap nestedClosureData = 3200 ClosureClassMap nestedClosureData =
3178 compiler.closureToClassMapper.getMappingForNestedFunction(node); 3201 compiler.closureToClassMapper.getMappingForNestedFunction(node);
3179 assert(nestedClosureData != null); 3202 assert(nestedClosureData != null);
3180 assert(nestedClosureData.closureClassElement != null); 3203 assert(nestedClosureData.closureClassElement != null);
3181 ClosureClassElement closureClassElement = 3204 ClosureClassElement closureClassElement =
3182 nestedClosureData.closureClassElement; 3205 nestedClosureData.closureClassElement;
3183 FunctionElement callElement = nestedClosureData.callElement; 3206 FunctionElement callElement = nestedClosureData.callElement;
3184 // TODO(ahe): This should be registered in codegen, not here. 3207 // TODO(ahe): This should be registered in codegen, not here.
3185 // TODO(johnniwinther): Is [registerStaticUse] equivalent to 3208 // TODO(johnniwinther): Is [registerStaticUse] equivalent to
3186 // [addToWorkList]? 3209 // [addToWorkList]?
3187 registry.registerStaticUse(callElement); 3210 registry?.registerStaticUse(callElement);
3188 3211
3189 List<HInstruction> capturedVariables = <HInstruction>[]; 3212 List<HInstruction> capturedVariables = <HInstruction>[];
3190 closureClassElement.closureFields.forEach((ClosureFieldElement field) { 3213 closureClassElement.closureFields.forEach((ClosureFieldElement field) {
3191 Local capturedLocal = 3214 Local capturedLocal =
3192 nestedClosureData.getLocalVariableForClosureField(field); 3215 nestedClosureData.getLocalVariableForClosureField(field);
3193 assert(capturedLocal != null); 3216 assert(capturedLocal != null);
3194 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 3217 capturedVariables.add(localsHandler.readLocal(capturedLocal));
3195 }); 3218 });
3196 3219
3197 TypeMask type = 3220 TypeMask type =
3198 new TypeMask.nonNullExact(compiler.functionClass, compiler.world); 3221 new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
3199 push(new HForeignNew(closureClassElement, type, capturedVariables) 3222 push(new HForeignNew(closureClassElement, type, capturedVariables)
3200 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); 3223 ..sourceInformation = sourceInformationBuilder.buildCreate(node));
3201 3224
3202 Element methodElement = nestedClosureData.closureElement; 3225 Element methodElement = nestedClosureData.closureElement;
3203 registry.registerInstantiatedClosure(methodElement); 3226 registry?.registerInstantiatedClosure(methodElement);
3204 } 3227 }
3205 3228
3206 visitFunctionDeclaration(ast.FunctionDeclaration node) { 3229 visitFunctionDeclaration(ast.FunctionDeclaration node) {
3207 assert(isReachable); 3230 assert(isReachable);
3208 visit(node.function); 3231 visit(node.function);
3209 LocalFunctionElement localFunction = 3232 LocalFunctionElement localFunction =
3210 elements.getFunctionDefinition(node.function); 3233 elements.getFunctionDefinition(node.function);
3211 localsHandler.updateLocal(localFunction, pop()); 3234 localsHandler.updateLocal(localFunction, pop());
3212 } 3235 }
3213 3236
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
4385 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration 4408 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
4386 // and implementation signatures. Currently it is need because the 4409 // and implementation signatures. Currently it is need because the
4387 // signatures have different elements for parameters. 4410 // signatures have different elements for parameters.
4388 FunctionElement implementation = function.implementation; 4411 FunctionElement implementation = function.implementation;
4389 FunctionSignature params = implementation.functionSignature; 4412 FunctionSignature params = implementation.functionSignature;
4390 if (params.optionalParameterCount != 0) { 4413 if (params.optionalParameterCount != 0) {
4391 reporter.internalError(closure, 4414 reporter.internalError(closure,
4392 '"$name" does not handle closure with optional parameters.'); 4415 '"$name" does not handle closure with optional parameters.');
4393 } 4416 }
4394 4417
4395 registry.registerStaticUse(element); 4418 registry?.registerStaticUse(element);
4396 push(new HForeignCode( 4419 push(new HForeignCode(
4397 js.js.expressionTemplateYielding( 4420 js.js.expressionTemplateYielding(
4398 backend.emitter.staticFunctionAccess(element)), 4421 backend.emitter.staticFunctionAccess(element)),
4399 backend.dynamicType, 4422 backend.dynamicType,
4400 <HInstruction>[], 4423 <HInstruction>[],
4401 nativeBehavior: native.NativeBehavior.PURE)); 4424 nativeBehavior: native.NativeBehavior.PURE));
4402 return params; 4425 return params;
4403 } 4426 }
4404 4427
4405 void handleForeignDartClosureToJs(ast.Send node, String name) { 4428 void handleForeignDartClosureToJs(ast.Send node, String name) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
4492 String name = selector.name; 4515 String name = selector.name;
4493 4516
4494 ClassElement cls = currentNonClosureClass; 4517 ClassElement cls = currentNonClosureClass;
4495 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); 4518 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
4496 if (compiler.enabledInvokeOn 4519 if (compiler.enabledInvokeOn
4497 && element.enclosingElement.declaration != compiler.objectClass) { 4520 && element.enclosingElement.declaration != compiler.objectClass) {
4498 // Register the call as dynamic if [noSuchMethod] on the super 4521 // Register the call as dynamic if [noSuchMethod] on the super
4499 // class is _not_ the default implementation from [Object], in 4522 // class is _not_ the default implementation from [Object], in
4500 // case the [noSuchMethod] implementation calls 4523 // case the [noSuchMethod] implementation calls
4501 // [JSInvocationMirror._invokeOn]. 4524 // [JSInvocationMirror._invokeOn].
4502 registry.registerSelectorUse(selector); 4525 registry?.registerSelectorUse(selector);
4503 } 4526 }
4504 String publicName = name; 4527 String publicName = name;
4505 if (selector.isSetter) publicName += '='; 4528 if (selector.isSetter) publicName += '=';
4506 4529
4507 ConstantValue nameConstant = constantSystem.createString( 4530 ConstantValue nameConstant = constantSystem.createString(
4508 new ast.DartString.literal(publicName)); 4531 new ast.DartString.literal(publicName));
4509 4532
4510 js.Name internalName = backend.namer.invocationName(selector); 4533 js.Name internalName = backend.namer.invocationName(selector);
4511 4534
4512 Element createInvocationMirror = helpers.createInvocationMirror; 4535 Element createInvocationMirror = helpers.createInvocationMirror;
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
4871 sourceInformation: sourceInformation); 4894 sourceInformation: sourceInformation);
4872 } else { 4895 } else {
4873 assert(member.isField); 4896 assert(member.isField);
4874 // The type variable is stored in a parameter of the method. 4897 // The type variable is stored in a parameter of the method.
4875 return localsHandler.readLocal(typeVariableLocal); 4898 return localsHandler.readLocal(typeVariableLocal);
4876 } 4899 }
4877 } else if (isInConstructorContext || 4900 } else if (isInConstructorContext ||
4878 // When [member] is a field, we can be either 4901 // When [member] is a field, we can be either
4879 // generating a checked setter or inlining its 4902 // generating a checked setter or inlining its
4880 // initializer in a constructor. An initializer is 4903 // initializer in a constructor. An initializer is
4881 // never built standalone, so [isBuildingFor] will 4904 // never built standalone, so in that case [target] is not
4882 // always return true when seeing one. 4905 // the [member] itself.
4883 (member.isField && !isBuildingFor(member))) { 4906 (member.isField && member != target)) {
4884 // The type variable is stored in a parameter of the method. 4907 // The type variable is stored in a parameter of the method.
4885 return localsHandler.readLocal( 4908 return localsHandler.readLocal(
4886 typeVariableLocal, sourceInformation: sourceInformation); 4909 typeVariableLocal, sourceInformation: sourceInformation);
4887 } else if (member.isInstanceMember) { 4910 } else if (member.isInstanceMember) {
4888 // The type variable is stored on the object. 4911 // The type variable is stored on the object.
4889 return readTypeVariable( 4912 return readTypeVariable(
4890 member.enclosingClass, 4913 member.enclosingClass,
4891 type.element, 4914 type.element,
4892 sourceInformation: sourceInformation); 4915 sourceInformation: sourceInformation);
4893 } else { 4916 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4931 HInstruction newObject) { 4954 HInstruction newObject) {
4932 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 4955 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
4933 return newObject; 4956 return newObject;
4934 } 4957 }
4935 List<HInstruction> inputs = <HInstruction>[]; 4958 List<HInstruction> inputs = <HInstruction>[];
4936 type = localsHandler.substInContext(type); 4959 type = localsHandler.substInContext(type);
4937 type.typeArguments.forEach((DartType argument) { 4960 type.typeArguments.forEach((DartType argument) {
4938 inputs.add(analyzeTypeArgument(argument)); 4961 inputs.add(analyzeTypeArgument(argument));
4939 }); 4962 });
4940 // TODO(15489): Register at codegen. 4963 // TODO(15489): Register at codegen.
4941 registry.registerInstantiatedType(type); 4964 registry?.registerInstantiatedType(type);
4942 return callSetRuntimeTypeInfo(type.element, inputs, newObject); 4965 return callSetRuntimeTypeInfo(type.element, inputs, newObject);
4943 } 4966 }
4944 4967
4945 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { 4968 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) {
4946 Element copyHelper = helpers.copyTypeArguments; 4969 Element copyHelper = helpers.copyTypeArguments;
4947 pushInvokeStatic(null, copyHelper, [source, target], 4970 pushInvokeStatic(null, copyHelper, [source, target],
4948 sourceInformation: target.sourceInformation); 4971 sourceInformation: target.sourceInformation);
4949 pop(); 4972 pop();
4950 } 4973 }
4951 4974
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
5144 typeMask: elementType, 5167 typeMask: elementType,
5145 instanceType: expectedType, 5168 instanceType: expectedType,
5146 sourceInformation: sourceInformation); 5169 sourceInformation: sourceInformation);
5147 removeInlinedInstantiation(expectedType); 5170 removeInlinedInstantiation(expectedType);
5148 } 5171 }
5149 HInstruction newInstance = stack.last; 5172 HInstruction newInstance = stack.last;
5150 if (isFixedList) { 5173 if (isFixedList) {
5151 // Overwrite the element type, in case the allocation site has 5174 // Overwrite the element type, in case the allocation site has
5152 // been inlined. 5175 // been inlined.
5153 newInstance.instructionType = elementType; 5176 newInstance.instructionType = elementType;
5154 JavaScriptItemCompilationContext context = work.compilationContext; 5177 if (context != null) {
5155 context.allocatedFixedLists.add(newInstance); 5178 context.allocatedFixedLists.add(newInstance);
5179 }
5156 } 5180 }
5157 5181
5158 // The List constructor forwards to a Dart static method that does 5182 // The List constructor forwards to a Dart static method that does
5159 // not know about the type argument. Therefore we special case 5183 // not know about the type argument. Therefore we special case
5160 // this constructor to have the setRuntimeTypeInfo called where 5184 // this constructor to have the setRuntimeTypeInfo called where
5161 // the 'new' is done. 5185 // the 'new' is done.
5162 if (backend.classNeedsRti(compiler.listClass) && 5186 if (backend.classNeedsRti(compiler.listClass) &&
5163 (isFixedListConstructorCall || isGrowableListConstructorCall || 5187 (isFixedListConstructorCall || isGrowableListConstructorCall ||
5164 isJSArrayTypedConstructor)) { 5188 isJSArrayTypedConstructor)) {
5165 newInstance = handleListConstructor(type, send, pop()); 5189 newInstance = handleListConstructor(type, send, pop());
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
5690 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind]; 5714 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind];
5691 Message message = template.message(error.messageArguments); 5715 Message message = template.message(error.messageArguments);
5692 generateRuntimeError(node.send, message.toString()); 5716 generateRuntimeError(node.send, message.toString());
5693 } 5717 }
5694 } else if (node.isConst) { 5718 } else if (node.isConst) {
5695 stack.add(addConstant(node)); 5719 stack.add(addConstant(node));
5696 if (isSymbolConstructor) { 5720 if (isSymbolConstructor) {
5697 ConstructedConstantValue symbol = getConstantForNode(node); 5721 ConstructedConstantValue symbol = getConstantForNode(node);
5698 StringConstantValue stringConstant = symbol.fields.values.single; 5722 StringConstantValue stringConstant = symbol.fields.values.single;
5699 String nameString = stringConstant.toDartString().slowToString(); 5723 String nameString = stringConstant.toDartString().slowToString();
5700 registry.registerConstSymbol(nameString); 5724 registry?.registerConstSymbol(nameString);
5701 } 5725 }
5702 } else { 5726 } else {
5703 handleNewSend(node); 5727 handleNewSend(node);
5704 } 5728 }
5705 } 5729 }
5706 5730
5707 @override 5731 @override
5708 void errorNonConstantConstructorInvoke( 5732 void errorNonConstantConstructorInvoke(
5709 ast.NewExpression node, 5733 ast.NewExpression node,
5710 Element element, 5734 Element element,
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 void visitLiteralBool(ast.LiteralBool node) { 6894 void visitLiteralBool(ast.LiteralBool node) {
6871 stack.add(graph.addConstantBool(node.value, compiler)); 6895 stack.add(graph.addConstantBool(node.value, compiler));
6872 } 6896 }
6873 6897
6874 void visitLiteralString(ast.LiteralString node) { 6898 void visitLiteralString(ast.LiteralString node) {
6875 stack.add(graph.addConstantString(node.dartString, compiler)); 6899 stack.add(graph.addConstantString(node.dartString, compiler));
6876 } 6900 }
6877 6901
6878 void visitLiteralSymbol(ast.LiteralSymbol node) { 6902 void visitLiteralSymbol(ast.LiteralSymbol node) {
6879 stack.add(addConstant(node)); 6903 stack.add(addConstant(node));
6880 registry.registerConstSymbol(node.slowNameString); 6904 registry?.registerConstSymbol(node.slowNameString);
6881 } 6905 }
6882 6906
6883 void visitStringJuxtaposition(ast.StringJuxtaposition node) { 6907 void visitStringJuxtaposition(ast.StringJuxtaposition node) {
6884 if (!node.isInterpolation) { 6908 if (!node.isInterpolation) {
6885 // This is a simple string with no interpolations. 6909 // This is a simple string with no interpolations.
6886 stack.add(graph.addConstantString(node.dartString, compiler)); 6910 stack.add(graph.addConstantString(node.dartString, compiler));
6887 return; 6911 return;
6888 } 6912 }
6889 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); 6913 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
6890 stringBuilder.visit(node); 6914 stringBuilder.visit(node);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
7092 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { 7116 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) {
7093 InterfaceType type = localsHandler.substInContext(elements.getType(node)); 7117 InterfaceType type = localsHandler.substInContext(elements.getType(node));
7094 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 7118 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
7095 return object; 7119 return object;
7096 } 7120 }
7097 List<HInstruction> arguments = <HInstruction>[]; 7121 List<HInstruction> arguments = <HInstruction>[];
7098 for (DartType argument in type.typeArguments) { 7122 for (DartType argument in type.typeArguments) {
7099 arguments.add(analyzeTypeArgument(argument)); 7123 arguments.add(analyzeTypeArgument(argument));
7100 } 7124 }
7101 // TODO(15489): Register at codegen. 7125 // TODO(15489): Register at codegen.
7102 registry.registerInstantiatedType(type); 7126 registry?.registerInstantiatedType(type);
7103 return callSetRuntimeTypeInfo(type.element, arguments, object); 7127 return callSetRuntimeTypeInfo(type.element, arguments, object);
7104 } 7128 }
7105 7129
7106 visitLiteralList(ast.LiteralList node) { 7130 visitLiteralList(ast.LiteralList node) {
7107 HInstruction instruction; 7131 HInstruction instruction;
7108 7132
7109 if (node.isConst) { 7133 if (node.isConst) {
7110 instruction = addConstant(node); 7134 instruction = addConstant(node);
7111 } else { 7135 } else {
7112 List<HInstruction> inputs = <HInstruction>[]; 7136 List<HInstruction> inputs = <HInstruction>[];
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after
8995 if (unaliased is TypedefType) throw 'unable to unalias $type'; 9019 if (unaliased is TypedefType) throw 'unable to unalias $type';
8996 unaliased.accept(this, builder); 9020 unaliased.accept(this, builder);
8997 } 9021 }
8998 9022
8999 void visitDynamicType(DynamicType type, SsaBuilder builder) { 9023 void visitDynamicType(DynamicType type, SsaBuilder builder) {
9000 JavaScriptBackend backend = builder.compiler.backend; 9024 JavaScriptBackend backend = builder.compiler.backend;
9001 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 9025 ClassElement cls = backend.findHelper('DynamicRuntimeType');
9002 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 9026 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
9003 } 9027 }
9004 } 9028 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698