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

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

Powered by Google App Engine
This is Rietveld 408576698