Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |