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

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

Issue 11092104: Reserve a state variable for the bailout function. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add tests. 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 2683 matching lines...) Expand 10 before | Expand all | Expand 10 after
2694 2694
2695 String currentLabel() { 2695 String currentLabel() {
2696 return labels.last(); 2696 return labels.last();
2697 } 2697 }
2698 2698
2699 HBasicBlock beginGraph(HGraph graph) { 2699 HBasicBlock beginGraph(HGraph graph) {
2700 propagator = new SsaBailoutPropagator(compiler, generateAtUseSite); 2700 propagator = new SsaBailoutPropagator(compiler, generateAtUseSite);
2701 propagator.visitGraph(graph); 2701 propagator.visitGraph(graph);
2702 // TODO(ngeoffray): We could avoid generating the state at the 2702 // TODO(ngeoffray): We could avoid generating the state at the
2703 // call site for non-complex bailout methods. 2703 // call site for non-complex bailout methods.
2704 newParameters.add(new js.Parameter('state')); 2704 newParameters.add(new js.Parameter(variableNames.stateName));
2705 2705
2706 if (propagator.hasComplexBailoutTargets) { 2706 if (propagator.hasComplexBailoutTargets) {
2707 // Use generic parameters that will be assigned to 2707 // Use generic parameters that will be assigned to
2708 // the right variables in the setup phase. 2708 // the right variables in the setup phase.
2709 for (int i = 0; i < propagator.maxBailoutParameters; i++) { 2709 for (int i = 0; i < propagator.maxBailoutParameters; i++) {
2710 String name = 'env$i'; 2710 String name = 'env$i';
2711 declaredVariables.add(name); 2711 declaredVariables.add(name);
2712 newParameters.add(new js.Parameter(name)); 2712 newParameters.add(new js.Parameter(name));
2713 } 2713 }
2714 2714
2715 startBailoutSwitch(); 2715 startBailoutSwitch();
2716 2716
2717 // The setup phase of a bailout function sets up the environment for 2717 // The setup phase of a bailout function sets up the environment for
2718 // each bailout target. Each bailout target will populate this 2718 // each bailout target. Each bailout target will populate this
2719 // setup phase. It is put at the beginning of the function. 2719 // setup phase. It is put at the beginning of the function.
2720 setup = new js.Switch(new js.VariableUse('state'), <js.SwitchClause>[]); 2720 setup = new js.Switch(new js.VariableUse(variableNames.stateName),
2721 <js.SwitchClause>[]);
2721 return graph.entry; 2722 return graph.entry;
2722 } else { 2723 } else {
2723 // We have a simple bailout target, so we can reuse the names that 2724 // We have a simple bailout target, so we can reuse the names that
2724 // the bailout target expects. 2725 // the bailout target expects.
2725 for (HInstruction input in propagator.firstBailoutTarget.inputs) { 2726 for (HInstruction input in propagator.firstBailoutTarget.inputs) {
2726 input = unwrap(input); 2727 input = unwrap(input);
2727 String name = variableNames.getName(input); 2728 String name = variableNames.getName(input);
2728 declaredVariables.add(name); 2729 declaredVariables.add(name);
2729 newParameters.add(new js.Parameter(name)); 2730 newParameters.add(new js.Parameter(name));
2730 } 2731 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2781 } 2782 }
2782 2783
2783 void visitBailoutTarget(HBailoutTarget node) { 2784 void visitBailoutTarget(HBailoutTarget node) {
2784 if (!propagator.hasComplexBailoutTargets) return; 2785 if (!propagator.hasComplexBailoutTargets) return;
2785 2786
2786 js.Block nextBlock = new js.Block.empty(); 2787 js.Block nextBlock = new js.Block.empty();
2787 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'), 2788 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'),
2788 nextBlock); 2789 nextBlock);
2789 currentBailoutSwitch.cases.add(clause); 2790 currentBailoutSwitch.cases.add(clause);
2790 currentContainer = nextBlock; 2791 currentContainer = nextBlock;
2791 pushExpressionAsStatement(new js.Assignment(new js.VariableUse('state'), 2792 String stateName = variableNames.stateName;
2793 pushExpressionAsStatement(new js.Assignment(new js.VariableUse(stateName),
kasperl 2012/10/12 12:33:52 Add a helper for using the state? new js.Vari
floitsch 2012/10/12 13:16:44 Done.
2792 new js.LiteralNumber('0'))); 2794 new js.LiteralNumber('0')));
2793 js.Block setupBlock = new js.Block.empty(); 2795 js.Block setupBlock = new js.Block.empty();
2794 int i = 0; 2796 int i = 0;
2795 for (HInstruction input in node.inputs) { 2797 for (HInstruction input in node.inputs) {
2796 input = unwrap(input); 2798 input = unwrap(input);
2797 String name = variableNames.getName(input); 2799 String name = variableNames.getName(input);
2798 if (!isVariableDeclared(name)) { 2800 if (!isVariableDeclared(name)) {
2799 declaredVariables.add(name); 2801 declaredVariables.add(name);
2800 js.VariableInitialization init = 2802 js.VariableInitialization init =
2801 new js.VariableInitialization(new js.VariableDeclaration(name), 2803 new js.VariableInitialization(new js.VariableDeclaration(name),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2838 currentBailoutSwitch.cases.add(new js.Case(expr, new js.Block.empty())); 2840 currentBailoutSwitch.cases.add(new js.Case(expr, new js.Block.empty()));
2839 } 2841 }
2840 } 2842 }
2841 2843
2842 void startBailoutSwitch() { 2844 void startBailoutSwitch() {
2843 defaultClauseUsedInBailoutStack.add(false); 2845 defaultClauseUsedInBailoutStack.add(false);
2844 oldBailoutSwitches.add(currentBailoutSwitch); 2846 oldBailoutSwitches.add(currentBailoutSwitch);
2845 List<js.SwitchClause> cases = <js.SwitchClause>[]; 2847 List<js.SwitchClause> cases = <js.SwitchClause>[];
2846 js.Block firstBlock = new js.Block.empty(); 2848 js.Block firstBlock = new js.Block.empty();
2847 cases.add(new js.Case(new js.LiteralNumber("0"), firstBlock)); 2849 cases.add(new js.Case(new js.LiteralNumber("0"), firstBlock));
2848 currentBailoutSwitch = new js.Switch(new js.VariableUse('state'), cases); 2850 String stateName = variableNames.stateName;
2851 currentBailoutSwitch = new js.Switch(new js.VariableUse(stateName), cases);
2849 pushStatement(currentBailoutSwitch); 2852 pushStatement(currentBailoutSwitch);
2850 oldContainerStack.add(currentContainer); 2853 oldContainerStack.add(currentContainer);
2851 currentContainer = firstBlock; 2854 currentContainer = firstBlock;
2852 } 2855 }
2853 2856
2854 js.Switch endBailoutSwitch() { 2857 js.Switch endBailoutSwitch() {
2855 js.Switch result = currentBailoutSwitch; 2858 js.Switch result = currentBailoutSwitch;
2856 currentBailoutSwitch = oldBailoutSwitches.removeLast(); 2859 currentBailoutSwitch = oldBailoutSwitches.removeLast();
2857 defaultClauseUsedInBailoutStack.removeLast(); 2860 defaultClauseUsedInBailoutStack.removeLast();
2858 currentContainer = oldContainerStack.removeLast(); 2861 currentContainer = oldContainerStack.removeLast();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 bool hasGuards = thenHasGuards || elseHasGuards; 2917 bool hasGuards = thenHasGuards || elseHasGuards;
2915 if (!hasGuards) { 2918 if (!hasGuards) {
2916 super.generateIf(node, info); 2919 super.generateIf(node, info);
2917 return; 2920 return;
2918 } 2921 }
2919 2922
2920 startBailoutCase(thenGraph.start.bailoutTargets, 2923 startBailoutCase(thenGraph.start.bailoutTargets,
2921 elseGraph.start.bailoutTargets); 2924 elseGraph.start.bailoutTargets);
2922 2925
2923 use(node.inputs[0]); 2926 use(node.inputs[0]);
2927 String stateName = variableNames.stateName;
2924 js.Binary stateEquals0 = 2928 js.Binary stateEquals0 =
2925 new js.Binary('===', 2929 new js.Binary('===',
2926 new js.VariableUse('state'), new js.LiteralNumber('0')); 2930 new js.VariableUse(stateName), new js.LiteralNumber('0'));
2927 js.Expression condition = new js.Binary('&&', stateEquals0, pop()); 2931 js.Expression condition = new js.Binary('&&', stateEquals0, pop());
2928 // TODO(ngeoffray): Put the condition initialization in the 2932 // TODO(ngeoffray): Put the condition initialization in the
2929 // [setup] buffer. 2933 // [setup] buffer.
2930 List<HBailoutTarget> targets = node.thenBlock.bailoutTargets; 2934 List<HBailoutTarget> targets = node.thenBlock.bailoutTargets;
2931 for (int i = 0, len = targets.length; i < len; i++) { 2935 for (int i = 0, len = targets.length; i < len; i++) {
2932 js.VariableUse stateRef = new js.VariableUse('state'); 2936 js.VariableUse stateRef = new js.VariableUse(variableNames.stateName);
2933 js.Expression targetState = new js.LiteralNumber('${targets[i].state}'); 2937 js.Expression targetState = new js.LiteralNumber('${targets[i].state}');
2934 js.Binary stateTest = new js.Binary('===', stateRef, targetState); 2938 js.Binary stateTest = new js.Binary('===', stateRef, targetState);
2935 condition = new js.Binary('||', stateTest, condition); 2939 condition = new js.Binary('||', stateTest, condition);
2936 } 2940 }
2937 2941
2938 js.Statement thenBody = new js.Block.empty(); 2942 js.Statement thenBody = new js.Block.empty();
2939 js.Block oldContainer = currentContainer; 2943 js.Block oldContainer = currentContainer;
2940 currentContainer = thenBody; 2944 currentContainer = thenBody;
2941 if (thenHasGuards) startBailoutSwitch(); 2945 if (thenHasGuards) startBailoutSwitch();
2942 generateStatements(thenGraph); 2946 generateStatements(thenGraph);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 if (leftType.canBeNull() && rightType.canBeNull()) { 2992 if (leftType.canBeNull() && rightType.canBeNull()) {
2989 if (left.isConstantNull() || right.isConstantNull() || 2993 if (left.isConstantNull() || right.isConstantNull() ||
2990 (leftType.isPrimitive() && leftType == rightType)) { 2994 (leftType.isPrimitive() && leftType == rightType)) {
2991 return '=='; 2995 return '==';
2992 } 2996 }
2993 return null; 2997 return null;
2994 } else { 2998 } else {
2995 return '==='; 2999 return '===';
2996 } 3000 }
2997 } 3001 }
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