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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 11543017: Revert r16032: it revealed a bug in our bailout environment computation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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
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 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 HInstruction operand = node.operand; 199 HInstruction operand = node.operand;
200 if (operand is HConstant) { 200 if (operand is HConstant) {
201 UnaryOperation operation = node.operation(constantSystem); 201 UnaryOperation operation = node.operation(constantSystem);
202 HConstant receiver = operand; 202 HConstant receiver = operand;
203 Constant folded = operation.fold(receiver.constant); 203 Constant folded = operation.fold(receiver.constant);
204 if (folded != null) return graph.addConstant(folded); 204 if (folded != null) return graph.addConstant(folded);
205 } 205 }
206 return node; 206 return node;
207 } 207 }
208 208
209 HInstruction handleInterceptorCall(HInvokeDynamicMethod node) { 209 HInstruction handleInterceptorCall(HInvokeDynamic node) {
210 if (node is !HInvokeDynamicMethod) return null;
210 HInstruction input = node.inputs[1]; 211 HInstruction input = node.inputs[1];
211 if (input.isString(types) 212 if (input.isString(types)
212 && node.selector.name == const SourceString('toString')) { 213 && node.selector.name == const SourceString('toString')) {
213 return node.inputs[1]; 214 return node.inputs[1];
214 } 215 }
215 // Check if this call does not need to be intercepted. 216 // Check if this call does not need to be intercepted.
216 HType type = types[input]; 217 HType type = types[input];
217 var interceptor = node.inputs[0]; 218 var interceptor = node.inputs[0];
218 if (interceptor is !HThis && !type.canBePrimitive()) { 219 if (interceptor is !HThis && !type.canBePrimitive()) {
219 // If the type can be null, and the intercepted method can be in 220 // If the type can be null, and the intercepted method can be in
220 // the object class, keep the interceptor. 221 // the object class, keep the interceptor.
221 if (type.canBeNull() 222 if (type.canBeNull()
222 && interceptor.interceptedClasses.contains(compiler.objectClass)) { 223 && interceptor.interceptedClasses.contains(compiler.objectClass)) {
223 return node; 224 return node;
224 } 225 }
225 // Change the call to a regular invoke dynamic call. 226 // Change the call to a regular invoke dynamic call.
226 return new HInvokeDynamicMethod( 227 return new HInvokeDynamicMethod(
227 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); 228 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
228 } 229 }
229 230
230 Selector selector = node.selector; 231 Selector selector = node.selector;
231
232 if (node.isIndexOperatorOnIndexablePrimitive(types)) {
233 return new HIndex(node.inputs[1], node.inputs[2]);
234 }
235
236 SourceString selectorName = selector.name; 232 SourceString selectorName = selector.name;
237 Element target; 233 Element target;
238 if (input.isExtendableArray(types)) { 234 if (input.isExtendableArray(types)) {
239 if (selectorName == backend.jsArrayRemoveLast.name 235 if (selectorName == backend.jsArrayRemoveLast.name
240 && selector.argumentCount == 0) { 236 && selector.argumentCount == 0) {
241 target = backend.jsArrayRemoveLast; 237 target = backend.jsArrayRemoveLast;
242 } else if (selectorName == backend.jsArrayAdd.name 238 } else if (selectorName == backend.jsArrayAdd.name
243 && selector.argumentCount == 1 239 && selector.argumentCount == 1
244 && selector.namedArgumentCount == 0 240 && selector.namedArgumentCount == 0
245 && !compiler.enableTypeAssertions) { 241 && !compiler.enableTypeAssertions) {
(...skipping 28 matching lines...) Expand all
274 && node.inputs[1].isInteger(types); 270 && node.inputs[1].isInteger(types);
275 } 271 }
276 272
277 HInstruction visitInvokeStatic(HInvokeStatic node) { 273 HInstruction visitInvokeStatic(HInvokeStatic node) {
278 if (isFixedSizeListConstructor(node)) { 274 if (isFixedSizeListConstructor(node)) {
279 node.guaranteedType = HType.FIXED_ARRAY; 275 node.guaranteedType = HType.FIXED_ARRAY;
280 } 276 }
281 return node; 277 return node;
282 } 278 }
283 279
284 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 280 HInstruction visitInvokeDynamic(HInvokeDynamic node) {
285 if (node.isInterceptorCall) return handleInterceptorCall(node); 281 if (node.isInterceptorCall) return handleInterceptorCall(node);
286 HType receiverType = types[node.receiver]; 282 HType receiverType = types[node.receiver];
287 if (receiverType.isExact()) { 283 if (receiverType.isExact()) {
288 HBoundedType type = receiverType; 284 HBoundedType type = receiverType;
289 Element element = type.lookupMember(node.selector.name); 285 Element element = type.lookupMember(node.selector.name);
290 // TODO(ngeoffray): Also fold if it's a getter or variable. 286 // TODO(ngeoffray): Also fold if it's a getter or variable.
291 if (element != null && element.isFunction()) { 287 if (element != null && element.isFunction()) {
292 if (node.selector.applies(element, compiler)) { 288 if (node.selector.applies(element, compiler)) {
293 FunctionElement method = element; 289 FunctionElement method = element;
294 FunctionSignature parameters = method.computeSignature(compiler); 290 FunctionSignature parameters = method.computeSignature(compiler);
295 if (parameters.optionalParameterCount == 0) { 291 if (parameters.optionalParameterCount == 0) {
296 node.element = element; 292 node.element = element;
297 } 293 }
298 // TODO(ngeoffray): If the method has optional parameters, 294 // TODO(ngeoffray): If the method has optional parameters,
299 // we should pass the default values here. 295 // we should pass the default values here.
300 } 296 }
301 } 297 }
302 } 298 }
303 return node; 299 return node;
304 } 300 }
305 301
306 /** 302 /**
307 * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a 303 * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a
308 * [HInvokeDynamic] because we know the receiver is not a JS 304 * [HInvokeDynamic] because we know the receiver is not a JS
309 * primitive object. 305 * primitive object.
310 */ 306 */
311 HInstruction fromPrimitiveInstructionToDynamicInvocation(HInstruction node, 307 HInstruction fromPrimitiveInstructionToDynamicInvocation(HInvokeStatic node,
312 Selector selector) { 308 Selector selector) {
313 HBoundedType type = types[node.inputs[1]]; 309 HBoundedType type = types[node.inputs[1]];
314 HInvokeDynamicMethod result = new HInvokeDynamicMethod( 310 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
315 selector, 311 selector,
316 node.inputs.getRange(1, node.inputs.length - 1)); 312 node.inputs.getRange(1, node.inputs.length - 1));
317 if (type.isExact()) { 313 if (type.isExact()) {
318 HBoundedType concrete = type; 314 HBoundedType concrete = type;
319 result.element = concrete.lookupMember(selector.name); 315 result.element = concrete.lookupMember(selector.name);
320 } 316 }
321 return result; 317 return result;
322 } 318 }
323 319
324 HInstruction visitIntegerCheck(HIntegerCheck node) { 320 HInstruction visitIntegerCheck(HIntegerCheck node) {
325 HInstruction value = node.value; 321 HInstruction value = node.value;
326 if (value.isInteger(types)) return value; 322 if (value.isInteger(types)) return value;
327 if (value.isConstant()) { 323 if (value.isConstant()) {
328 HConstant constantInstruction = value; 324 HConstant constantInstruction = value;
329 assert(!constantInstruction.constant.isInt()); 325 assert(!constantInstruction.constant.isInt());
330 if (!constantSystem.isInt(constantInstruction.constant)) { 326 if (!constantSystem.isInt(constantInstruction.constant)) {
331 // -0.0 is a double but will pass the runtime integer check. 327 // -0.0 is a double but will pass the runtime integer check.
332 node.alwaysFalse = true; 328 node.alwaysFalse = true;
333 } 329 }
334 } 330 }
335 return node; 331 return node;
336 } 332 }
337 333
334
335 HInstruction visitIndex(HIndex node) {
336 if (!node.receiver.canBePrimitive(types)) {
337 Selector selector = new Selector.index();
338 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
339 }
340 return node;
341 }
342
338 HInstruction visitIndexAssign(HIndexAssign node) { 343 HInstruction visitIndexAssign(HIndexAssign node) {
339 if (!node.receiver.canBePrimitive(types)) { 344 if (!node.receiver.canBePrimitive(types)) {
340 Selector selector = new Selector.indexSet(); 345 Selector selector = new Selector.indexSet();
341 return fromPrimitiveInstructionToDynamicInvocation(node, selector); 346 return fromPrimitiveInstructionToDynamicInvocation(node, selector);
342 } 347 }
343 return node; 348 return node;
344 } 349 }
345 350
346 HInstruction visitInvokeBinary(HInvokeBinary node) { 351 HInstruction visitInvokeBinary(HInvokeBinary node) {
347 HInstruction left = node.left; 352 HInstruction left = node.left;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 HIntegerCheck check = new HIntegerCheck(value); 796 HIntegerCheck check = new HIntegerCheck(value);
792 node.block.addBefore(node, check); 797 node.block.addBefore(node, check);
793 Set<HInstruction> dominatedUsers = value.dominatedUsers(node); 798 Set<HInstruction> dominatedUsers = value.dominatedUsers(node);
794 for (HInstruction user in dominatedUsers) { 799 for (HInstruction user in dominatedUsers) {
795 user.changeUse(value, check); 800 user.changeUse(value, check);
796 } 801 }
797 return check; 802 return check;
798 } 803 }
799 804
800 void visitIndex(HIndex node) { 805 void visitIndex(HIndex node) {
806 if (!node.receiver.isIndexablePrimitive(types)) return;
801 if (boundsChecked.contains(node)) return; 807 if (boundsChecked.contains(node)) return;
802 HInstruction index = node.index; 808 HInstruction index = node.index;
803 if (!node.index.isInteger(types)) { 809 if (!node.index.isInteger(types)) {
804 index = insertIntegerCheck(node, index); 810 index = insertIntegerCheck(node, index);
805 } 811 }
806 index = insertBoundsCheck(node, node.receiver, index); 812 index = insertBoundsCheck(node, node.receiver, index);
807 node.changeUse(node.index, index); 813 node.changeUse(node.index, index);
814 assert(node.isBuiltin(types));
808 } 815 }
809 816
810 void visitIndexAssign(HIndexAssign node) { 817 void visitIndexAssign(HIndexAssign node) {
811 if (!node.receiver.isMutableArray(types)) return; 818 if (!node.receiver.isMutableArray(types)) return;
812 if (boundsChecked.contains(node)) return; 819 if (boundsChecked.contains(node)) return;
813 HInstruction index = node.index; 820 HInstruction index = node.index;
814 if (!node.index.isInteger(types)) { 821 if (!node.index.isInteger(types)) {
815 index = insertIntegerCheck(node, index); 822 index = insertIntegerCheck(node, index);
816 } 823 }
817 index = insertBoundsCheck(node, node.receiver, index); 824 index = insertBoundsCheck(node, node.receiver, index);
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 HInstruction receiver = interceptor.receiver; 1477 HInstruction receiver = interceptor.receiver;
1471 for (var user in receiver.usedBy) { 1478 for (var user in receiver.usedBy) {
1472 if (user is HInterceptor && interceptor.dominates(user)) { 1479 if (user is HInterceptor && interceptor.dominates(user)) {
1473 user.interceptedClasses = interceptor.interceptedClasses; 1480 user.interceptedClasses = interceptor.interceptedClasses;
1474 } 1481 }
1475 } 1482 }
1476 } 1483 }
1477 1484
1478 // TODO(ngeoffray): Also implement it for non-intercepted calls. 1485 // TODO(ngeoffray): Also implement it for non-intercepted calls.
1479 } 1486 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698