OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |