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

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 11186048: Fix bad mangling of environment parameters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update comments. Created 8 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 6
7 final JavaScriptBackend backend; 7 final JavaScriptBackend backend;
8 8
9 SsaCodeGeneratorTask(JavaScriptBackend backend) 9 SsaCodeGeneratorTask(JavaScriptBackend backend)
10 : this.backend = backend, 10 : this.backend = backend,
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 } 1095 }
1096 1096
1097 void emitAssignment(String destination, String source) { 1097 void emitAssignment(String destination, String source) {
1098 assignVariable(destination, new js.VariableUse(source)); 1098 assignVariable(destination, new js.VariableUse(source));
1099 } 1099 }
1100 1100
1101 /** 1101 /**
1102 * Sequentialize a list of conceptually parallel copies. Parallel 1102 * Sequentialize a list of conceptually parallel copies. Parallel
1103 * copies may contain cycles, that this method breaks. 1103 * copies may contain cycles, that this method breaks.
1104 */ 1104 */
1105 void sequentializeCopies(List<Copy> copies) { 1105 void sequentializeCopies(List<Copy> copies,
1106 String tempName,
ngeoffray 2012/10/25 11:27:45 Why parameterizing tempName? It's swapTemp for bot
floitsch 2012/10/31 14:49:19 I don't want sequentializeCopies to deal with the
1107 void doAssignment(String target, String source)) {
1106 // Map to keep track of the current location (ie the variable that 1108 // Map to keep track of the current location (ie the variable that
1107 // holds the initial value) of a variable. 1109 // holds the initial value) of a variable.
1108 Map<String, String> currentLocation = new Map<String, String>(); 1110 Map<String, String> currentLocation = new Map<String, String>();
1109 1111
1110 // Map to keep track of the initial value of a variable. 1112 // Map to keep track of the initial value of a variable.
1111 Map<String, String> initialValue = new Map<String, String>(); 1113 Map<String, String> initialValue = new Map<String, String>();
1112 1114
1113 // List of variables to assign a value. 1115 // List of variables to assign a value.
1114 List<String> worklist = <String>[]; 1116 List<String> worklist = <String>[];
1115 1117
1116 // List of variables that we can assign a value to (ie are not 1118 // List of variables that we can assign a value to (ie are not
1117 // being used anymore). 1119 // being used anymore).
1118 List<String> ready = <String>[]; 1120 List<String> ready = <String>[];
1119 1121
1120 // Prune [copies] by removing self-copies. 1122 // Prune [copies] by removing self-copies.
1121 List<Copy> prunedCopies = <Copy>[]; 1123 List<Copy> prunedCopies = <Copy>[];
1122 for (Copy copy in copies) { 1124 for (Copy copy in copies) {
1123 String sourceName = variableNames.getName(copy.source); 1125 if (copy.source != copy.destination) {
1124 String destinationName = variableNames.getName(copy.destination); 1126 prunedCopies.add(copy);
1125 if (sourceName != destinationName) {
1126 prunedCopies.add(new Copy(sourceName, destinationName));
1127 } 1127 }
1128 } 1128 }
1129 copies = prunedCopies; 1129 copies = prunedCopies;
1130 1130
1131 1131
1132 // For each copy, set the current location of the source to 1132 // For each copy, set the current location of the source to
1133 // itself, and the initial value of the destination to the source. 1133 // itself, and the initial value of the destination to the source.
1134 // Add the destination to the list of copies to make. 1134 // Add the destination to the list of copies to make.
1135 for (Copy copy in copies) { 1135 for (Copy copy in copies) {
1136 currentLocation[copy.source] = copy.source; 1136 currentLocation[copy.source] = copy.source;
1137 initialValue[copy.destination] = copy.source; 1137 initialValue[copy.destination] = copy.source;
1138 worklist.add(copy.destination); 1138 worklist.add(copy.destination);
1139 } 1139 }
1140 1140
1141 // For each copy, if the destination does not have a current 1141 // For each copy, if the destination does not have a current
1142 // location, then we can safely assign to it. 1142 // location, then we can safely assign to it.
1143 for (Copy copy in copies) { 1143 for (Copy copy in copies) {
1144 if (currentLocation[copy.destination] == null) { 1144 if (currentLocation[copy.destination] == null) {
1145 ready.add(copy.destination); 1145 ready.add(copy.destination);
1146 } 1146 }
1147 } 1147 }
1148 1148
1149 while (!worklist.isEmpty()) { 1149 while (!worklist.isEmpty()) {
1150 while (!ready.isEmpty()) { 1150 while (!ready.isEmpty()) {
1151 String destination = ready.removeLast(); 1151 String destination = ready.removeLast();
1152 String source = initialValue[destination]; 1152 String source = initialValue[destination];
1153 // Since [source] might have been updated, use the current 1153 // Since [source] might have been updated, use the current
1154 // location of [source] 1154 // location of [source]
1155 String copy = currentLocation[source]; 1155 String copy = currentLocation[source];
1156 emitAssignment(destination, copy); 1156 doAssignment(destination, copy);
1157 // Now [destination] is the current location of [source]. 1157 // Now [destination] is the current location of [source].
1158 currentLocation[source] = destination; 1158 currentLocation[source] = destination;
1159 // If [source] hasn't been updated and needs to have a value, 1159 // If [source] hasn't been updated and needs to have a value,
1160 // add it to the list of variables that can be updated. Copies 1160 // add it to the list of variables that can be updated. Copies
1161 // of [source] will now use [destination]. 1161 // of [source] will now use [destination].
1162 if (source == copy && initialValue[source] != null) { 1162 if (source == copy && initialValue[source] != null) {
1163 ready.add(source); 1163 ready.add(source);
1164 } 1164 }
1165 } 1165 }
1166 1166
1167 // Check if we have a cycle. 1167 // Check if we have a cycle.
1168 String current = worklist.removeLast(); 1168 String current = worklist.removeLast();
1169 // If [current] is used as a source, and the assignment has been 1169 // If [current] is used as a source, and the assignment has been
1170 // done, we are done with this variable. Otherwise there is a 1170 // done, we are done with this variable. Otherwise there is a
1171 // cycle that we break by using a temporary name. 1171 // cycle that we break by using a temporary name.
1172 if (currentLocation[current] != null 1172 if (currentLocation[current] != null
1173 && current != currentLocation[initialValue[current]]) { 1173 && current != currentLocation[initialValue[current]]) {
1174 String tempName = variableNames.swapTemp; 1174 doAssignment(tempName, current);
1175 emitAssignment(tempName, current);
1176 currentLocation[current] = tempName; 1175 currentLocation[current] = tempName;
1177 // [current] can now be safely updated. Copies of [current] 1176 // [current] can now be safely updated. Copies of [current]
1178 // will now use [tempName]. 1177 // will now use [tempName].
1179 ready.add(current); 1178 ready.add(current);
1180 } 1179 }
1181 } 1180 }
1182 } 1181 }
1183 1182
1184 void assignPhisOfSuccessors(HBasicBlock node) { 1183 void assignPhisOfSuccessors(HBasicBlock node) {
1185 CopyHandler handler = variableNames.getCopyHandler(node); 1184 CopyHandler handler = variableNames.getCopyHandler(node);
1186 if (handler == null) return; 1185 if (handler == null) return;
1187 1186
1188 sequentializeCopies(handler.copies); 1187 // Map the instructions to strings.
1188 List<Copy> copies = handler.copies.map((Copy copy) {
1189 return new Copy(variableNames.getName(copy.source),
1190 variableNames.getName(copy.destination));
1191 });
1192
1193 sequentializeCopies(copies, variableNames.swapTemp, emitAssignment);
1189 1194
1190 for (Copy copy in handler.assignments) { 1195 for (Copy copy in handler.assignments) {
1191 String name = variableNames.getName(copy.destination); 1196 String name = variableNames.getName(copy.destination);
1192 use(copy.source); 1197 use(copy.source);
1193 assignVariable(name, pop()); 1198 assignVariable(name, pop());
1194 } 1199 }
1195 } 1200 }
1196 1201
1197 void iterateBasicBlock(HBasicBlock node) { 1202 void iterateBasicBlock(HBasicBlock node) {
1198 HInstruction instruction = node.first; 1203 HInstruction instruction = node.first;
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
2787 if (!propagator.hasComplexBailoutTargets) return; 2792 if (!propagator.hasComplexBailoutTargets) return;
2788 2793
2789 js.Block nextBlock = new js.Block.empty(); 2794 js.Block nextBlock = new js.Block.empty();
2790 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'), 2795 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'),
2791 nextBlock); 2796 nextBlock);
2792 currentBailoutSwitch.cases.add(clause); 2797 currentBailoutSwitch.cases.add(clause);
2793 currentContainer = nextBlock; 2798 currentContainer = nextBlock;
2794 pushExpressionAsStatement(new js.Assignment(generateStateUse(), 2799 pushExpressionAsStatement(new js.Assignment(generateStateUse(),
2795 new js.LiteralNumber('0'))); 2800 new js.LiteralNumber('0')));
2796 js.Block setupBlock = new js.Block.empty(); 2801 js.Block setupBlock = new js.Block.empty();
2797 int i = 0; 2802 List<Copy> copies = <Copy>[];
2798 for (HInstruction input in node.inputs) { 2803 for (int i = 0; i < node.inputs.length; i++) {
2804 HInstruction input = node.inputs[i];
2799 input = unwrap(input); 2805 input = unwrap(input);
2800 String name = variableNames.getName(input); 2806 String name = variableNames.getName(input);
2801 if (!isVariableDeclared(name)) { 2807 String source = "env$i";
2802 declaredVariables.add(name); 2808 copies.add(new Copy(source, name));
2809 }
2810 sequentializeCopies(copies,
2811 variableNames.swapTemp,
2812 (String target, String source) {
2813 if (!isVariableDeclared(target)) {
2814 declaredVariables.add(target);
2803 js.VariableInitialization init = 2815 js.VariableInitialization init =
2804 new js.VariableInitialization(new js.VariableDeclaration(name), 2816 new js.VariableInitialization(new js.VariableDeclaration(target),
2805 new js.VariableUse('env$i')); 2817 new js.VariableUse(source));
2806 js.Expression varList = 2818 js.Expression varList =
2807 new js.VariableDeclarationList(<js.VariableInitialization>[init]); 2819 new js.VariableDeclarationList(<js.VariableInitialization>[init]);
2808 setupBlock.statements.add(new js.ExpressionStatement(varList)); 2820 setupBlock.statements.add(new js.ExpressionStatement(varList));
2809 } else { 2821 } else {
2810 js.Expression target = new js.VariableUse(name); 2822 js.Expression jsTarget = new js.VariableUse(target);
2811 js.Expression source = new js.VariableUse('env$i'); 2823 js.Expression jsSource = new js.VariableUse(source);
2812 js.Expression assignment = new js.Assignment(target, source); 2824 js.Expression assignment = new js.Assignment(jsTarget, jsSource);
2813 setupBlock.statements.add(new js.ExpressionStatement(assignment)); 2825 setupBlock.statements.add(new js.ExpressionStatement(assignment));
2814 } 2826 }
2815 i++; 2827 });
2816 }
2817 setupBlock.statements.add(new js.Break(null)); 2828 setupBlock.statements.add(new js.Break(null));
2818 js.Case setupClause = 2829 js.Case setupClause =
2819 new js.Case(new js.LiteralNumber('${node.state}'), setupBlock); 2830 new js.Case(new js.LiteralNumber('${node.state}'), setupBlock);
2820 (setup as js.Switch).cases.add(setupClause); 2831 (setup as js.Switch).cases.add(setupClause);
2821 } 2832 }
2822 2833
2823 void startBailoutCase(List<HBailoutTarget> bailouts1, 2834 void startBailoutCase(List<HBailoutTarget> bailouts1,
2824 [List<HBailoutTarget> bailouts2 = const []]) { 2835 [List<HBailoutTarget> bailouts2 = const []]) {
2825 if (!defaultClauseUsedInBailoutStack.last() && 2836 if (!defaultClauseUsedInBailoutStack.last() &&
2826 bailouts1.length + bailouts2.length >= 2) { 2837 bailouts1.length + bailouts2.length >= 2) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2990 if (leftType.canBeNull() && rightType.canBeNull()) { 3001 if (leftType.canBeNull() && rightType.canBeNull()) {
2991 if (left.isConstantNull() || right.isConstantNull() || 3002 if (left.isConstantNull() || right.isConstantNull() ||
2992 (leftType.isPrimitive() && leftType == rightType)) { 3003 (leftType.isPrimitive() && leftType == rightType)) {
2993 return '=='; 3004 return '==';
2994 } 3005 }
2995 return null; 3006 return null;
2996 } else { 3007 } else {
2997 return '==='; 3008 return '===';
2998 } 3009 }
2999 } 3010 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/variable_allocator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698