1 // Copyright 2010 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 // Test deopt with count operation on parameter. 31 var max_smi = 1073741823; 32 var o = {x:0}; 33 34 function inc1(x) { x++; o.x = x; } 35 inc1(max_smi); 36 assertEquals(max_smi + 1, o.x); 37 38 inc1(1.1); 39 assertEquals(2.1, o.x); 40 41 42 // Test deopt with count operation on named property. 43 function inc2(p) { p.x++ } 44 45 o.x = "42"; 46 inc2(o); 47 assertEquals(43, o.x); 48 49 var s = max_smi - 10; 50 o.x = s; 51 for(var i = 0; i < 20; i++) { 52 inc2(o); 53 if (i == 4) { 54 %OptimizeFunctionOnNextCall(inc2); 55 } 56 } 57 assertEquals(max_smi + 10, o.x); 58 59 60 // Test deopt with count operation on keyed property. 61 function inc3(a, b) { a[b]++; } 62 63 o = ["42"]; 64 inc3(o, 0); 65 assertEquals(43, o[0]); 66 67 var s = max_smi - 10; 68 o[0] = s; 69 for(var i = 0; i < 20; i++) { 70 inc3(o, 0); 71 if (i == 4) { 72 %OptimizeFunctionOnNextCall(inc3); 73 } 74 } 75 assertEquals(max_smi + 10, o[0]); 76 77 inc3(o,"0"); 78 79 assertEquals(max_smi + 11, o[0]); 80 81 // Test bailout when accessing a non-existing array element. 82 o[0] = 0; 83 for(var i = 0; i < 5; i++) { 84 inc3(o, 0); 85 } 86 %OptimizeFunctionOnNextCall(inc3); 87 inc3(o, 0); 88 inc3(o, 1); 89 90 // Test bailout with count operation in a value context. 91 function inc4(x,y) { return (x++) + y; } 92 for (var i = 0; i < 5; ++i) assertEquals(3, inc4(2, 1)); 93 %OptimizeFunctionOnNextCall(inc4); 94 inc4(2, 1); 95 assertEquals(3.1, inc4(2, 1.1)); 96 97 function inc5(x,y) { return (++x) + y; } 98 for (var i = 0; i < 5; ++i) assertEquals(4, inc5(2, 1)); 99 %OptimizeFunctionOnNextCall(inc5); 100 assertEquals(4, inc5(2, 1)); 101 assertEquals(4.1, inc5(2, 1.1)); 102 assertEquals(4.1, inc5(2.1, 1)); 103 104 function inc6(o,y) { return (o.x++) + y; } 105 o = {x:0}; 106 for (var i = 0; i < 5; ++i) { 107 o.x = 42; 108 assertEquals(43, inc6(o, 1)); 109 } 110 %OptimizeFunctionOnNextCall(inc6); 111 o.x = 42; 112 assertEquals(43, inc6(o, 1)); 113 o.x = 42; 114 assertEquals(43.1, inc6(o, 1.1)); 115 o.x = 42.1; 116 assertEquals(43.1, inc6(o, 1)); 117 118 function inc7(o,y) { return (++o.x) + y; } 119 o = {x:0}; 120 for (var i = 0; i < 5; ++i) { 121 o.x = 42; 122 assertEquals(44, inc7(o, 1)); 123 } 124 %OptimizeFunctionOnNextCall(inc7); 125 o.x = 42; 126 assertEquals(44, inc7(o, 1)); 127 o.x = 42; 128 assertEquals(44.1, inc7(o, 1.1)); 129 o.x = 42.1; 130 assertEquals(44.1, inc7(o, 1)); 131 132 function inc8(o,y) { return (o[0]++) + y; } 133 var q = [0]; 134 for (var i = 0; i < 5; ++i) { 135 q[0] = 42; 136 assertEquals(43, inc8(q, 1)); 137 } 138 %OptimizeFunctionOnNextCall(inc8); 139 q[0] = 42; 140 assertEquals(43, inc8(q, 1)); 141 q[0] = 42; 142 assertEquals(43.1, inc8(q, 1.1)); 143 q[0] = 42.1; 144 assertEquals(43.1, inc8(q, 1)); 145 146 function inc9(o,y) { return (++o[0]) + y; } 147 q = [0]; 148 for (var i = 0; i < 5; ++i) { 149 q[0] = 42; 150 assertEquals(44, inc9(q, 1)); 151 } 152 %OptimizeFunctionOnNextCall(inc9); 153 q[0] = 42; 154 assertEquals(44, inc9(q, 1)); 155 q[0] = 42; 156 assertEquals(44.1, inc9(q, 1.1)); 157 q[0] = 42.1; 158 assertEquals(44.1, inc9(q, 1)); 159 160 // Test deopt because of a failed map check. 161 function inc10(p) { return p.x++ } 162 var g1 = {x:0}; 163 var g2 = {y:0, x:42} 164 for (var i = 0; i < 5; ++i) { 165 g1.x = 42; 166 assertEquals(42, inc10(g1)); 167 assertEquals(43, g1.x); 168 } 169 %OptimizeFunctionOnNextCall(inc10); 170 g1.x = 42; 171 assertEquals(42, inc10(g1)); 172 assertEquals(43, g1.x); 173 assertEquals(42, inc10(g2)); 174 assertEquals(43, g2.x); 175 176 // Test deoptimization with postfix operation in a value context. 177 function inc11(a) { return a[this.x++]; } 178 var g3 = {x:null, f:inc11}; 179 var g4 = [42]; 180 assertEquals(42, g3.f(g4)); 181