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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 | 878 |
879 void close() { | 879 void close() { |
880 // The mapping from TargetElement to JumpHandler is no longer needed. | 880 // The mapping from TargetElement to JumpHandler is no longer needed. |
881 for (TargetElement target in targetIndexMap.keys) { | 881 for (TargetElement target in targetIndexMap.keys) { |
882 builder.jumpTargets.remove(target); | 882 builder.jumpTargets.remove(target); |
883 } | 883 } |
884 super.close(); | 884 super.close(); |
885 } | 885 } |
886 } | 886 } |
887 | 887 |
888 class SsaBuilder extends ResolvedVisitor implements Visitor { | 888 /** |
889 final SsaBuilderTask builder; | 889 * This mixin implements functionality that is shared between the [SsaBuilder] |
890 final JavaScriptBackend backend; | 890 * and the [SsaFromIrBuilder] classes. |
891 final CodegenWorkItem work; | 891 */ |
892 final ConstantSystem constantSystem; | 892 class SsaGraphBuilderMixin { |
893 HGraph graph; | 893 final HGraph graph = new HGraph(); |
894 LocalsHandler localsHandler; | |
895 HInstruction rethrowableException; | |
896 Map<Element, HInstruction> parameters; | |
897 final RuntimeTypes rti; | |
898 HParameterValue lastAddedParameter; | |
899 | |
900 Map<TargetElement, JumpHandler> jumpTargets; | |
901 | |
902 /** | |
903 * Variables stored in the current activation. These variables are | |
904 * being updated in try/catch blocks, and should be | |
905 * accessed indirectly through [HLocalGet] and [HLocalSet]. | |
906 */ | |
907 Map<Element, HLocalValue> activationVariables; | |
908 | |
909 // We build the Ssa graph by simulating a stack machine. | |
910 List<HInstruction> stack; | |
911 | 894 |
912 /** | 895 /** |
913 * The current block to add instructions to. Might be null, if we are | 896 * The current block to add instructions to. Might be null, if we are |
914 * visiting dead code, but see [isReachable]. | 897 * visiting dead code, but see [isReachable]. |
915 */ | 898 */ |
916 HBasicBlock _current; | 899 HBasicBlock _current; |
917 | 900 |
918 /** | 901 /** |
919 * The most recently opened block. Has the same value as [_current] while | 902 * The most recently opened block. Has the same value as [_current] while |
920 * the block is open, but unlike [_current], it isn't cleared when the | 903 * the block is open, but unlike [_current], it isn't cleared when the |
921 * current block is closed. | 904 * current block is closed. |
922 */ | 905 */ |
923 HBasicBlock lastOpenedBlock; | 906 HBasicBlock lastOpenedBlock; |
924 | 907 |
925 /** | 908 /** |
926 * Indicates whether the current block is dead (because it has a throw or a | 909 * Indicates whether the current block is dead (because it has a throw or a |
927 * return further up). If this is false, then [_current] may be null. If the | 910 * return further up). If this is false, then [_current] may be null. If the |
928 * block is dead then it may also be aborted, but for simplicity we only | 911 * block is dead then it may also be aborted, but for simplicity we only |
929 * abort on statement boundaries, not in the middle of expressions. See | 912 * abort on statement boundaries, not in the middle of expressions. See |
930 * isAborted. | 913 * isAborted. |
931 */ | 914 */ |
932 bool isReachable = true; | 915 bool isReachable = true; |
933 | 916 |
| 917 HBasicBlock get current => _current; |
| 918 void set current(c) { |
| 919 isReachable = c != null; |
| 920 _current = c; |
| 921 } |
| 922 |
| 923 HBasicBlock addNewBlock() { |
| 924 HBasicBlock block = graph.addNewBlock(); |
| 925 // If adding a new block during building of an expression, it is due to |
| 926 // conditional expressions or short-circuit logical operators. |
| 927 return block; |
| 928 } |
| 929 |
| 930 void open(HBasicBlock block) { |
| 931 block.open(); |
| 932 current = block; |
| 933 lastOpenedBlock = block; |
| 934 } |
| 935 |
| 936 HBasicBlock close(HControlFlow end) { |
| 937 HBasicBlock result = current; |
| 938 current.close(end); |
| 939 current = null; |
| 940 return result; |
| 941 } |
| 942 |
| 943 HBasicBlock closeAndGotoExit(HControlFlow end) { |
| 944 HBasicBlock result = current; |
| 945 current.close(end); |
| 946 current = null; |
| 947 result.addSuccessor(graph.exit); |
| 948 return result; |
| 949 } |
| 950 |
| 951 void goto(HBasicBlock from, HBasicBlock to) { |
| 952 from.close(new HGoto()); |
| 953 from.addSuccessor(to); |
| 954 } |
| 955 |
| 956 bool isAborted() { |
| 957 return _current == null; |
| 958 } |
| 959 |
| 960 /** |
| 961 * Creates a new block, transitions to it from any current block, and |
| 962 * opens the new block. |
| 963 */ |
| 964 HBasicBlock openNewBlock() { |
| 965 HBasicBlock newBlock = addNewBlock(); |
| 966 if (!isAborted()) goto(current, newBlock); |
| 967 open(newBlock); |
| 968 return newBlock; |
| 969 } |
| 970 |
| 971 void add(HInstruction instruction) { |
| 972 current.add(instruction); |
| 973 } |
| 974 } |
| 975 |
| 976 class SsaBuilder extends ResolvedVisitor with SsaGraphBuilderMixin { |
| 977 final SsaBuilderTask builder; |
| 978 final JavaScriptBackend backend; |
| 979 final CodegenWorkItem work; |
| 980 final ConstantSystem constantSystem; |
| 981 LocalsHandler localsHandler; |
| 982 HInstruction rethrowableException; |
| 983 Map<Element, HInstruction> parameters; |
| 984 final RuntimeTypes rti; |
| 985 HParameterValue lastAddedParameter; |
| 986 |
| 987 Map<TargetElement, JumpHandler> jumpTargets; |
| 988 |
| 989 /** |
| 990 * Variables stored in the current activation. These variables are |
| 991 * being updated in try/catch blocks, and should be |
| 992 * accessed indirectly through [HLocalGet] and [HLocalSet]. |
| 993 */ |
| 994 Map<Element, HLocalValue> activationVariables; |
| 995 |
| 996 // We build the Ssa graph by simulating a stack machine. |
| 997 List<HInstruction> stack; |
| 998 |
934 /** | 999 /** |
935 * True if we are visiting the expression of a throw expression. | 1000 * True if we are visiting the expression of a throw expression. |
936 */ | 1001 */ |
937 bool inThrowExpression = false; | 1002 bool inThrowExpression = false; |
938 | 1003 |
939 final List<Element> sourceElementStack; | 1004 final List<Element> sourceElementStack; |
940 | 1005 |
941 Element get currentElement => sourceElementStack.last.declaration; | 1006 Element get currentElement => sourceElementStack.last.declaration; |
942 Element get currentNonClosureClass { | 1007 Element get currentNonClosureClass { |
943 ClassElement cls = currentElement.getEnclosingClass(); | 1008 ClassElement cls = currentElement.getEnclosingClass(); |
(...skipping 20 matching lines...) Expand all Loading... |
964 // types of the type variables in an environment (like the [LocalsHandler]). | 1029 // types of the type variables in an environment (like the [LocalsHandler]). |
965 final List<DartType> currentInlinedInstantiations = <DartType>[]; | 1030 final List<DartType> currentInlinedInstantiations = <DartType>[]; |
966 | 1031 |
967 Compiler get compiler => builder.compiler; | 1032 Compiler get compiler => builder.compiler; |
968 CodeEmitterTask get emitter => builder.emitter; | 1033 CodeEmitterTask get emitter => builder.emitter; |
969 | 1034 |
970 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work) | 1035 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work) |
971 : this.builder = builder, | 1036 : this.builder = builder, |
972 this.backend = builder.backend, | 1037 this.backend = builder.backend, |
973 this.work = work, | 1038 this.work = work, |
974 graph = new HGraph(), | |
975 stack = new List<HInstruction>(), | 1039 stack = new List<HInstruction>(), |
976 activationVariables = new Map<Element, HLocalValue>(), | 1040 activationVariables = new Map<Element, HLocalValue>(), |
977 jumpTargets = new Map<TargetElement, JumpHandler>(), | 1041 jumpTargets = new Map<TargetElement, JumpHandler>(), |
978 parameters = new Map<Element, HInstruction>(), | 1042 parameters = new Map<Element, HInstruction>(), |
979 sourceElementStack = <Element>[work.element], | 1043 sourceElementStack = <Element>[work.element], |
980 inliningStack = <InliningState>[], | 1044 inliningStack = <InliningState>[], |
981 rti = builder.backend.rti, | 1045 rti = builder.backend.rti, |
982 super(work.resolutionTree, builder.compiler) { | 1046 super(work.resolutionTree, builder.compiler) { |
983 localsHandler = new LocalsHandler(this); | 1047 localsHandler = new LocalsHandler(this); |
984 } | 1048 } |
985 | 1049 |
986 List<InliningState> inliningStack; | 1050 List<InliningState> inliningStack; |
987 | 1051 |
988 Element returnElement; | 1052 Element returnElement; |
989 DartType returnType; | 1053 DartType returnType; |
990 | 1054 |
991 bool inTryStatement = false; | 1055 bool inTryStatement = false; |
992 int loopNesting = 0; | 1056 int loopNesting = 0; |
993 | 1057 |
994 HBasicBlock get current => _current; | |
995 void set current(c) { | |
996 isReachable = c != null; | |
997 _current = c; | |
998 } | |
999 | |
1000 Constant getConstantForNode(Node node) { | 1058 Constant getConstantForNode(Node node) { |
1001 ConstantHandler handler = compiler.constantHandler; | 1059 ConstantHandler handler = compiler.constantHandler; |
1002 Constant constant = elements.getConstant(node); | 1060 Constant constant = elements.getConstant(node); |
1003 assert(invariant(node, constant != null, | 1061 assert(invariant(node, constant != null, |
1004 message: 'No constant computed for $node')); | 1062 message: 'No constant computed for $node')); |
1005 return constant; | 1063 return constant; |
1006 } | 1064 } |
1007 | 1065 |
1008 HInstruction addConstant(Node node) { | 1066 HInstruction addConstant(Node node) { |
1009 return graph.addConstant(getConstantForNode(node), compiler); | 1067 return graph.addConstant(getConstantForNode(node), compiler); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 assert(succeeded); | 1276 assert(succeeded); |
1219 } | 1277 } |
1220 | 1278 |
1221 // Create the inlining state after evaluating the arguments, that | 1279 // Create the inlining state after evaluating the arguments, that |
1222 // may have an impact on the state of the current method. | 1280 // may have an impact on the state of the current method. |
1223 InliningState state = new InliningState( | 1281 InliningState state = new InliningState( |
1224 function, returnElement, returnType, elements, stack, | 1282 function, returnElement, returnType, elements, stack, |
1225 localsHandler, inTryStatement); | 1283 localsHandler, inTryStatement); |
1226 inTryStatement = false; | 1284 inTryStatement = false; |
1227 LocalsHandler newLocalsHandler = new LocalsHandler(this); | 1285 LocalsHandler newLocalsHandler = new LocalsHandler(this); |
1228 newLocalsHandler.closureData = | 1286 if (compiler.irBuilder.hasIr(function)) { |
1229 compiler.closureToClassMapper.computeClosureToClassMapping( | 1287 // TODO(lry): handle ir functions with nested closure definitions. |
1230 function, function.parseNode(compiler), elements); | 1288 newLocalsHandler.closureData = |
| 1289 new ClosureClassMap(null, null, null, new ThisElement(function)); |
| 1290 } else { |
| 1291 newLocalsHandler.closureData = |
| 1292 compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1293 function, function.parseNode(compiler), elements); |
| 1294 } |
1231 int argumentIndex = 0; | 1295 int argumentIndex = 0; |
1232 if (isInstanceMember) { | 1296 if (isInstanceMember) { |
1233 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, | 1297 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, |
1234 compiledArguments[argumentIndex++]); | 1298 compiledArguments[argumentIndex++]); |
1235 } | 1299 } |
1236 | 1300 |
1237 FunctionSignature signature = function.computeSignature(compiler); | 1301 FunctionSignature signature = function.computeSignature(compiler); |
1238 signature.orderedForEachParameter((Element parameter) { | 1302 signature.orderedForEachParameter((Element parameter) { |
1239 HInstruction argument = compiledArguments[argumentIndex++]; | 1303 HInstruction argument = compiledArguments[argumentIndex++]; |
1240 newLocalsHandler.updateLocal(parameter, argument); | 1304 newLocalsHandler.updateLocal(parameter, argument); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 && returnType.isEmpty | 1407 && returnType.isEmpty |
1344 && !returnType.isNullable) { | 1408 && !returnType.isNullable) { |
1345 isReachable = false; | 1409 isReachable = false; |
1346 return false; | 1410 return false; |
1347 } | 1411 } |
1348 } | 1412 } |
1349 | 1413 |
1350 return true; | 1414 return true; |
1351 } | 1415 } |
1352 | 1416 |
1353 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { | 1417 bool heuristicSayGoodToGo(bool canBeInlined(int maxNodes, bool useMax)) { |
1354 // Don't inline recursivly | 1418 // Don't inline recursivly |
1355 if (inliningStack.any((entry) => entry.function == function)) { | 1419 if (inliningStack.any((entry) => entry.function == function)) { |
1356 return false; | 1420 return false; |
1357 } | 1421 } |
1358 | 1422 |
1359 if (element.isSynthesized) return true; | 1423 if (element.isSynthesized) return true; |
1360 | 1424 |
1361 if (cachedCanBeInlined == true) return cachedCanBeInlined; | 1425 if (cachedCanBeInlined == true) return cachedCanBeInlined; |
1362 | 1426 |
1363 if (inThrowExpression) return false; | 1427 if (inThrowExpression) return false; |
(...skipping 11 matching lines...) Expand all Loading... |
1375 | 1439 |
1376 // If a method is called only once, and all the methods in the | 1440 // If a method is called only once, and all the methods in the |
1377 // inlining stack are called only once as well, we know we will | 1441 // inlining stack are called only once as well, we know we will |
1378 // save on output size by inlining this method. | 1442 // save on output size by inlining this method. |
1379 TypesInferrer inferrer = compiler.typesTask.typesInferrer; | 1443 TypesInferrer inferrer = compiler.typesTask.typesInferrer; |
1380 if (inferrer.isCalledOnce(element) | 1444 if (inferrer.isCalledOnce(element) |
1381 && (inliningStack.every( | 1445 && (inliningStack.every( |
1382 (entry) => inferrer.isCalledOnce(entry.function)))) { | 1446 (entry) => inferrer.isCalledOnce(entry.function)))) { |
1383 useMaxInliningNodes = false; | 1447 useMaxInliningNodes = false; |
1384 } | 1448 } |
1385 bool canBeInlined = InlineWeeder.canBeInlined( | 1449 bool canInline = canBeInlined(maxInliningNodes, useMaxInliningNodes); |
1386 functionExpression, maxInliningNodes, useMaxInliningNodes); | 1450 if (canInline) { |
1387 if (canBeInlined) { | |
1388 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); | 1451 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); |
1389 } else { | 1452 } else { |
1390 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); | 1453 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); |
1391 } | 1454 } |
1392 return canBeInlined; | 1455 return canInline; |
1393 } | 1456 } |
1394 | 1457 |
1395 void doInlining(FunctionExpression functionExpression) { | 1458 void doInlining(void visitBody()) { |
1396 // Add an explicit null check on the receiver before doing the | 1459 // Add an explicit null check on the receiver before doing the |
1397 // inlining. We use [element] to get the same name in the | 1460 // inlining. We use [element] to get the same name in the |
1398 // NoSuchMethodError message as if we had called it. | 1461 // NoSuchMethodError message as if we had called it. |
1399 if (element.isInstanceMember() | 1462 if (element.isInstanceMember() |
1400 && !element.isGenerativeConstructorBody() | 1463 && !element.isGenerativeConstructorBody() |
1401 && (selector.mask == null || selector.mask.isNullable)) { | 1464 && (selector.mask == null || selector.mask.isNullable)) { |
1402 addWithPosition( | 1465 addWithPosition( |
1403 new HFieldGet(null, providedArguments[0], backend.dynamicType, | 1466 new HFieldGet(null, providedArguments[0], backend.dynamicType, |
1404 isAssignable: false), | 1467 isAssignable: false), |
1405 currentNode); | 1468 currentNode); |
1406 } | 1469 } |
1407 InliningState state = enterInlinedMethod( | 1470 InliningState state = enterInlinedMethod( |
1408 function, selector, providedArguments, currentNode); | 1471 function, selector, providedArguments, currentNode); |
1409 | 1472 |
1410 inlinedFrom(element, () { | 1473 inlinedFrom(element, () { |
1411 FunctionElement function = element; | 1474 FunctionElement function = element; |
1412 FunctionSignature signature = function.computeSignature(compiler); | 1475 FunctionSignature signature = function.computeSignature(compiler); |
1413 signature.orderedForEachParameter((Element parameter) { | 1476 signature.orderedForEachParameter((Element parameter) { |
1414 HInstruction argument = localsHandler.readLocal(parameter); | 1477 HInstruction argument = localsHandler.readLocal(parameter); |
1415 potentiallyCheckType(argument, parameter.computeType(compiler)); | 1478 potentiallyCheckType(argument, parameter.computeType(compiler)); |
1416 }); | 1479 }); |
1417 addInlinedInstantiation(instantiatedType); | 1480 addInlinedInstantiation(instantiatedType); |
1418 if (element.isGenerativeConstructor()) { | 1481 if (element.isGenerativeConstructor()) { |
1419 buildFactory(element); | 1482 buildFactory(element); |
1420 } else { | 1483 } else { |
1421 functionExpression.body.accept(this); | 1484 visitBody(); |
1422 } | 1485 } |
1423 removeInlinedInstantiation(instantiatedType); | 1486 removeInlinedInstantiation(instantiatedType); |
1424 }); | 1487 }); |
1425 leaveInlinedMethod(state); | 1488 leaveInlinedMethod(state); |
1426 } | 1489 } |
1427 | 1490 |
1428 if (meetsHardConstraints()) { | 1491 if (meetsHardConstraints()) { |
1429 FunctionExpression functionExpression = function.parseNode(compiler); | 1492 if (compiler.irBuilder.hasIr(function)) { |
1430 | 1493 IrFunction irFunction = compiler.irBuilder.getIr(function); |
1431 if (heuristicSayGoodToGo(functionExpression)) { | 1494 bool canInline(int n, bool b) { |
1432 doInlining(functionExpression); | 1495 return IrInlineWeeder.canBeInlined(irFunction, n, b); |
1433 return true; | 1496 } |
| 1497 if (heuristicSayGoodToGo(canInline)) { |
| 1498 SsaFromIrInliner irInliner = new SsaFromIrInliner(this); |
| 1499 doInlining(() => irInliner.visitAll(irFunction.statements)); |
| 1500 return true; |
| 1501 } |
| 1502 } else { |
| 1503 FunctionExpression functionNode = function.parseNode(compiler); |
| 1504 bool canInline(int n, bool b) { |
| 1505 return InlineWeeder.canBeInlined(functionNode, n, b); |
| 1506 } |
| 1507 if (heuristicSayGoodToGo(canInline)) { |
| 1508 doInlining(() => functionNode.body.accept(this)); |
| 1509 return true; |
| 1510 } |
1434 } | 1511 } |
1435 } | 1512 } |
1436 | 1513 |
1437 return false; | 1514 return false; |
1438 } | 1515 } |
1439 | 1516 |
1440 addInlinedInstantiation(DartType type) { | 1517 addInlinedInstantiation(DartType type) { |
1441 if (type != null) { | 1518 if (type != null) { |
1442 currentInlinedInstantiations.add(type); | 1519 currentInlinedInstantiations.add(type); |
1443 } | 1520 } |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 add(assertIsSubtype); | 2128 add(assertIsSubtype); |
2052 } | 2129 } |
2053 | 2130 |
2054 HGraph closeFunction() { | 2131 HGraph closeFunction() { |
2055 // TODO(kasperl): Make this goto an implicit return. | 2132 // TODO(kasperl): Make this goto an implicit return. |
2056 if (!isAborted()) closeAndGotoExit(new HGoto()); | 2133 if (!isAborted()) closeAndGotoExit(new HGoto()); |
2057 graph.finalize(); | 2134 graph.finalize(); |
2058 return graph; | 2135 return graph; |
2059 } | 2136 } |
2060 | 2137 |
2061 HBasicBlock addNewBlock() { | |
2062 HBasicBlock block = graph.addNewBlock(); | |
2063 // If adding a new block during building of an expression, it is due to | |
2064 // conditional expressions or short-circuit logical operators. | |
2065 return block; | |
2066 } | |
2067 | |
2068 void open(HBasicBlock block) { | |
2069 block.open(); | |
2070 current = block; | |
2071 lastOpenedBlock = block; | |
2072 } | |
2073 | |
2074 HBasicBlock close(HControlFlow end) { | |
2075 HBasicBlock result = current; | |
2076 current.close(end); | |
2077 current = null; | |
2078 return result; | |
2079 } | |
2080 | |
2081 HBasicBlock closeAndGotoExit(HControlFlow end) { | |
2082 HBasicBlock result = current; | |
2083 current.close(end); | |
2084 current = null; | |
2085 result.addSuccessor(graph.exit); | |
2086 return result; | |
2087 } | |
2088 | |
2089 void goto(HBasicBlock from, HBasicBlock to) { | |
2090 from.close(new HGoto()); | |
2091 from.addSuccessor(to); | |
2092 } | |
2093 | |
2094 bool isAborted() { | |
2095 return _current == null; | |
2096 } | |
2097 | |
2098 /** | |
2099 * Creates a new block, transitions to it from any current block, and | |
2100 * opens the new block. | |
2101 */ | |
2102 HBasicBlock openNewBlock() { | |
2103 HBasicBlock newBlock = addNewBlock(); | |
2104 if (!isAborted()) goto(current, newBlock); | |
2105 open(newBlock); | |
2106 return newBlock; | |
2107 } | |
2108 | |
2109 void add(HInstruction instruction) { | |
2110 current.add(instruction); | |
2111 } | |
2112 | |
2113 void addWithPosition(HInstruction instruction, Node node) { | 2138 void addWithPosition(HInstruction instruction, Node node) { |
2114 add(attachPosition(instruction, node)); | 2139 add(attachPosition(instruction, node)); |
2115 } | 2140 } |
2116 | 2141 |
2117 void push(HInstruction instruction) { | 2142 void push(HInstruction instruction) { |
2118 add(instruction); | 2143 add(instruction); |
2119 stack.add(instruction); | 2144 stack.add(instruction); |
2120 } | 2145 } |
2121 | 2146 |
2122 void pushWithPosition(HInstruction instruction, Node node) { | 2147 void pushWithPosition(HInstruction instruction, Node node) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 | 2184 |
2160 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { | 2185 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { |
2161 Element element = sourceElementStack.last; | 2186 Element element = sourceElementStack.last; |
2162 // TODO(johnniwinther): remove the 'element.patch' hack. | 2187 // TODO(johnniwinther): remove the 'element.patch' hack. |
2163 if (element is FunctionElement) { | 2188 if (element is FunctionElement) { |
2164 FunctionElement functionElement = element; | 2189 FunctionElement functionElement = element; |
2165 if (functionElement.patch != null) element = functionElement.patch; | 2190 if (functionElement.patch != null) element = functionElement.patch; |
2166 } | 2191 } |
2167 Script script = element.getCompilationUnit().script; | 2192 Script script = element.getCompilationUnit().script; |
2168 SourceFile sourceFile = script.file; | 2193 SourceFile sourceFile = script.file; |
2169 SourceFileLocation location = new SourceFileLocation(sourceFile, token); | 2194 SourceFileLocation location = |
| 2195 new TokenSourceFileLocation(sourceFile, token); |
2170 if (!location.isValid()) { | 2196 if (!location.isValid()) { |
2171 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( | 2197 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( |
2172 {'offset': token.charOffset, | 2198 {'offset': token.charOffset, |
2173 'fileName': sourceFile.filename, | 2199 'fileName': sourceFile.filename, |
2174 'length': sourceFile.length}); | 2200 'length': sourceFile.length}); |
2175 } | 2201 } |
2176 return location; | 2202 return location; |
2177 } | 2203 } |
2178 | 2204 |
2179 void visit(Node node) { | 2205 void visit(Node node) { |
(...skipping 3758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5938 new HSubGraphBlockInformation(elseBranch.graph)); | 5964 new HSubGraphBlockInformation(elseBranch.graph)); |
5939 | 5965 |
5940 HBasicBlock conditionStartBlock = conditionBranch.block; | 5966 HBasicBlock conditionStartBlock = conditionBranch.block; |
5941 conditionStartBlock.setBlockFlow(info, joinBlock); | 5967 conditionStartBlock.setBlockFlow(info, joinBlock); |
5942 SubGraph conditionGraph = conditionBranch.graph; | 5968 SubGraph conditionGraph = conditionBranch.graph; |
5943 HIf branch = conditionGraph.end.last; | 5969 HIf branch = conditionGraph.end.last; |
5944 assert(branch is HIf); | 5970 assert(branch is HIf); |
5945 branch.blockInformation = conditionStartBlock.blockFlow; | 5971 branch.blockInformation = conditionStartBlock.blockFlow; |
5946 } | 5972 } |
5947 } | 5973 } |
OLD | NEW |