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 assign1(x) { x += 1; o.x = x; } 35 assign1(max_smi); 36 assertEquals(max_smi + 1, o.x); 37 38 assign1(1.1); 39 assertEquals(2.1, o.x); 40 41 42 // Test deopt with count operation on named property. 43 function assign2(p) { p.x += 1 } 44 45 o.x = "42"; 46 assign2(o); 47 assertEquals("421", o.x); 48 49 var s = max_smi - 10; 50 o.x = s; 51 for(var i = 0; i < 20; i++) { 52 assign2(o); 53 if (i == 4) { 54 %OptimizeFunctionOnNextCall(assign2); 55 } 56 } 57 assertEquals(max_smi + 10, o.x); 58 59 60 // Test deopt with count operation on keyed property. 61 function assign3(a, b) { a[b] += 1; } 62 63 o = ["42"]; 64 assign3(o, 0); 65 assertEquals("421", o[0]); 66 67 var s = max_smi - 10; 68 o[0] = s; 69 for(var i = 0; i < 20; i++) { 70 assign3(o, 0); 71 if (i == 4) { 72 %OptimizeFunctionOnNextCall(assign3); 73 } 74 } 75 assertEquals(max_smi + 10, o[0]); 76 77 assign3(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 assign3(o, 0); 85 } 86 %OptimizeFunctionOnNextCall(assign3); 87 assign3(o, 0); 88 assign3(o, 1); 89 90 // Test bailout with count operation in a value context. 91 function assign5(x,y) { return (x += 1) + y; } 92 for (var i = 0; i < 5; ++i) assertEquals(4, assign5(2, 1)); 93 %OptimizeFunctionOnNextCall(assign5); 94 assertEquals(4, assign5(2, 1)); 95 96 assertEquals(4.1, assign5(2, 1.1)); 97 assertEquals(4.1, assign5(2.1, 1)); 98 99 function assign7(o,y) { return (o.x += 1) + y; } 100 o = {x:0}; 101 for (var i = 0; i < 5; ++i) { 102 o.x = 42; 103 assertEquals(44, assign7(o, 1)); 104 } 105 %OptimizeFunctionOnNextCall(assign7); 106 o.x = 42; 107 assertEquals(44, assign7(o, 1)); 108 109 o.x = 42; 110 assertEquals(44.1, assign7(o, 1.1)); 111 o.x = 42.1; 112 assertEquals(44.1, assign7(o, 1)); 113 114 function assign9(o,y) { return (o[0] += 1) + y; } 115 q = [0]; 116 for (var i = 0; i < 5; ++i) { 117 q[0] = 42; 118 assertEquals(44, assign9(q, 1)); 119 } 120 %OptimizeFunctionOnNextCall(assign9); 121 q[0] = 42; 122 assertEquals(44, assign9(q, 1)); 123 124 q[0] = 42; 125 assertEquals(44.1, assign9(q, 1.1)); 126 q[0] = 42.1; 127 assertEquals(44.1, assign9(q, 1)); 128 129 // Test deopt because of a failed map check on the load. 130 function assign10(p) { return p.x += 1 } 131 var g1 = {x:0}; 132 var g2 = {y:0, x:42}; 133 for (var i = 0; i < 5; ++i) { 134 g1.x = 42; 135 assertEquals(43, assign10(g1)); 136 assertEquals(43, g1.x); 137 } 138 %OptimizeFunctionOnNextCall(assign10); 139 g1.x = 42; 140 assertEquals(43, assign10(g1)); 141 assertEquals(43, g1.x); 142 143 assertEquals(43, assign10(g2)); 144 assertEquals(43, g2.x); 145 146 // Test deopt because of a failed map check on the store. 147 // The binary operation changes the map as a side effect. 148 o = {x:0}; 149 var g3 = { valueOf: function() { o.y = "bar"; return 42; }}; 150 function assign11(p) { return p.x += 1; } 151 152 for (var i = 0; i < 5; i++) { 153 o.x = "a"; 154 assign11(o); 155 } 156 %OptimizeFunctionOnNextCall(assign11); 157 o.x = "a"; 158 assign11(o); 159 160 assertEquals("a11", assign11(o)); 161 o.x = g3; 162 assertEquals(43, assign11(o)); 163 assertEquals("bar", o.y); 164 165 o = [0]; 166 var g4 = { valueOf: function() { o.y = "bar"; return 42; }}; 167 function assign12(p) { return p[0] += 1; } 168 169 for (var i = 0; i < 5; i++) { 170 o[0] = "a"; 171 assign12(o); 172 } 173 %OptimizeFunctionOnNextCall(assign12); 174 o[0] = "a"; 175 assign12(o); 176 177 assertEquals("a11", assign12(o)); 178 o[0] = g4; 179 assertEquals(43, assign12(o)); 180 assertEquals("bar", o.y); 181