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