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

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

Issue 10454049: Validate that all instructions dominate their inputs. And fix a bug where that did not happen. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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/closure.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 Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 // accessed through a closure-field. 405 // accessed through a closure-field.
406 // Calling [readLocal] makes sure we generate the correct code to get 406 // Calling [readLocal] makes sure we generate the correct code to get
407 // the box. 407 // the box.
408 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); 408 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE);
409 HInstruction box = readLocal(redirect.enclosingElement); 409 HInstruction box = readLocal(redirect.enclosingElement);
410 HInstruction lookup = new HFieldGet(redirect.name, box); 410 HInstruction lookup = new HFieldGet(redirect.name, box);
411 builder.add(lookup); 411 builder.add(lookup);
412 return lookup; 412 return lookup;
413 } else { 413 } else {
414 assert(isUsedInTry(element)); 414 assert(isUsedInTry(element));
415 HParameterValue parameter = getActivationParameter(element); 415 HInstruction instruction = getActivationValue(element);
416 HInstruction variable = new HFieldGet.fromActivation(parameter); 416 HInstruction variable = new HFieldGet.fromActivation(instruction);
417 builder.add(variable); 417 builder.add(variable);
418 return variable; 418 return variable;
419 } 419 }
420 } 420 }
421 421
422 HType cachedTypeOfThis; 422 HType cachedTypeOfThis;
423 423
424 HInstruction readThis() { 424 HInstruction readThis() {
425 HInstruction res = readLocal(closureData.thisElement); 425 HInstruction res = readLocal(closureData.thisElement);
426 if (res.guaranteedType === null) { 426 if (res.guaranteedType === null) {
427 if (cachedTypeOfThis === null) { 427 if (cachedTypeOfThis === null) {
428 assert(closureData.isClosure()); 428 assert(closureData.isClosure());
429 Element element = closureData.thisElement; 429 Element element = closureData.thisElement;
430 ClassElement cls = element.enclosingElement.enclosingElement; 430 ClassElement cls = element.enclosingElement.enclosingElement;
431 Type type = cls.computeType(builder.compiler); 431 Type type = cls.computeType(builder.compiler);
432 cachedTypeOfThis = new HBoundedType(type); 432 cachedTypeOfThis = new HBoundedType(type);
433 } 433 }
434 res.guaranteedType = cachedTypeOfThis; 434 res.guaranteedType = cachedTypeOfThis;
435 } 435 }
436 return res; 436 return res;
437 } 437 }
438 438
439 HParameterValue getActivationParameter(Element element) { 439 HInstruction getActivationValue(Element element) {
440 if (element.isParameter()) { 440 if (element.isParameter()) return directLocals[element];
floitsch 2012/05/29 18:31:38 Please add comment what is happening here.
ngeoffray 2012/05/30 08:31:45 Done.
441 HInstruction instruction = directLocals[element];
442 if (instruction is HParameterValue) return instruction;
443 }
444 441
445 return builder.activationVariables.putIfAbsent(element, () { 442 return builder.activationVariables.putIfAbsent(element, () {
446 HParameterValue parameter = new HParameterValue(element); 443 HParameterValue parameter = new HParameterValue(element);
447 builder.graph.entry.addAtExit(parameter); 444 builder.graph.entry.addAtExit(parameter);
448 return parameter; 445 return parameter;
449 }); 446 });
450 } 447 }
451 448
452 /** 449 /**
453 * Sets the [element] to [value]. If the element is boxed or stored in a 450 * Sets the [element] to [value]. If the element is boxed or stored in a
(...skipping 14 matching lines...) Expand all
468 Element redirect = redirectionMapping[element]; 465 Element redirect = redirectionMapping[element];
469 // The box itself could be captured, or be local. A local variable that 466 // The box itself could be captured, or be local. A local variable that
470 // is captured will be boxed, but the box itself will be a local. 467 // is captured will be boxed, but the box itself will be a local.
471 // Inside the closure the box is stored in a closure-field and cannot 468 // Inside the closure the box is stored in a closure-field and cannot
472 // be accessed directly. 469 // be accessed directly.
473 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); 470 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE);
474 HInstruction box = readLocal(redirect.enclosingElement); 471 HInstruction box = readLocal(redirect.enclosingElement);
475 builder.add(new HFieldSet(redirect.name, box, value)); 472 builder.add(new HFieldSet(redirect.name, box, value));
476 } else { 473 } else {
477 assert(isUsedInTry(element)); 474 assert(isUsedInTry(element));
478 HParameterValue parameter = getActivationParameter(element); 475 HInstruction instruction = getActivationValue(element);
479 builder.add(new HFieldSet.fromActivation(parameter, value)); 476 builder.add(new HFieldSet.fromActivation(instruction, value));
480 } 477 }
481 } 478 }
482 479
483 /** 480 /**
484 * This function must be called before visiting any children of the loop. In 481 * This function must be called before visiting any children of the loop. In
485 * particular it needs to be called before executing the initializers. 482 * particular it needs to be called before executing the initializers.
486 * 483 *
487 * The [LocalsHandler] will make the boxes and updates at the right moment. 484 * The [LocalsHandler] will make the boxes and updates at the right moment.
488 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for 485 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for
489 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and 486 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and
(...skipping 2621 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 visitSwitchCase(SwitchCase node) { 3108 visitSwitchCase(SwitchCase node) {
3112 compiler.internalError('SsaBuilder.visitSwitchCase'); 3109 compiler.internalError('SsaBuilder.visitSwitchCase');
3113 } 3110 }
3114 3111
3115 visitCaseMatch(CaseMatch node) { 3112 visitCaseMatch(CaseMatch node) {
3116 compiler.internalError('SsaBuilder.visitCaseMatch'); 3113 compiler.internalError('SsaBuilder.visitCaseMatch');
3117 } 3114 }
3118 3115
3119 visitTryStatement(TryStatement node) { 3116 visitTryStatement(TryStatement node) {
3120 work.allowSpeculativeOptimization = false; 3117 work.allowSpeculativeOptimization = false;
3118 // Save the current locals. The catch block, the finally block, and
3119 // the merge block need to use this state of the locals.
3120 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
3121
3121 HBasicBlock enterBlock = openNewBlock(); 3122 HBasicBlock enterBlock = openNewBlock();
3122 HTry tryInstruction = new HTry(); 3123 HTry tryInstruction = new HTry();
3123 List<HBasicBlock> blocks = <HBasicBlock>[]; 3124 List<HBasicBlock> blocks = <HBasicBlock>[];
3124 blocks.add(close(tryInstruction)); 3125 blocks.add(close(tryInstruction));
3125 3126
3126 HBasicBlock tryBody = graph.addNewBlock(); 3127 HBasicBlock tryBody = graph.addNewBlock();
3127 enterBlock.addSuccessor(tryBody); 3128 enterBlock.addSuccessor(tryBody);
3128 open(tryBody); 3129 open(tryBody);
3129 visit(node.tryBlock); 3130 visit(node.tryBlock);
3130 if (!isAborted()) blocks.add(close(new HGoto())); 3131 if (!isAborted()) blocks.add(close(new HGoto()));
3131 SubGraph bodyGraph = new SubGraph(tryBody, lastOpenedBlock); 3132 SubGraph bodyGraph = new SubGraph(tryBody, lastOpenedBlock);
3132 SubGraph catchGraph = null; 3133 SubGraph catchGraph = null;
3133 HParameterValue exception = null; 3134 HParameterValue exception = null;
3134 if (!node.catchBlocks.isEmpty()) { 3135 if (!node.catchBlocks.isEmpty()) {
3136 localsHandler = new LocalsHandler.from(savedLocals);
floitsch 2012/05/29 18:31:38 Add comment: The catch block must not reuse the ex
ngeoffray 2012/05/30 08:31:45 Done.
3135 HBasicBlock block = graph.addNewBlock(); 3137 HBasicBlock block = graph.addNewBlock();
3136 enterBlock.addSuccessor(block); 3138 enterBlock.addSuccessor(block);
3137 open(block); 3139 open(block);
3138 // Note that the name of this element is irrelevant. 3140 // Note that the name of this element is irrelevant.
3139 Element element = new Element( 3141 Element element = new Element(
3140 const SourceString('exception'), ElementKind.PARAMETER, work.element); 3142 const SourceString('exception'), ElementKind.PARAMETER, work.element);
3141 exception = new HParameterValue(element); 3143 exception = new HParameterValue(element);
3142 add(exception); 3144 add(exception);
3143 HInstruction oldRethrowableException = rethrowableException; 3145 HInstruction oldRethrowableException = rethrowableException;
3144 rethrowableException = exception; 3146 rethrowableException = exception;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 visitThen, visitElse); 3194 visitThen, visitElse);
3193 } 3195 }
3194 } 3196 }
3195 3197
3196 CatchBlock firstBlock = link.head; 3198 CatchBlock firstBlock = link.head;
3197 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse); 3199 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse);
3198 if (!isAborted()) blocks.add(close(new HGoto())); 3200 if (!isAborted()) blocks.add(close(new HGoto()));
3199 3201
3200 rethrowableException = oldRethrowableException; 3202 rethrowableException = oldRethrowableException;
3201 catchGraph = new SubGraph(block, lastOpenedBlock); 3203 catchGraph = new SubGraph(block, lastOpenedBlock);
3204 tryInstruction.catchBlock = block;
3202 } 3205 }
3203 3206
3204 SubGraph finallyGraph = null; 3207 SubGraph finallyGraph = null;
3205 if (node.finallyBlock != null) { 3208 if (node.finallyBlock != null) {
3209 localsHandler = new LocalsHandler.from(savedLocals);
3206 HBasicBlock finallyBlock = graph.addNewBlock(); 3210 HBasicBlock finallyBlock = graph.addNewBlock();
3207 enterBlock.addSuccessor(finallyBlock); 3211 enterBlock.addSuccessor(finallyBlock);
3208 open(finallyBlock); 3212 open(finallyBlock);
3209 visit(node.finallyBlock); 3213 visit(node.finallyBlock);
3210 if (!isAborted()) blocks.add(close(new HGoto())); 3214 if (!isAborted()) blocks.add(close(new HGoto()));
3211 tryInstruction.finallyBlock = finallyBlock; 3215 tryInstruction.finallyBlock = finallyBlock;
3212 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); 3216 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock);
3213 } 3217 }
3214 3218
3215 HBasicBlock exitBlock = graph.addNewBlock(); 3219 HBasicBlock exitBlock = graph.addNewBlock();
3216 3220
3217 for (HBasicBlock block in blocks) { 3221 for (HBasicBlock block in blocks) {
3218 block.addSuccessor(exitBlock); 3222 block.addSuccessor(exitBlock);
3219 } 3223 }
3220 3224
3221 open(exitBlock); 3225 open(exitBlock);
3226 localsHandler = savedLocals;
3227
3222 enterBlock.setBlockFlow( 3228 enterBlock.setBlockFlow(
3223 new HTryBlockInformation( 3229 new HTryBlockInformation(
3224 wrapStatementGraph(bodyGraph), 3230 wrapStatementGraph(bodyGraph),
3225 exception, 3231 exception,
3226 wrapStatementGraph(catchGraph), 3232 wrapStatementGraph(catchGraph),
3227 wrapStatementGraph(finallyGraph)), 3233 wrapStatementGraph(finallyGraph)),
3228 exitBlock); 3234 exitBlock);
3229 } 3235 }
3230 3236
3231 visitScriptTag(ScriptTag node) { 3237 visitScriptTag(ScriptTag node) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3389 <HInstruction>[target, input], 3395 <HInstruction>[target, input],
3390 HType.STRING)); 3396 HType.STRING));
3391 return builder.pop(); 3397 return builder.pop();
3392 } 3398 }
3393 3399
3394 HInstruction result(Node node) { 3400 HInstruction result(Node node) {
3395 flushLiterals(node); 3401 flushLiterals(node);
3396 return prefix; 3402 return prefix;
3397 } 3403 }
3398 } 3404 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/closure.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698