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

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

Issue 1892093003: Support deserialized compilation of the empty program. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments Created 4 years, 8 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 330 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
331 .computeClosureToClassMapping(element.resolvedAst); 331 compiler.backend.frontend.getResolvedAst(element.declaration));
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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 * boxed or stored in a closure then the method generates code to retrieve 450 * boxed or stored in a closure then the method generates code to retrieve
451 * the value. 451 * the value.
452 */ 452 */
453 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) { 453 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) {
454 if (isAccessedDirectly(local)) { 454 if (isAccessedDirectly(local)) {
455 if (directLocals[local] == null) { 455 if (directLocals[local] == null) {
456 if (local is TypeVariableElement) { 456 if (local is TypeVariableElement) {
457 builder.reporter.internalError(builder.compiler.currentElement, 457 builder.reporter.internalError(builder.compiler.currentElement,
458 "Runtime type information not available for $local."); 458 "Runtime type information not available for $local.");
459 } else { 459 } else {
460 builder.reporter.internalError(local, "Cannot find value $local."); 460 builder.reporter.internalError(
461 local, "Cannot find value $local in ${directLocals.keys}.");
461 } 462 }
462 } 463 }
463 HInstruction value = directLocals[local]; 464 HInstruction value = directLocals[local];
464 if (sourceInformation != null) { 465 if (sourceInformation != null) {
465 value = new HRef(value, sourceInformation); 466 value = new HRef(value, sourceInformation);
466 builder.add(value); 467 builder.add(value);
467 } 468 }
468 return value; 469 return value;
469 } else if (isStoredInClosureField(local)) { 470 } else if (isStoredInClosureField(local)) {
470 ClosureFieldElement redirect = redirectionMapping[local]; 471 ClosureFieldElement redirect = redirectionMapping[local];
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 // We only inline factory JavaScript interop constructors. 1371 // We only inline factory JavaScript interop constructors.
1371 return false; 1372 return false;
1372 } 1373 }
1373 1374
1374 // Ensure that [element] is an implementation element. 1375 // Ensure that [element] is an implementation element.
1375 element = element.implementation; 1376 element = element.implementation;
1376 1377
1377 if (compiler.elementHasCompileTimeError(element)) return false; 1378 if (compiler.elementHasCompileTimeError(element)) return false;
1378 1379
1379 FunctionElement function = element; 1380 FunctionElement function = element;
1381 ResolvedAst functionResolvedAst = backend.frontend.getResolvedAst(function);
1380 bool insideLoop = loopNesting > 0 || graph.calledInLoop; 1382 bool insideLoop = loopNesting > 0 || graph.calledInLoop;
1381 1383
1382 // Bail out early if the inlining decision is in the cache and we can't 1384 // Bail out early if the inlining decision is in the cache and we can't
1383 // inline (no need to check the hard constraints). 1385 // inline (no need to check the hard constraints).
1384 bool cachedCanBeInlined = 1386 bool cachedCanBeInlined =
1385 backend.inlineCache.canInline(function, insideLoop: insideLoop); 1387 backend.inlineCache.canInline(function, insideLoop: insideLoop);
1386 if (cachedCanBeInlined == false) return false; 1388 if (cachedCanBeInlined == false) return false;
1387 1389
1388 bool meetsHardConstraints() { 1390 bool meetsHardConstraints() {
1389 if (compiler.options.disableInlining) return false; 1391 if (compiler.options.disableInlining) return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 isReachable = false; 1431 isReachable = false;
1430 return false; 1432 return false;
1431 } 1433 }
1432 } 1434 }
1433 1435
1434 return true; 1436 return true;
1435 } 1437 }
1436 1438
1437 bool doesNotContainCode() { 1439 bool doesNotContainCode() {
1438 // A function with size 1 does not contain any code. 1440 // A function with size 1 does not contain any code.
1439 return InlineWeeder.canBeInlined(function, 1, true, 1441 return InlineWeeder.canBeInlined(functionResolvedAst, 1, true,
1440 enableUserAssertions: compiler.options.enableUserAssertions); 1442 enableUserAssertions: compiler.options.enableUserAssertions);
1441 } 1443 }
1442 1444
1443 bool reductiveHeuristic() { 1445 bool reductiveHeuristic() {
1444 // The call is on a path which is executed rarely, so inline only if it 1446 // The call is on a path which is executed rarely, so inline only if it
1445 // does not make the program larger. 1447 // does not make the program larger.
1446 if (isCalledOnce(element)) { 1448 if (isCalledOnce(element)) {
1447 return InlineWeeder.canBeInlined(function, -1, false, 1449 return InlineWeeder.canBeInlined(functionResolvedAst, -1, false,
1448 enableUserAssertions: compiler.options.enableUserAssertions); 1450 enableUserAssertions: compiler.options.enableUserAssertions);
1449 } 1451 }
1450 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable 1452 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable
1451 // case we miss by doing nothing is inlining very simple constructors 1453 // case we miss by doing nothing is inlining very simple constructors
1452 // where all fields are initialized with values from the arguments at this 1454 // where all fields are initialized with values from the arguments at this
1453 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but 1455 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
1454 // that usually means the factory constructor is left unused and not 1456 // that usually means the factory constructor is left unused and not
1455 // emitted. 1457 // emitted.
1456 // We at least inline bodies that are empty (and thus have a size of 1). 1458 // We at least inline bodies that are empty (and thus have a size of 1).
1457 return doesNotContainCode(); 1459 return doesNotContainCode();
(...skipping 17 matching lines...) Expand all
1475 } 1477 }
1476 1478
1477 // Do not inline code that is rarely executed unless it reduces size. 1479 // Do not inline code that is rarely executed unless it reduces size.
1478 if (inExpressionOfThrow || inLazyInitializerExpression) { 1480 if (inExpressionOfThrow || inLazyInitializerExpression) {
1479 return reductiveHeuristic(); 1481 return reductiveHeuristic();
1480 } 1482 }
1481 1483
1482 if (cachedCanBeInlined == true) { 1484 if (cachedCanBeInlined == true) {
1483 // We may have forced the inlining of some methods. Therefore check 1485 // We may have forced the inlining of some methods. Therefore check
1484 // if we can inline this method regardless of size. 1486 // if we can inline this method regardless of size.
1485 assert(InlineWeeder.canBeInlined(function, -1, false, 1487 assert(InlineWeeder.canBeInlined(functionResolvedAst, -1, false,
1486 allowLoops: true, 1488 allowLoops: true,
1487 enableUserAssertions: compiler.options.enableUserAssertions)); 1489 enableUserAssertions: compiler.options.enableUserAssertions));
1488 return true; 1490 return true;
1489 } 1491 }
1490 1492
1491 int numParameters = function.functionSignature.parameterCount; 1493 int numParameters = function.functionSignature.parameterCount;
1492 int maxInliningNodes; 1494 int maxInliningNodes;
1493 bool useMaxInliningNodes = true; 1495 bool useMaxInliningNodes = true;
1494 if (insideLoop) { 1496 if (insideLoop) {
1495 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 1497 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
1496 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 1498 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
1497 } else { 1499 } else {
1498 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 1500 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
1499 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 1501 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
1500 } 1502 }
1501 1503
1502 // If a method is called only once, and all the methods in the 1504 // If a method is called only once, and all the methods in the
1503 // inlining stack are called only once as well, we know we will 1505 // inlining stack are called only once as well, we know we will
1504 // save on output size by inlining this method. 1506 // save on output size by inlining this method.
1505 if (isCalledOnce(element)) { 1507 if (isCalledOnce(element)) {
1506 useMaxInliningNodes = false; 1508 useMaxInliningNodes = false;
1507 } 1509 }
1508 bool canInline; 1510 bool canInline;
1509 canInline = InlineWeeder.canBeInlined( 1511 canInline = InlineWeeder.canBeInlined(
1510 function, maxInliningNodes, useMaxInliningNodes, 1512 functionResolvedAst, maxInliningNodes, useMaxInliningNodes,
1511 enableUserAssertions: compiler.options.enableUserAssertions); 1513 enableUserAssertions: compiler.options.enableUserAssertions);
1512 if (canInline) { 1514 if (canInline) {
1513 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); 1515 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
1514 } else { 1516 } else {
1515 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 1517 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
1516 } 1518 }
1517 return canInline; 1519 return canInline;
1518 } 1520 }
1519 1521
1520 void doInlining() { 1522 void doInlining() {
1521 // Add an explicit null check on the receiver before doing the 1523 // Add an explicit null check on the receiver before doing the
1522 // inlining. We use [element] to get the same name in the 1524 // inlining. We use [element] to get the same name in the
1523 // NoSuchMethodError message as if we had called it. 1525 // NoSuchMethodError message as if we had called it.
1524 if (element.isInstanceMember && 1526 if (element.isInstanceMember &&
1525 !element.isGenerativeConstructorBody && 1527 !element.isGenerativeConstructorBody &&
1526 (mask == null || mask.isNullable)) { 1528 (mask == null || mask.isNullable)) {
1527 addWithPosition( 1529 addWithPosition(
1528 new HFieldGet(null, providedArguments[0], backend.dynamicType, 1530 new HFieldGet(null, providedArguments[0], backend.dynamicType,
1529 isAssignable: false), 1531 isAssignable: false),
1530 currentNode); 1532 currentNode);
1531 } 1533 }
1532 List<HInstruction> compiledArguments = completeSendArgumentsList( 1534 List<HInstruction> compiledArguments = completeSendArgumentsList(
1533 function, selector, providedArguments, currentNode); 1535 function, selector, providedArguments, currentNode);
1534 enterInlinedMethod(function, currentNode, compiledArguments, 1536 enterInlinedMethod(function, functionResolvedAst, compiledArguments,
1535 instanceType: instanceType); 1537 instanceType: instanceType);
1536 inlinedFrom(function, () { 1538 inlinedFrom(function, () {
1537 if (!isReachable) { 1539 if (!isReachable) {
1538 emitReturn(graph.addConstantNull(compiler), null); 1540 emitReturn(graph.addConstantNull(compiler), null);
1539 } else { 1541 } else {
1540 doInline(function); 1542 doInline(function);
1541 } 1543 }
1542 }); 1544 });
1543 leaveInlinedMethod(); 1545 leaveInlinedMethod();
1544 } 1546 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 } 1673 }
1672 1674
1673 /** 1675 /**
1674 * Documentation wanted -- johnniwinther 1676 * Documentation wanted -- johnniwinther
1675 * 1677 *
1676 * Invariant: [functionElement] must be an implementation element. 1678 * Invariant: [functionElement] must be an implementation element.
1677 */ 1679 */
1678 HGraph buildMethod(FunctionElement functionElement) { 1680 HGraph buildMethod(FunctionElement functionElement) {
1679 assert(invariant(functionElement, functionElement.isImplementation)); 1681 assert(invariant(functionElement, functionElement.isImplementation));
1680 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); 1682 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
1681 ast.FunctionExpression function = functionElement.node; 1683 ast.FunctionExpression function = resolvedAst.node;
1682 assert(function != null); 1684 assert(function != null);
1683 assert(elements.getFunctionDefinition(function) != null); 1685 assert(elements.getFunctionDefinition(function) != null);
1684 openFunction(functionElement, function); 1686 openFunction(functionElement, function);
1685 String name = functionElement.name; 1687 String name = functionElement.name;
1686 if (backend.isJsInterop(functionElement)) { 1688 if (backend.isJsInterop(functionElement)) {
1687 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 1689 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
1688 sourceInformationBuilder.buildGeneric(function))); 1690 sourceInformationBuilder.buildGeneric(function)));
1689 var value = pop(); 1691 var value = pop();
1690 closeAndGotoExit(new HReturn( 1692 closeAndGotoExit(new HReturn(
1691 value, sourceInformationBuilder.buildReturn(functionElement.node))); 1693 value, sourceInformationBuilder.buildReturn(functionElement.node)));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 * The arguments of the function are inserted into the [localsHandler]. 1827 * The arguments of the function are inserted into the [localsHandler].
1826 * 1828 *
1827 * When inlining a function, [:return:] statements are not emitted as 1829 * When inlining a function, [:return:] statements are not emitted as
1828 * [HReturn] instructions. Instead, the value of a synthetic element is 1830 * [HReturn] instructions. Instead, the value of a synthetic element is
1829 * updated in the [localsHandler]. This function creates such an element and 1831 * updated in the [localsHandler]. This function creates such an element and
1830 * stores it in the [returnLocal] field. 1832 * stores it in the [returnLocal] field.
1831 */ 1833 */
1832 void setupStateForInlining( 1834 void setupStateForInlining(
1833 FunctionElement function, List<HInstruction> compiledArguments, 1835 FunctionElement function, List<HInstruction> compiledArguments,
1834 {InterfaceType instanceType}) { 1836 {InterfaceType instanceType}) {
1837 ResolvedAst resolvedAst =
1838 compiler.backend.frontend.getResolvedAst(function.declaration);
1839 assert(resolvedAst != null);
1835 localsHandler = new LocalsHandler(this, function, instanceType); 1840 localsHandler = new LocalsHandler(this, function, instanceType);
1836 localsHandler.closureData = compiler.closureToClassMapper 1841 localsHandler.closureData =
1837 .computeClosureToClassMapping(function.resolvedAst); 1842 compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst);
1838 returnLocal = new SyntheticLocal("result", function); 1843 returnLocal = new SyntheticLocal("result", function);
1839 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler)); 1844 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler));
1840 1845
1841 inTryStatement = false; // TODO(lry): why? Document. 1846 inTryStatement = false; // TODO(lry): why? Document.
1842 1847
1843 int argumentIndex = 0; 1848 int argumentIndex = 0;
1844 if (function.isInstanceMember) { 1849 if (function.isInstanceMember) {
1845 localsHandler.updateLocal(localsHandler.closureData.thisLocal, 1850 localsHandler.updateLocal(localsHandler.closureData.thisLocal,
1846 compiledArguments[argumentIndex++]); 1851 compiledArguments[argumentIndex++]);
1847 } 1852 }
1848 1853
1849 FunctionSignature signature = function.functionSignature; 1854 FunctionSignature signature = function.functionSignature;
1850 signature.orderedForEachParameter((ParameterElement parameter) { 1855 signature.orderedForEachParameter((ParameterElement parameter) {
1851 HInstruction argument = compiledArguments[argumentIndex++]; 1856 HInstruction argument = compiledArguments[argumentIndex++];
1852 localsHandler.updateLocal(parameter, argument); 1857 localsHandler.updateLocal(parameter, argument);
1853 }); 1858 });
1854 1859
1855 ClassElement enclosing = function.enclosingClass; 1860 ClassElement enclosing = function.enclosingClass;
1856 if ((function.isConstructor || function.isGenerativeConstructorBody) && 1861 if ((function.isConstructor || function.isGenerativeConstructorBody) &&
1857 backend.classNeedsRti(enclosing)) { 1862 backend.classNeedsRti(enclosing)) {
1858 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1863 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1859 HInstruction argument = compiledArguments[argumentIndex++]; 1864 HInstruction argument = compiledArguments[argumentIndex++];
1860 localsHandler.updateLocal( 1865 localsHandler.updateLocal(
1861 localsHandler.getTypeVariableAsLocal(typeVariable), argument); 1866 localsHandler.getTypeVariableAsLocal(typeVariable), argument);
1862 }); 1867 });
1863 } 1868 }
1864 assert(argumentIndex == compiledArguments.length); 1869 assert(argumentIndex == compiledArguments.length);
1865 1870
1866 resolvedAst = function.resolvedAst;
1867 assert(resolvedAst != null);
1868 returnType = signature.type.returnType; 1871 returnType = signature.type.returnType;
1869 stack = <HInstruction>[]; 1872 stack = <HInstruction>[];
1870 1873
1871 insertTraceCall(function); 1874 insertTraceCall(function);
1872 insertCoverageCall(function); 1875 insertCoverageCall(function);
1873 } 1876 }
1874 1877
1875 void restoreState(AstInliningState state) { 1878 void restoreState(AstInliningState state) {
1876 localsHandler = state.oldLocalsHandler; 1879 localsHandler = state.oldLocalsHandler;
1877 returnLocal = state.oldReturnLocal; 1880 returnLocal = state.oldReturnLocal;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 // Don't forget to update the field, if the parameter is of the 2004 // Don't forget to update the field, if the parameter is of the
2002 // form [:this.x:]. 2005 // form [:this.x:].
2003 if (parameter.isInitializingFormal) { 2006 if (parameter.isInitializingFormal) {
2004 InitializingFormalElement fieldParameterElement = parameter; 2007 InitializingFormalElement fieldParameterElement = parameter;
2005 fieldValues[fieldParameterElement.fieldElement] = argument; 2008 fieldValues[fieldParameterElement.fieldElement] = argument;
2006 } 2009 }
2007 }); 2010 });
2008 2011
2009 // Build the initializers in the context of the new constructor. 2012 // Build the initializers in the context of the new constructor.
2010 ResolvedAst oldResolvedAst = resolvedAst; 2013 ResolvedAst oldResolvedAst = resolvedAst;
2011 resolvedAst = callee.resolvedAst; 2014 resolvedAst = backend.frontend.getResolvedAst(callee);
2012 ClosureClassMap oldClosureData = localsHandler.closureData; 2015 ClosureClassMap oldClosureData = localsHandler.closureData;
2013 ClosureClassMap newClosureData = compiler.closureToClassMapper 2016 ClosureClassMap newClosureData = compiler.closureToClassMapper
2014 .computeClosureToClassMapping(resolvedAst); 2017 .computeClosureToClassMapping(resolvedAst);
2015 localsHandler.closureData = newClosureData; 2018 localsHandler.closureData = newClosureData;
2016 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 2019 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
2017 localsHandler.enterScope(resolvedAst.node, callee); 2020 localsHandler.enterScope(resolvedAst.node, callee);
2018 } 2021 }
2019 buildInitializers(callee, constructors, fieldValues); 2022 buildInitializers(callee, constructors, fieldValues);
2020 localsHandler.closureData = oldClosureData; 2023 localsHandler.closureData = oldClosureData;
2021 resolvedAst = oldResolvedAst; 2024 resolvedAst = oldResolvedAst;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 ast.Expression initializer = member.initializer; 2171 ast.Expression initializer = member.initializer;
2169 if (initializer == null) { 2172 if (initializer == null) {
2170 // Unassigned fields of native classes are not initialized to 2173 // Unassigned fields of native classes are not initialized to
2171 // prevent overwriting pre-initialized native properties. 2174 // prevent overwriting pre-initialized native properties.
2172 if (!backend.isNativeOrExtendsNative(classElement)) { 2175 if (!backend.isNativeOrExtendsNative(classElement)) {
2173 fieldValues[member] = graph.addConstantNull(compiler); 2176 fieldValues[member] = graph.addConstantNull(compiler);
2174 } 2177 }
2175 } else { 2178 } else {
2176 ast.Node right = initializer; 2179 ast.Node right = initializer;
2177 ResolvedAst savedResolvedAst = resolvedAst; 2180 ResolvedAst savedResolvedAst = resolvedAst;
2178 resolvedAst = member.resolvedAst; 2181 resolvedAst = backend.frontend.getResolvedAst(member);
2179 // In case the field initializer uses closures, run the 2182 // In case the field initializer uses closures, run the
2180 // closure to class mapper. 2183 // closure to class mapper.
2181 compiler.closureToClassMapper 2184 compiler.closureToClassMapper
2182 .computeClosureToClassMapping(resolvedAst); 2185 .computeClosureToClassMapping(resolvedAst);
2183 inlinedFrom(member, () => right.accept(this)); 2186 inlinedFrom(member, () => right.accept(this));
2184 resolvedAst = savedResolvedAst; 2187 resolvedAst = savedResolvedAst;
2185 fieldValues[member] = pop(); 2188 fieldValues[member] = pop();
2186 } 2189 }
2187 }); 2190 });
2188 }); 2191 });
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 List bodyCallInputs = <HInstruction>[]; 2378 List bodyCallInputs = <HInstruction>[];
2376 if (isNativeUpgradeFactory) { 2379 if (isNativeUpgradeFactory) {
2377 if (interceptor == null) { 2380 if (interceptor == null) {
2378 ConstantValue constant = 2381 ConstantValue constant =
2379 new InterceptorConstantValue(classElement.thisType); 2382 new InterceptorConstantValue(classElement.thisType);
2380 interceptor = graph.addConstant(constant, compiler); 2383 interceptor = graph.addConstant(constant, compiler);
2381 } 2384 }
2382 bodyCallInputs.add(interceptor); 2385 bodyCallInputs.add(interceptor);
2383 } 2386 }
2384 bodyCallInputs.add(newObject); 2387 bodyCallInputs.add(newObject);
2385 ResolvedAst resolvedAst = constructor.resolvedAst; 2388 ResolvedAst resolvedAst = backend.frontend.getResolvedAst(constructor);
2386 ast.Node node = resolvedAst.node; 2389 ast.Node node = resolvedAst.node;
2387 ClosureClassMap parameterClosureData = 2390 ClosureClassMap parameterClosureData =
2388 compiler.closureToClassMapper.getMappingForNestedFunction(node); 2391 compiler.closureToClassMapper.getMappingForNestedFunction(node);
2389 2392
2390 FunctionSignature functionSignature = body.functionSignature; 2393 FunctionSignature functionSignature = body.functionSignature;
2391 // Provide the parameters to the generative constructor body. 2394 // Provide the parameters to the generative constructor body.
2392 functionSignature.orderedForEachParameter((ParameterElement parameter) { 2395 functionSignature.orderedForEachParameter((ParameterElement parameter) {
2393 // If [parameter] is boxed, it will be a field in the box passed as the 2396 // If [parameter] is boxed, it will be a field in the box passed as the
2394 // last parameter. So no need to directly pass it. 2397 // last parameter. So no need to directly pass it.
2395 if (!localsHandler.isBoxed(parameter)) { 2398 if (!localsHandler.isBoxed(parameter)) {
(...skipping 5476 matching lines...) Expand 10 before | Expand all | Expand 10 after
7872 } 7875 }
7873 7876
7874 visitTypeVariable(ast.TypeVariable node) { 7877 visitTypeVariable(ast.TypeVariable node) {
7875 reporter.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); 7878 reporter.internalError(node, 'SsaFromAstMixin.visitTypeVariable.');
7876 } 7879 }
7877 7880
7878 /** 7881 /**
7879 * This method is invoked before inlining the body of [function] into this 7882 * This method is invoked before inlining the body of [function] into this
7880 * [SsaBuilder]. 7883 * [SsaBuilder].
7881 */ 7884 */
7882 void enterInlinedMethod(FunctionElement function, ast.Node _, 7885 void enterInlinedMethod(FunctionElement function,
7883 List<HInstruction> compiledArguments, 7886 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments,
7884 {InterfaceType instanceType}) { 7887 {InterfaceType instanceType}) {
7885 AstInliningState state = new AstInliningState( 7888 AstInliningState state = new AstInliningState(
7886 function, 7889 function,
7887 returnLocal, 7890 returnLocal,
7888 returnType, 7891 returnType,
7889 resolvedAst, 7892 resolvedAst,
7890 stack, 7893 stack,
7891 localsHandler, 7894 localsHandler,
7892 inTryStatement, 7895 inTryStatement,
7893 allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function)); 7896 allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function));
7897 resolvedAst = functionResolvedAst;
7894 inliningStack.add(state); 7898 inliningStack.add(state);
7895 7899
7896 // Setting up the state of the (AST) builder is performed even when the 7900 // Setting up the state of the (AST) builder is performed even when the
7897 // inlined function is in IR, because the irInliner uses the [returnElement] 7901 // inlined function is in IR, because the irInliner uses the [returnElement]
7898 // of the AST builder. 7902 // of the AST builder.
7899 setupStateForInlining(function, compiledArguments, 7903 setupStateForInlining(function, compiledArguments,
7900 instanceType: instanceType); 7904 instanceType: instanceType);
7901 } 7905 }
7902 7906
7903 void leaveInlinedMethod() { 7907 void leaveInlinedMethod() {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
8080 int nodeCount = 0; 8084 int nodeCount = 0;
8081 final int maxInliningNodes; 8085 final int maxInliningNodes;
8082 final bool useMaxInliningNodes; 8086 final bool useMaxInliningNodes;
8083 final bool allowLoops; 8087 final bool allowLoops;
8084 final bool enableUserAssertions; 8088 final bool enableUserAssertions;
8085 8089
8086 InlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes, this.allowLoops, 8090 InlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes, this.allowLoops,
8087 this.enableUserAssertions); 8091 this.enableUserAssertions);
8088 8092
8089 static bool canBeInlined( 8093 static bool canBeInlined(
8090 FunctionElement function, int maxInliningNodes, bool useMaxInliningNodes, 8094 ResolvedAst resolvedAst, int maxInliningNodes, bool useMaxInliningNodes,
8091 {bool allowLoops: false, bool enableUserAssertions: null}) { 8095 {bool allowLoops: false, bool enableUserAssertions: null}) {
8092 assert(enableUserAssertions is bool); // Ensure we passed it. 8096 assert(enableUserAssertions is bool); // Ensure we passed it.
8093 if (function.resolvedAst.elements.containsTryStatement) return false; 8097 if (resolvedAst.elements.containsTryStatement) return false;
8094 8098
8095 InlineWeeder weeder = new InlineWeeder(maxInliningNodes, 8099 InlineWeeder weeder = new InlineWeeder(maxInliningNodes,
8096 useMaxInliningNodes, allowLoops, enableUserAssertions); 8100 useMaxInliningNodes, allowLoops, enableUserAssertions);
8097 ast.FunctionExpression functionExpression = function.node; 8101 ast.FunctionExpression functionExpression = resolvedAst.node;
8098 weeder.visit(functionExpression.initializers); 8102 weeder.visit(functionExpression.initializers);
8099 weeder.visit(functionExpression.body); 8103 weeder.visit(functionExpression.body);
8100 weeder.visit(functionExpression.asyncModifier); 8104 weeder.visit(functionExpression.asyncModifier);
8101 return !weeder.tooDifficult; 8105 return !weeder.tooDifficult;
8102 } 8106 }
8103 8107
8104 bool registerNode() { 8108 bool registerNode() {
8105 if (!useMaxInliningNodes) return true; 8109 if (!useMaxInliningNodes) return true;
8106 if (nodeCount++ > maxInliningNodes) { 8110 if (nodeCount++ > maxInliningNodes) {
8107 tooDifficult = true; 8111 tooDifficult = true;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
8569 const _LoopTypeVisitor(); 8573 const _LoopTypeVisitor();
8570 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; 8574 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
8571 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; 8575 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
8572 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 8576 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
8573 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 8577 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
8574 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8578 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8575 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8579 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8576 int visitSwitchStatement(ast.SwitchStatement node) => 8580 int visitSwitchStatement(ast.SwitchStatement node) =>
8577 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 8581 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
8578 } 8582 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698