1// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --allow-natives-syntax
29
30(function() {
31  var result = [];
32  var x = 0;
33
34  function branch(b) {
35    if (b == "deopt") {
36      %DeoptimizeFunction(f);
37      return "c";
38    }
39
40    return b ? "a" : "b";
41  }
42
43  function f(label, b1, b2, b3) {
44    switch (label) {
45      case "string":
46        result.push(1);
47        break;
48      case branch(b1) + branch(b2):
49        result.push(2);
50        break;
51      case 10:
52        result.push(3);
53        break;
54      default:
55        branch(b3);
56        result.push(4);
57        break;
58      case x++:
59        branch(b3);
60        result.push(5);
61        break;
62    }
63  }
64
65  function assertResult(r, label, b1, b2, b3) {
66    f(label, b1, b2, b3);
67    assertEquals(result, r);
68    result = [];
69  }
70
71  // Warmup.
72  assertResult([2], "aa", true, true);
73  assertResult([2], "ab", true, false);
74  assertResult([2], "ba", false, true);
75  assertResult([2], "bb", false, false);
76  assertEquals(0, x);
77  assertResult([4], "other");
78  assertEquals(1, x);
79  assertResult([5], 1, true, true);
80  assertResult([4], 1, true, true);
81  assertResult([5], 3, true, true);
82  assertResult([4], 3, true, true);
83  assertResult([5], 5, true, true);
84  assertResult([4], 5, true, true);
85  assertEquals(7, x);
86
87  // Test regular behavior.
88  %OptimizeFunctionOnNextCall(f);
89  assertResult([2], "aa", true, true);
90  assertResult([1], "string");
91  assertResult([4], "other");
92  assertEquals(8, x);
93  assertResult([5], 8);
94  assertEquals(9, x);
95
96  // Test deopt at the beginning of the case label evaluation.
97  assertResult([2], "ca", "deopt", true);
98  %OptimizeFunctionOnNextCall(f);
99  assertResult([4], "ca", "deopt", false);
100  assertEquals(10, x);
101  %OptimizeFunctionOnNextCall(f);
102
103  // Test deopt in the middle of the case label evaluation.
104  assertResult([2], "ac", true, "deopt");
105  %OptimizeFunctionOnNextCall(f);
106  assertResult([4], "ac", false, "deopt");
107  assertEquals(11, x);
108
109  // Test deopt in the default case.
110  %OptimizeFunctionOnNextCall(f);
111  print("here");
112  assertResult([4], 10000, false, false, "deopt");
113  assertEquals(12, x);
114
115  // Test deopt in the default case.
116  %OptimizeFunctionOnNextCall(f);
117  assertResult([4], 10000, false, false, "deopt");
118  assertEquals(13, x);
119
120  // Test deopt in x++ case.
121  %OptimizeFunctionOnNextCall(f);
122  assertResult([5], 13, false, false, "deopt");
123  assertEquals(14, x);
124})();
125
126
127(function() {
128  var result = [];
129  var x = 0;
130
131  function branch(b) {
132    if (b == "deopt") {
133      %DeoptimizeFunction(f);
134      return "c";
135    }
136
137    return b ? "a" : "b";
138  }
139
140  function f(label, b1, b2, b3) {
141    switch (label) {
142      case "string":
143        result.push(1);
144        break;
145      case branch(b1) + branch(b2):
146        result.push(2);
147        // Fall through.
148      case 10:
149        result.push(3);
150        break;
151      default:
152        branch(b3);
153        result.push(4);
154        // Fall through.
155      case x++:
156        branch(b3);
157        result.push(5);
158        break;
159    }
160  }
161
162  function assertResult(r, label, b1, b2, b3) {
163    f(label, b1, b2, b3);
164    assertEquals(r, result);
165    result = [];
166  }
167
168  // Warmup.
169  assertResult([2,3], "aa", true, true);
170  assertResult([2,3], "ab", true, false);
171  assertResult([2,3], "ba", false, true);
172  assertResult([2,3], "bb", false, false);
173  assertEquals(0, x);
174  assertResult([4,5], "other");
175  assertEquals(1, x);
176  assertResult([5], 1, true, true);
177  assertResult([4,5], 1, true, true);
178  assertResult([5], 3, true, true);
179  assertResult([4,5], 3, true, true);
180  assertResult([5], 5, true, true);
181  assertResult([4,5], 5, true, true);
182  assertEquals(7, x);
183
184  // Test regular behavior.
185  %OptimizeFunctionOnNextCall(f);
186  assertResult([2,3], "aa", true, true);
187  assertResult([1], "string");
188  assertResult([4,5], "other");
189  assertEquals(8, x);
190  assertResult([5], 8);
191  assertEquals(9, x);
192
193  // Test deopt at the beginning of the case label evaluation.
194  assertResult([2,3], "ca", "deopt", true);
195  %OptimizeFunctionOnNextCall(f);
196  assertResult([4,5], "ca", "deopt", false);
197  assertEquals(10, x);
198  %OptimizeFunctionOnNextCall(f);
199
200  // Test deopt in the middle of the case label evaluation.
201  assertResult([2,3], "ac", true, "deopt");
202  %OptimizeFunctionOnNextCall(f);
203  assertResult([4,5], "ac", false, "deopt");
204  assertEquals(11, x);
205
206  // Test deopt in the default case.
207  %OptimizeFunctionOnNextCall(f);
208  print("here");
209  assertResult([4,5], 10000, false, false, "deopt");
210  assertEquals(12, x);
211
212  // Test deopt in the default case.
213  %OptimizeFunctionOnNextCall(f);
214  assertResult([4,5], 10000, false, false, "deopt");
215  assertEquals(13, x);
216
217  // Test deopt in x++ case.
218  %OptimizeFunctionOnNextCall(f);
219  assertResult([5], 13, false, false, "deopt");
220  assertEquals(14, x);
221})();
222