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

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

Issue 10544132: Revert r8592: failures on checked mode and some web tests. (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
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 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 } else { 65 } else {
66 code = codegen.buffer.toString(); 66 code = codegen.buffer.toString();
67 } 67 }
68 return buildJavaScriptFunction(element, parameters, code); 68 return buildJavaScriptFunction(element, parameters, code);
69 }); 69 });
70 } 70 }
71 71
72 String generateBailoutMethod(WorkItem work, HGraph graph) { 72 String generateBailoutMethod(WorkItem work, HGraph graph) {
73 return measure(() { 73 return measure(() {
74 compiler.tracer.traceGraph("codegen-bailout", graph); 74 compiler.tracer.traceGraph("codegen-bailout", graph);
75 new SsaBailoutPropagator(compiler).visitGraph(graph);
75 76
76 Map<Element, String> parameterNames = getParameterNames(work); 77 Map<Element, String> parameterNames = getParameterNames(work);
77 String parameters = Strings.join(parameterNames.getValues(), ', '); 78 String parameters = Strings.join(parameterNames.getValues(), ', ');
78 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( 79 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator(
79 backend, work, parameters, parameterNames); 80 backend, work, parameters, parameterNames);
80 codegen.visitGraph(graph); 81 codegen.visitGraph(graph);
81 82
83 StringBuffer newParameters = new StringBuffer();
84 if (!parameterNames.isEmpty()) newParameters.add('$parameters, ');
85 newParameters.add('state');
86
87 for (int i = 0; i < codegen.maxBailoutParameters; i++) {
88 newParameters.add(', env$i');
89 }
90
91 Element element = work.element;
82 String body = '${codegen.setup}${codegen.buffer}'; 92 String body = '${codegen.setup}${codegen.buffer}';
83 return buildJavaScriptFunction( 93 return buildJavaScriptFunction(element, newParameters.toString(), body);
84 work.element, codegen.newParameters.toString(), body);
85 }); 94 });
86 } 95 }
87 96
88 Map<Element, String> getParameterNames(WorkItem work) { 97 Map<Element, String> getParameterNames(WorkItem work) {
89 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>(); 98 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>();
90 FunctionElement function = work.element; 99 FunctionElement function = work.element;
91 100
92 // The dom/html libraries have inline JS code that reference 101 // The dom/html libraries have inline JS code that reference
93 // parameter names directly. Long-term such code will be rejected. 102 // parameter names directly. Long-term such code will be rejected.
94 // Now, just don't mangle the parameter name. 103 // Now, just don't mangle the parameter name.
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 parameterNames); 266 parameterNames);
258 allocator.visitGraph(graph); 267 allocator.visitGraph(graph);
259 variableNames = allocator.names; 268 variableNames = allocator.names;
260 } 269 }
261 270
262 visitGraph(HGraph graph) { 271 visitGraph(HGraph graph) {
263 preGenerateMethod(graph); 272 preGenerateMethod(graph);
264 currentGraph = graph; 273 currentGraph = graph;
265 indent++; // We are already inside a function. 274 indent++; // We are already inside a function.
266 subGraph = new SubGraph(graph.entry, graph.exit); 275 subGraph = new SubGraph(graph.entry, graph.exit);
267 HBasicBlock start = beginGraph(graph); 276 beginGraph(graph);
268 visitBasicBlock(start); 277 visitBasicBlock(graph.entry);
269 if (!delayedVariableDeclarations.isEmpty()) { 278 if (!delayedVariableDeclarations.isEmpty()) {
270 addIndented("var "); 279 addIndented("var ");
271 buffer.add(Strings.join( 280 buffer.add(Strings.join(
272 new List<String>.from(delayedVariableDeclarations), ', ')); 281 new List<String>.from(delayedVariableDeclarations), ', '));
273 buffer.add(";\n"); 282 buffer.add(";\n");
274 } 283 }
275 endGraph(graph); 284 endGraph(graph);
276 } 285 }
277 286
278 void visitSubGraph(SubGraph newSubGraph) { 287 void visitSubGraph(SubGraph newSubGraph) {
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 } 2456 }
2448 } 2457 }
2449 } 2458 }
2450 2459
2451 class SsaOptimizedCodeGenerator extends SsaCodeGenerator { 2460 class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
2452 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames) 2461 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames)
2453 : super(backend, work, parameters, parameterNames); 2462 : super(backend, work, parameters, parameterNames);
2454 2463
2455 int maxBailoutParameters; 2464 int maxBailoutParameters;
2456 2465
2457 HBasicBlock beginGraph(HGraph graph) => graph.entry; 2466 void beginGraph(HGraph graph) {}
2458 void endGraph(HGraph graph) {} 2467 void endGraph(HGraph graph) {}
2459 2468
2460 void bailout(HTypeGuard guard, String reason) { 2469 void bailout(HTypeGuard guard, String reason) {
2461 if (maxBailoutParameters === null) { 2470 if (maxBailoutParameters === null) {
2462 maxBailoutParameters = 0; 2471 maxBailoutParameters = 0;
2463 work.guards.forEach((HTypeGuard guard) { 2472 work.guards.forEach((HTypeGuard guard) {
2464 int inputLength = guard.inputs.length; 2473 int inputLength = guard.inputs.length;
2465 if (inputLength > maxBailoutParameters) { 2474 if (inputLength > maxBailoutParameters) {
2466 maxBailoutParameters = inputLength; 2475 maxBailoutParameters = inputLength;
2467 } 2476 }
2468 }); 2477 });
2469 } 2478 }
2470 HInstruction input = guard.guarded; 2479 HInstruction input = guard.guarded;
2471 Namer namer = compiler.namer; 2480 Namer namer = compiler.namer;
2472 Element element = work.element; 2481 Element element = work.element;
2473 buffer.add('return '); 2482 buffer.add('return ');
2474 if (element.isInstanceMember()) { 2483 if (element.isInstanceMember()) {
2475 // TODO(ngeoffray): This does not work in case we come from a 2484 // TODO(ngeoffray): This does not work in case we come from a
2476 // super call. We must make bailout names unique. 2485 // super call. We must make bailout names unique.
2477 buffer.add('this.${namer.getBailoutName(element)}'); 2486 buffer.add('this.${namer.getBailoutName(element)}');
2478 } else { 2487 } else {
2479 buffer.add(namer.isolateBailoutAccess(element)); 2488 buffer.add(namer.isolateBailoutAccess(element));
2480 } 2489 }
2481 buffer.add('(${guard.state}'); 2490 int parametersCount = parameterNames.length;
2491 buffer.add('($parameters');
2492 if (parametersCount != 0) buffer.add(', ');
2493 buffer.add('${guard.state}');
2482 // TODO(ngeoffray): try to put a variable at a deterministic 2494 // TODO(ngeoffray): try to put a variable at a deterministic
2483 // location, so that multiple bailout calls put the variable at 2495 // location, so that multiple bailout calls put the variable at
2484 // the same parameter index. 2496 // the same parameter index.
2485 int i = 0; 2497 int i = 0;
2486 for (; i < guard.inputs.length; i++) { 2498 for (; i < guard.inputs.length; i++) {
2487 buffer.add(', '); 2499 buffer.add(', ');
2488 use(guard.inputs[i], JSPrecedence.ASSIGNMENT_PRECEDENCE); 2500 use(guard.inputs[i], JSPrecedence.ASSIGNMENT_PRECEDENCE);
2489 } 2501 }
2490 // Make sure we call the bailout method with the number of 2502 // Make sure we call the bailout method with the number of
2491 // arguments it expects. This avoids having the underlying 2503 // arguments it expects. This avoids having the underlying
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2600 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2589 } 2601 }
2590 2602
2591 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2603 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2592 } 2604 }
2593 } 2605 }
2594 2606
2595 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { 2607 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
2596 2608
2597 final StringBuffer setup; 2609 final StringBuffer setup;
2598 final StringBuffer newParameters;
2599 final List<String> labels; 2610 final List<String> labels;
2600 int labelId = 0; 2611 int labelId = 0;
2601 int maxBailoutParameters = 0; 2612 int maxBailoutParameters = 0;
2602 2613
2603 SsaBailoutPropagator propagator;
2604 HInstruction savedFirstInstruction;
2605
2606 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames) 2614 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames)
2607 : super(backend, work, parameters, parameterNames), 2615 : super(backend, work, parameters, parameterNames),
2608 setup = new StringBuffer(), 2616 setup = new StringBuffer(),
2609 newParameters = new StringBuffer(),
2610 labels = <String>[]; 2617 labels = <String>[];
2611 2618
2612 String pushLabel() { 2619 String pushLabel() {
2613 String label = 'L${labelId++}'; 2620 String label = 'L${labelId++}';
2614 labels.addLast(label); 2621 labels.addLast(label);
2615 return label; 2622 return label;
2616 } 2623 }
2617 2624
2618 String popLabel() { 2625 String popLabel() {
2619 return labels.removeLast(); 2626 return labels.removeLast();
2620 } 2627 }
2621 2628
2622 String currentLabel() { 2629 String currentLabel() {
2623 return labels.last(); 2630 return labels.last();
2624 } 2631 }
2625 2632
2626 HBasicBlock beginGraph(HGraph graph) { 2633 void beginGraph(HGraph graph) {
2627 propagator = new SsaBailoutPropagator(compiler, generateAtUseSite); 2634 if (!graph.entry.hasGuards()) return;
2628 propagator.visitGraph(graph); 2635 addIndented('switch (state) {\n');
2636 indent++;
2637 addIndented('case 0:\n');
2638 indent++;
2629 2639
2630 if (propagator.hasComplexTypeGuards) { 2640 // The setup phase of a bailout function sets up the environment for
2631 startBailoutSwitch(); 2641 // each bailout target. Each bailout target will populate this
2642 // setup phase. It is put at the beginning of the function.
2643 setup.add(' switch (state) {\n');
2644 }
2632 2645
2633 // The setup phase of a bailout function sets up the environment for 2646 void endGraph(HGraph graph) {
2634 // each bailout target. Each bailout target will populate this 2647 if (!graph.entry.hasGuards()) return;
2635 // setup phase. It is put at the beginning of the function. 2648 indent--; // Close original case.
2636 setup.add(' switch (state) {\n'); 2649 indent--;
2637 return graph.entry; 2650 addIndented('}\n'); // Close 'switch'.
2638 } else { 2651 setup.add(' }\n');
2639 // We change the first instruction of the first guard to be the
2640 // guard. We will change it back in the call to [endGraph].
2641 HBasicBlock block = propagator.firstTypeGuard.block;
2642 savedFirstInstruction = block.first;
2643 block.first = propagator.firstTypeGuard;
2644 return block;
2645 }
2646 } 2652 }
2647 2653
2654 bool visitAndOrInfo(HAndOrBlockInformation info) => false;
2655 bool visitIfInfo(HIfBlockInformation info) => false;
2656 bool visitLoopInfo(HLoopBlockInformation info) => false;
2657 bool visitTryInfo(HTryBlockInformation info) => false;
2658 bool visitSequenceInfo(HStatementSequenceInformation info) => false;
2659
2648 // If argument is a [HCheck] and it does not have a name, we try to 2660 // If argument is a [HCheck] and it does not have a name, we try to
2649 // find the name of its checked input. Note that there must be a 2661 // find the name of its checked input. Note that there must be a
2650 // name, otherwise the instruction would not be in the live 2662 // name, otherwise the instruction would not be in the live
2651 // environment. 2663 // environment.
2652 HInstruction unwrap(HInstruction argument) { 2664 HInstruction unwrap(argument) {
2653 while (argument is HCheck && !variableNames.hasName(argument)) { 2665 while (argument is HCheck && !variableNames.hasName(argument)) {
2654 argument = argument.checkedInput; 2666 argument = argument.checkedInput;
2655 } 2667 }
2656 assert(variableNames.hasName(argument)); 2668 assert(variableNames.hasName(argument));
2657 return argument; 2669 return argument;
2658 } 2670 }
2659 2671
2660 void endGraph(HGraph graph) {
2661 // TODO(ngeoffray): We could avoid generating the state at the
2662 // call site for non-complex bailout methods.
2663 newParameters.add('state');
2664
2665 if (!propagator.hasComplexTypeGuards) {
2666 propagator.firstTypeGuard.block.first = savedFirstInstruction;
2667 for (HInstruction input in propagator.firstTypeGuard.inputs) {
2668 input = unwrap(input);
2669 newParameters.add(', ${variableNames.getName(input)}');
2670 }
2671 } else {
2672 for (int i = 0; i < maxBailoutParameters; i++) {
2673 newParameters.add(', env$i');
2674 }
2675 indent--; // Close original case.
2676 indent--;
2677 addIndented('}\n'); // Close 'switch'.
2678 setup.add(' }\n');
2679 }
2680 }
2681
2682 bool visitAndOrInfo(HAndOrBlockInformation info) => false;
2683
2684 bool visitIfInfo(HIfBlockInformation info) {
2685 if (info.thenGraph.start.hasGuards()) return false;
2686 if (info.elseGraph.start.hasGuards()) return false;
2687 return super.visitIfInfo(info);
2688 }
2689
2690 bool visitLoopInfo(HLoopBlockInformation info) {
2691 if (info.start.hasGuards()) return false;
2692 if (info.loopHeader.hasGuards()) return false;
2693 return super.visitLoopInfo(info);
2694 }
2695
2696 bool visitTryInfo(HTryBlockInformation info) => false;
2697 bool visitSequenceInfo(HStatementSequenceInformation info) => false;
2698
2699 void visitTypeGuard(HTypeGuard node) { 2672 void visitTypeGuard(HTypeGuard node) {
2700 if (!propagator.hasComplexTypeGuards) return;
2701
2702 indent--; 2673 indent--;
2703 addIndented('case ${node.state}:\n'); 2674 addIndented('case ${node.state}:\n');
2704 indent++; 2675 indent++;
2705 addIndented('state = 0;\n'); 2676 addIndented('state = 0;\n');
2706 2677
2707 setup.add(' case ${node.state}:\n'); 2678 setup.add(' case ${node.state}:\n');
2708 int i = 0; 2679 int i = 0;
2709 for (HInstruction input in node.inputs) { 2680 for (HInstruction input in node.inputs) {
2710 input = unwrap(input); 2681 HInstruction instruction = unwrap(input);
2711 String name = variableNames.getName(input); 2682 setup.add(' ${variableNames.getName(instruction)} = env$i;\n');
2712 setup.add(' $name = env$i;\n');
2713 i++; 2683 i++;
2714 } 2684 }
2715 if (i > maxBailoutParameters) maxBailoutParameters = i; 2685 if (i > maxBailoutParameters) maxBailoutParameters = i;
2716 setup.add(' break;\n'); 2686 setup.add(' break;\n');
2717 } 2687 }
2718 2688
2719 void startBailoutCase(List<HTypeGuard> bailouts1, 2689 void startBailoutCase(List<HTypeGuard> bailouts1,
2720 List<HTypeGuard> bailouts2) { 2690 List<HTypeGuard> bailouts2) {
2721 indent--; 2691 indent--;
2722 handleBailoutCase(bailouts1); 2692 handleBailoutCase(bailouts1);
(...skipping 14 matching lines...) Expand all
2737 indent++; 2707 indent++;
2738 } 2708 }
2739 2709
2740 void endBailoutSwitch() { 2710 void endBailoutSwitch() {
2741 indent--; // Close 'case'. 2711 indent--; // Close 'case'.
2742 indent--; 2712 indent--;
2743 addIndented('}\n'); // Close 'switch'. 2713 addIndented('}\n'); // Close 'switch'.
2744 } 2714 }
2745 2715
2746 void beginLoop(HBasicBlock block) { 2716 void beginLoop(HBasicBlock block) {
2717 // TODO(ngeoffray): Don't put labels on loops that don't bailout.
2747 String newLabel = pushLabel(); 2718 String newLabel = pushLabel();
2748 if (block.hasGuards()) { 2719 if (block.hasGuards()) {
2749 startBailoutCase(block.guards, const <HTypeGuard>[]); 2720 startBailoutCase(block.guards, const <HTypeGuard>[]);
2750 } 2721 }
2751 2722
2752 addIndentation(); 2723 addIndentation();
2753 HLoopInformation loopInformation = block.loopInformation; 2724 HLoopInformation loopInformation = block.loopInformation;
2754 for (LabelElement label in loopInformation.labels) { 2725 for (LabelElement label in loopInformation.labels) {
2755 writeLabel(label); 2726 writeLabel(label);
2756 buffer.add(":"); 2727 buffer.add(":");
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 startBailoutSwitch(); 2816 startBailoutSwitch();
2846 } 2817 }
2847 } 2818 }
2848 2819
2849 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2820 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2850 if (labeledBlockInfo.body.start.hasGuards()) { 2821 if (labeledBlockInfo.body.start.hasGuards()) {
2851 endBailoutSwitch(); 2822 endBailoutSwitch();
2852 } 2823 }
2853 } 2824 }
2854 } 2825 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/bailout.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698