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 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |