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

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

Issue 1970703002: Store ResolvedAst on AstElement (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 4 years, 7 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 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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 320 }
321 321
322 /** 322 /**
323 * Documentation wanted -- johnniwinther 323 * Documentation wanted -- johnniwinther
324 * 324 *
325 * Invariant: [function] must be an implementation element. 325 * Invariant: [function] must be an implementation element.
326 */ 326 */
327 void startFunction(AstElement element, ast.Node node) { 327 void startFunction(AstElement element, ast.Node node) {
328 assert(invariant(element, element.isImplementation)); 328 assert(invariant(element, element.isImplementation));
329 Compiler compiler = builder.compiler; 329 Compiler compiler = builder.compiler;
330 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 330 closureData = compiler.closureToClassMapper
331 compiler.backend.frontend.getResolvedAst(element.declaration)); 331 .computeClosureToClassMapping(element.resolvedAst);
332 332
333 if (element is FunctionElement) { 333 if (element is FunctionElement) {
334 FunctionElement functionElement = element; 334 FunctionElement functionElement = element;
335 FunctionSignature params = functionElement.functionSignature; 335 FunctionSignature params = functionElement.functionSignature;
336 ClosureScope scopeData = closureData.capturingScopes[node]; 336 ClosureScope scopeData = closureData.capturingScopes[node];
337 params.orderedForEachParameter((ParameterElement parameterElement) { 337 params.orderedForEachParameter((ParameterElement parameterElement) {
338 if (element.isGenerativeConstructorBody) { 338 if (element.isGenerativeConstructorBody) {
339 if (scopeData != null && 339 if (scopeData != null &&
340 scopeData.isCapturedVariable(parameterElement)) { 340 scopeData.isCapturedVariable(parameterElement)) {
341 // The parameter will be a field in the box passed as the 341 // The parameter will be a field in the box passed as the
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 // We only inline factory JavaScript interop constructors. 1376 // We only inline factory JavaScript interop constructors.
1377 return false; 1377 return false;
1378 } 1378 }
1379 1379
1380 // Ensure that [element] is an implementation element. 1380 // Ensure that [element] is an implementation element.
1381 element = element.implementation; 1381 element = element.implementation;
1382 1382
1383 if (compiler.elementHasCompileTimeError(element)) return false; 1383 if (compiler.elementHasCompileTimeError(element)) return false;
1384 1384
1385 FunctionElement function = element; 1385 FunctionElement function = element;
1386 ResolvedAst functionResolvedAst = backend.frontend.getResolvedAst(function); 1386 ResolvedAst functionResolvedAst = function.resolvedAst;
1387 bool insideLoop = loopNesting > 0 || graph.calledInLoop; 1387 bool insideLoop = loopNesting > 0 || graph.calledInLoop;
1388 1388
1389 // Bail out early if the inlining decision is in the cache and we can't 1389 // Bail out early if the inlining decision is in the cache and we can't
1390 // inline (no need to check the hard constraints). 1390 // inline (no need to check the hard constraints).
1391 bool cachedCanBeInlined = 1391 bool cachedCanBeInlined =
1392 backend.inlineCache.canInline(function, insideLoop: insideLoop); 1392 backend.inlineCache.canInline(function, insideLoop: insideLoop);
1393 if (cachedCanBeInlined == false) return false; 1393 if (cachedCanBeInlined == false) return false;
1394 1394
1395 bool meetsHardConstraints() { 1395 bool meetsHardConstraints() {
1396 if (compiler.options.disableInlining) return false; 1396 if (compiler.options.disableInlining) return false;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 * The arguments of the function are inserted into the [localsHandler]. 1840 * The arguments of the function are inserted into the [localsHandler].
1841 * 1841 *
1842 * When inlining a function, [:return:] statements are not emitted as 1842 * When inlining a function, [:return:] statements are not emitted as
1843 * [HReturn] instructions. Instead, the value of a synthetic element is 1843 * [HReturn] instructions. Instead, the value of a synthetic element is
1844 * updated in the [localsHandler]. This function creates such an element and 1844 * updated in the [localsHandler]. This function creates such an element and
1845 * stores it in the [returnLocal] field. 1845 * stores it in the [returnLocal] field.
1846 */ 1846 */
1847 void setupStateForInlining( 1847 void setupStateForInlining(
1848 FunctionElement function, List<HInstruction> compiledArguments, 1848 FunctionElement function, List<HInstruction> compiledArguments,
1849 {InterfaceType instanceType}) { 1849 {InterfaceType instanceType}) {
1850 ResolvedAst resolvedAst = 1850 ResolvedAst resolvedAst = function.resolvedAst;
1851 compiler.backend.frontend.getResolvedAst(function.declaration);
1852 assert(resolvedAst != null); 1851 assert(resolvedAst != null);
1853 localsHandler = new LocalsHandler(this, function, instanceType); 1852 localsHandler = new LocalsHandler(this, function, instanceType);
1854 localsHandler.closureData = 1853 localsHandler.closureData =
1855 compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst); 1854 compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst);
1856 returnLocal = new SyntheticLocal("result", function); 1855 returnLocal = new SyntheticLocal("result", function);
1857 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler)); 1856 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler));
1858 1857
1859 inTryStatement = false; // TODO(lry): why? Document. 1858 inTryStatement = false; // TODO(lry): why? Document.
1860 1859
1861 int argumentIndex = 0; 1860 int argumentIndex = 0;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2017 // Don't forget to update the field, if the parameter is of the 2016 // Don't forget to update the field, if the parameter is of the
2018 // form [:this.x:]. 2017 // form [:this.x:].
2019 if (parameter.isInitializingFormal) { 2018 if (parameter.isInitializingFormal) {
2020 InitializingFormalElement fieldParameterElement = parameter; 2019 InitializingFormalElement fieldParameterElement = parameter;
2021 fieldValues[fieldParameterElement.fieldElement] = argument; 2020 fieldValues[fieldParameterElement.fieldElement] = argument;
2022 } 2021 }
2023 }); 2022 });
2024 2023
2025 // Build the initializers in the context of the new constructor. 2024 // Build the initializers in the context of the new constructor.
2026 ResolvedAst oldResolvedAst = resolvedAst; 2025 ResolvedAst oldResolvedAst = resolvedAst;
2027 resolvedAst = backend.frontend.getResolvedAst(callee); 2026 resolvedAst = callee.resolvedAst;
2028 ClosureClassMap oldClosureData = localsHandler.closureData; 2027 ClosureClassMap oldClosureData = localsHandler.closureData;
2029 ClosureClassMap newClosureData = compiler.closureToClassMapper 2028 ClosureClassMap newClosureData = compiler.closureToClassMapper
2030 .computeClosureToClassMapping(resolvedAst); 2029 .computeClosureToClassMapping(resolvedAst);
2031 localsHandler.closureData = newClosureData; 2030 localsHandler.closureData = newClosureData;
2032 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 2031 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
2033 localsHandler.enterScope(resolvedAst.node, callee); 2032 localsHandler.enterScope(resolvedAst.node, callee);
2034 } 2033 }
2035 buildInitializers(callee, constructorResolvedAsts, fieldValues); 2034 buildInitializers(callee, constructorResolvedAsts, fieldValues);
2036 localsHandler.closureData = oldClosureData; 2035 localsHandler.closureData = oldClosureData;
2037 resolvedAst = oldResolvedAst; 2036 resolvedAst = oldResolvedAst;
(...skipping 20 matching lines...) Expand all
2058 ConstructorElement constructor, 2057 ConstructorElement constructor,
2059 List<ResolvedAst> constructorResolvedAsts, 2058 List<ResolvedAst> constructorResolvedAsts,
2060 Map<Element, HInstruction> fieldValues) { 2059 Map<Element, HInstruction> fieldValues) {
2061 assert(invariant(constructor, constructor.isSynthesized, 2060 assert(invariant(constructor, constructor.isSynthesized,
2062 message: "Unexpected unsynthesized constructor: $constructor")); 2061 message: "Unexpected unsynthesized constructor: $constructor"));
2063 List<HInstruction> arguments = <HInstruction>[]; 2062 List<HInstruction> arguments = <HInstruction>[];
2064 HInstruction compileArgument(ParameterElement parameter) { 2063 HInstruction compileArgument(ParameterElement parameter) {
2065 return localsHandler.readLocal(parameter); 2064 return localsHandler.readLocal(parameter);
2066 } 2065 }
2067 2066
2068 Element target = constructor.definingConstructor.implementation; 2067 ConstructorElement target = constructor.definingConstructor.implementation;
2069 bool match = !target.isMalformed && 2068 bool match = !target.isMalformed &&
2070 CallStructure.addForwardingElementArgumentsToList( 2069 CallStructure.addForwardingElementArgumentsToList(
2071 constructor, 2070 constructor,
2072 arguments, 2071 arguments,
2073 target, 2072 target,
2074 compileArgument, 2073 compileArgument,
2075 handleConstantForOptionalParameter); 2074 handleConstantForOptionalParameter);
2076 if (!match) { 2075 if (!match) {
2077 if (compiler.elementHasCompileTimeError(constructor)) { 2076 if (compiler.elementHasCompileTimeError(constructor)) {
2078 return; 2077 return;
2079 } 2078 }
2080 // If this fails, the selector we constructed for the call to a 2079 // If this fails, the selector we constructed for the call to a
2081 // forwarding constructor in a mixin application did not match the 2080 // forwarding constructor in a mixin application did not match the
2082 // constructor (which, for example, may happen when the libraries are 2081 // constructor (which, for example, may happen when the libraries are
2083 // not compatible for private names, see issue 20394). 2082 // not compatible for private names, see issue 20394).
2084 reporter.internalError( 2083 reporter.internalError(
2085 constructor, 'forwarding constructor call does not match'); 2084 constructor, 'forwarding constructor call does not match');
2086 } 2085 }
2087 inlineSuperOrRedirect(backend.frontend.getResolvedAst(target), arguments, 2086 inlineSuperOrRedirect(target.resolvedAst, arguments,
2088 constructorResolvedAsts, fieldValues, constructor); 2087 constructorResolvedAsts, fieldValues, constructor);
2089 } 2088 }
2090 2089
2091 /** 2090 /**
2092 * Run through the initializers and inline all field initializers. Recursively 2091 * Run through the initializers and inline all field initializers. Recursively
2093 * inlines super initializers. 2092 * inlines super initializers.
2094 * 2093 *
2095 * The constructors of the inlined initializers is added to [constructors] 2094 * The constructors of the inlined initializers is added to [constructors]
2096 * with sub constructors having a lower index than super constructors. 2095 * with sub constructors having a lower index than super constructors.
2097 * 2096 *
(...skipping 26 matching lines...) Expand all
2124 ast.Initializers.isConstructorRedirect(call)); 2123 ast.Initializers.isConstructorRedirect(call));
2125 FunctionElement target = elements[call].implementation; 2124 FunctionElement target = elements[call].implementation;
2126 CallStructure callStructure = 2125 CallStructure callStructure =
2127 elements.getSelector(call).callStructure; 2126 elements.getSelector(call).callStructure;
2128 Link<ast.Node> arguments = call.arguments; 2127 Link<ast.Node> arguments = call.arguments;
2129 List<HInstruction> compiledArguments; 2128 List<HInstruction> compiledArguments;
2130 inlinedFrom(resolvedAst, () { 2129 inlinedFrom(resolvedAst, () {
2131 compiledArguments = 2130 compiledArguments =
2132 makeStaticArgumentList(callStructure, arguments, target); 2131 makeStaticArgumentList(callStructure, arguments, target);
2133 }); 2132 });
2134 inlineSuperOrRedirect( 2133 inlineSuperOrRedirect(target.resolvedAst, compiledArguments,
2135 backend.frontend.getResolvedAst(target.declaration), 2134 constructorResolvedAsts, fieldValues, constructor);
2136 compiledArguments,
2137 constructorResolvedAsts,
2138 fieldValues,
2139 constructor);
2140 } else { 2135 } else {
2141 // A field initializer. 2136 // A field initializer.
2142 ast.SendSet init = link.head; 2137 ast.SendSet init = link.head;
2143 Link<ast.Node> arguments = init.arguments; 2138 Link<ast.Node> arguments = init.arguments;
2144 assert(!arguments.isEmpty && arguments.tail.isEmpty); 2139 assert(!arguments.isEmpty && arguments.tail.isEmpty);
2145 inlinedFrom(resolvedAst, () { 2140 inlinedFrom(resolvedAst, () {
2146 visit(arguments.head); 2141 visit(arguments.head);
2147 }); 2142 });
2148 fieldValues[elements[init]] = pop(); 2143 fieldValues[elements[init]] = pop();
2149 } 2144 }
(...skipping 12 matching lines...) Expand all
2162 FunctionElement target = superClass.lookupDefaultConstructor(); 2157 FunctionElement target = superClass.lookupDefaultConstructor();
2163 if (target == null) { 2158 if (target == null) {
2164 reporter.internalError( 2159 reporter.internalError(
2165 superClass, "No default constructor available."); 2160 superClass, "No default constructor available.");
2166 } 2161 }
2167 List<HInstruction> arguments = CallStructure.NO_ARGS.makeArgumentsList( 2162 List<HInstruction> arguments = CallStructure.NO_ARGS.makeArgumentsList(
2168 const Link<ast.Node>(), 2163 const Link<ast.Node>(),
2169 target.implementation, 2164 target.implementation,
2170 null, 2165 null,
2171 handleConstantForOptionalParameter); 2166 handleConstantForOptionalParameter);
2172 inlineSuperOrRedirect( 2167 inlineSuperOrRedirect(target.resolvedAst, arguments,
2173 backend.frontend.getResolvedAst(target.declaration), 2168 constructorResolvedAsts, fieldValues, constructor);
2174 arguments,
2175 constructorResolvedAsts,
2176 fieldValues,
2177 constructor);
2178 } 2169 }
2179 } 2170 }
2180 } 2171 }
2181 2172
2182 /** 2173 /**
2183 * Run through the fields of [cls] and add their potential 2174 * Run through the fields of [cls] and add their potential
2184 * initializers. 2175 * initializers.
2185 * 2176 *
2186 * Invariant: [classElement] must be an implementation element. 2177 * Invariant: [classElement] must be an implementation element.
2187 */ 2178 */
2188 void buildFieldInitializers( 2179 void buildFieldInitializers(
2189 ClassElement classElement, Map<Element, HInstruction> fieldValues) { 2180 ClassElement classElement, Map<Element, HInstruction> fieldValues) {
2190 assert(invariant(classElement, classElement.isImplementation)); 2181 assert(invariant(classElement, classElement.isImplementation));
2191 classElement.forEachInstanceField( 2182 classElement.forEachInstanceField(
2192 (ClassElement enclosingClass, FieldElement member) { 2183 (ClassElement enclosingClass, FieldElement member) {
2193 if (compiler.elementHasCompileTimeError(member)) return; 2184 if (compiler.elementHasCompileTimeError(member)) return;
2194 reporter.withCurrentElement(member, () { 2185 reporter.withCurrentElement(member, () {
2195 ResolvedAst fieldResolvedAst = backend.frontend.getResolvedAst(member); 2186 ResolvedAst fieldResolvedAst = member.resolvedAst;
2196 ast.Node node = fieldResolvedAst.node; 2187 ast.Node node = fieldResolvedAst.node;
2197 ast.Expression initializer = fieldResolvedAst.body; 2188 ast.Expression initializer = fieldResolvedAst.body;
2198 if (initializer == null) { 2189 if (initializer == null) {
2199 // Unassigned fields of native classes are not initialized to 2190 // Unassigned fields of native classes are not initialized to
2200 // prevent overwriting pre-initialized native properties. 2191 // prevent overwriting pre-initialized native properties.
2201 if (!backend.isNativeOrExtendsNative(classElement)) { 2192 if (!backend.isNativeOrExtendsNative(classElement)) {
2202 fieldValues[member] = graph.addConstantNull(compiler); 2193 fieldValues[member] = graph.addConstantNull(compiler);
2203 } 2194 }
2204 } else { 2195 } else {
2205 ast.Node right = initializer; 2196 ast.Node right = initializer;
(...skipping 6400 matching lines...) Expand 10 before | Expand all | Expand 10 after
8606 const _LoopTypeVisitor(); 8597 const _LoopTypeVisitor();
8607 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; 8598 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
8608 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; 8599 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
8609 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 8600 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
8610 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 8601 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
8611 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8602 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8612 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8603 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8613 int visitSwitchStatement(ast.SwitchStatement node) => 8604 int visitSwitchStatement(ast.SwitchStatement node) =>
8614 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 8605 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
8615 } 8606 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart ('k') | tests/compiler/dart2js/serialization/helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698