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

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: Address comment. 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
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 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 } 2689 }
2690 2690
2691 String popLabel() { 2691 String popLabel() {
2692 return labels.removeLast(); 2692 return labels.removeLast();
2693 } 2693 }
2694 2694
2695 String currentLabel() { 2695 String currentLabel() {
2696 return labels.last(); 2696 return labels.last();
2697 } 2697 }
2698 2698
2699 js.VariableUse generateStateUse()
2700 => new js.VariableUse(variableNames.stateName);
2701
2699 HBasicBlock beginGraph(HGraph graph) { 2702 HBasicBlock beginGraph(HGraph graph) {
2700 propagator = new SsaBailoutPropagator(compiler, generateAtUseSite); 2703 propagator = new SsaBailoutPropagator(compiler, generateAtUseSite);
2701 propagator.visitGraph(graph); 2704 propagator.visitGraph(graph);
2702 // TODO(ngeoffray): We could avoid generating the state at the 2705 // TODO(ngeoffray): We could avoid generating the state at the
2703 // call site for non-complex bailout methods. 2706 // call site for non-complex bailout methods.
2704 newParameters.add(new js.Parameter('state')); 2707 newParameters.add(new js.Parameter(variableNames.stateName));
2705 2708
2706 if (propagator.hasComplexBailoutTargets) { 2709 if (propagator.hasComplexBailoutTargets) {
2707 // Use generic parameters that will be assigned to 2710 // Use generic parameters that will be assigned to
2708 // the right variables in the setup phase. 2711 // the right variables in the setup phase.
2709 for (int i = 0; i < propagator.maxBailoutParameters; i++) { 2712 for (int i = 0; i < propagator.maxBailoutParameters; i++) {
2710 String name = 'env$i'; 2713 String name = 'env$i';
2711 declaredVariables.add(name); 2714 declaredVariables.add(name);
2712 newParameters.add(new js.Parameter(name)); 2715 newParameters.add(new js.Parameter(name));
ngeoffray 2012/10/15 14:12:29 Something doesn't look right here: why do you need
floitsch 2012/10/18 14:58:47 There was still a bug in the handling of environme
2713 } 2716 }
2714 2717
2715 startBailoutSwitch(); 2718 startBailoutSwitch();
2716 2719
2717 // The setup phase of a bailout function sets up the environment for 2720 // The setup phase of a bailout function sets up the environment for
2718 // each bailout target. Each bailout target will populate this 2721 // each bailout target. Each bailout target will populate this
2719 // setup phase. It is put at the beginning of the function. 2722 // setup phase. It is put at the beginning of the function.
2720 setup = new js.Switch(new js.VariableUse('state'), <js.SwitchClause>[]); 2723 setup = new js.Switch(generateStateUse(), <js.SwitchClause>[]);
2721 return graph.entry; 2724 return graph.entry;
2722 } else { 2725 } else {
2723 // We have a simple bailout target, so we can reuse the names that 2726 // We have a simple bailout target, so we can reuse the names that
2724 // the bailout target expects. 2727 // the bailout target expects.
2725 for (HInstruction input in propagator.firstBailoutTarget.inputs) { 2728 for (HInstruction input in propagator.firstBailoutTarget.inputs) {
2726 input = unwrap(input); 2729 input = unwrap(input);
2727 String name = variableNames.getName(input); 2730 String name = variableNames.getName(input);
2728 declaredVariables.add(name); 2731 declaredVariables.add(name);
2729 newParameters.add(new js.Parameter(name)); 2732 newParameters.add(new js.Parameter(name));
2730 } 2733 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2781 } 2784 }
2782 2785
2783 void visitBailoutTarget(HBailoutTarget node) { 2786 void visitBailoutTarget(HBailoutTarget node) {
2784 if (!propagator.hasComplexBailoutTargets) return; 2787 if (!propagator.hasComplexBailoutTargets) return;
2785 2788
2786 js.Block nextBlock = new js.Block.empty(); 2789 js.Block nextBlock = new js.Block.empty();
2787 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'), 2790 js.Case clause = new js.Case(new js.LiteralNumber('${node.state}'),
2788 nextBlock); 2791 nextBlock);
2789 currentBailoutSwitch.cases.add(clause); 2792 currentBailoutSwitch.cases.add(clause);
2790 currentContainer = nextBlock; 2793 currentContainer = nextBlock;
2791 pushExpressionAsStatement(new js.Assignment(new js.VariableUse('state'), 2794 pushExpressionAsStatement(new js.Assignment(generateStateUse(),
2792 new js.LiteralNumber('0'))); 2795 new js.LiteralNumber('0')));
2793 js.Block setupBlock = new js.Block.empty(); 2796 js.Block setupBlock = new js.Block.empty();
2794 int i = 0; 2797 int i = 0;
2795 for (HInstruction input in node.inputs) { 2798 for (HInstruction input in node.inputs) {
2796 input = unwrap(input); 2799 input = unwrap(input);
2797 String name = variableNames.getName(input); 2800 String name = variableNames.getName(input);
2798 if (!isVariableDeclared(name)) { 2801 if (!isVariableDeclared(name)) {
2799 declaredVariables.add(name); 2802 declaredVariables.add(name);
2800 js.VariableInitialization init = 2803 js.VariableInitialization init =
2801 new js.VariableInitialization(new js.VariableDeclaration(name), 2804 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())); 2841 currentBailoutSwitch.cases.add(new js.Case(expr, new js.Block.empty()));
2839 } 2842 }
2840 } 2843 }
2841 2844
2842 void startBailoutSwitch() { 2845 void startBailoutSwitch() {
2843 defaultClauseUsedInBailoutStack.add(false); 2846 defaultClauseUsedInBailoutStack.add(false);
2844 oldBailoutSwitches.add(currentBailoutSwitch); 2847 oldBailoutSwitches.add(currentBailoutSwitch);
2845 List<js.SwitchClause> cases = <js.SwitchClause>[]; 2848 List<js.SwitchClause> cases = <js.SwitchClause>[];
2846 js.Block firstBlock = new js.Block.empty(); 2849 js.Block firstBlock = new js.Block.empty();
2847 cases.add(new js.Case(new js.LiteralNumber("0"), firstBlock)); 2850 cases.add(new js.Case(new js.LiteralNumber("0"), firstBlock));
2848 currentBailoutSwitch = new js.Switch(new js.VariableUse('state'), cases); 2851 currentBailoutSwitch = new js.Switch(generateStateUse(), 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
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]);
2924 js.Binary stateEquals0 = 2927 js.Binary stateEquals0 =
2925 new js.Binary('===', 2928 new js.Binary('===', generateStateUse(), new js.LiteralNumber('0'));
2926 new js.VariableUse('state'), new js.LiteralNumber('0'));
2927 js.Expression condition = new js.Binary('&&', stateEquals0, pop()); 2929 js.Expression condition = new js.Binary('&&', stateEquals0, pop());
2928 // TODO(ngeoffray): Put the condition initialization in the 2930 // TODO(ngeoffray): Put the condition initialization in the
2929 // [setup] buffer. 2931 // [setup] buffer.
2930 List<HBailoutTarget> targets = node.thenBlock.bailoutTargets; 2932 List<HBailoutTarget> targets = node.thenBlock.bailoutTargets;
2931 for (int i = 0, len = targets.length; i < len; i++) { 2933 for (int i = 0, len = targets.length; i < len; i++) {
2932 js.VariableUse stateRef = new js.VariableUse('state'); 2934 js.VariableUse stateRef = generateStateUse();
2933 js.Expression targetState = new js.LiteralNumber('${targets[i].state}'); 2935 js.Expression targetState = new js.LiteralNumber('${targets[i].state}');
2934 js.Binary stateTest = new js.Binary('===', stateRef, targetState); 2936 js.Binary stateTest = new js.Binary('===', stateRef, targetState);
2935 condition = new js.Binary('||', stateTest, condition); 2937 condition = new js.Binary('||', stateTest, condition);
2936 } 2938 }
2937 2939
2938 js.Statement thenBody = new js.Block.empty(); 2940 js.Statement thenBody = new js.Block.empty();
2939 js.Block oldContainer = currentContainer; 2941 js.Block oldContainer = currentContainer;
2940 currentContainer = thenBody; 2942 currentContainer = thenBody;
2941 if (thenHasGuards) startBailoutSwitch(); 2943 if (thenHasGuards) startBailoutSwitch();
2942 generateStatements(thenGraph); 2944 generateStatements(thenGraph);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 if (leftType.canBeNull() && rightType.canBeNull()) { 2990 if (leftType.canBeNull() && rightType.canBeNull()) {
2989 if (left.isConstantNull() || right.isConstantNull() || 2991 if (left.isConstantNull() || right.isConstantNull() ||
2990 (leftType.isPrimitive() && leftType == rightType)) { 2992 (leftType.isPrimitive() && leftType == rightType)) {
2991 return '=='; 2993 return '==';
2992 } 2994 }
2993 return null; 2995 return null;
2994 } else { 2996 } else {
2995 return '==='; 2997 return '===';
2996 } 2998 }
2997 } 2999 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698