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%NeverOptimizeFunction(test); 31function test() { 32 33 var iteration_count = 1; 34 35 function transition1(a, i, v) { 36 a[i] = v; 37 } 38 39 // 40 // Test PACKED SMI -> PACKED DOUBLE 41 // 42 43 var a1 = [0, 1, 2, 3, 4]; 44 transition1(a1, 0, 2.5); 45 var a2 = [0, 1, 2, 3, 4]; 46 transition1(a2, 0, 2.5); 47 assertFalse(%HasFastHoleyElements(a2)); 48 %OptimizeFunctionOnNextCall(transition1); 49 50 var a3 = [0, 1, 2, 3, 4]; 51 assertTrue(%HasFastSmiElements(a3)); 52 transition1(a3, 0, 2.5); 53 assertFalse(%HasFastHoleyElements(a3)); 54 assertEquals(4, a3[4]); 55 assertEquals(2.5, a3[0]); 56 57 // Test handling of hole. 58 var a4 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 59 a4.length = 7; 60 assertTrue(%HasFastSmiElements(a4)); 61 transition1(a4, 0, 2.5); 62 assertFalse(%HasFastHoleyElements(a4)); 63 assertEquals(2.5, a4[0]); 64 assertEquals(undefined, a4[8]); 65 66 // Large array should deopt to runtimea 67 for (j = 0; j < iteration_count; ++j) { 68 a5 = new Array(); 69 for (i = 0; i < 0x40000; ++i) { 70 a5[i] = 0; 71 } 72 assertTrue(%HasFastSmiElements(a5) || %HasFastDoubleElements(a5)); 73 transition1(a5, 0, 2.5); 74 assertEquals(2.5, a5[0]); 75 } 76 77 // 78 // Test HOLEY SMI -> HOLEY DOUBLE 79 // 80 81 function transition2(a, i, v) { 82 a[i] = v; 83 } 84 85 var b1 = [0, 1, 2, , 4]; 86 transition2(b1, 0, 2.5); 87 var b2 = [0, 1, 2, , 4]; 88 transition2(b2, 0, 2.5); 89 assertTrue(%HasFastHoleyElements(b2)); 90 %OptimizeFunctionOnNextCall(transition2); 91 92 var b3 = [0, 1, 2, , 4]; 93 assertTrue(%HasFastSmiElements(b3)); 94 assertTrue(%HasFastHoleyElements(b3)); 95 transition2(b3, 0, 2.5); 96 assertTrue(%HasFastHoleyElements(b3)); 97 assertEquals(4, b3[4]); 98 assertEquals(2.5, b3[0]); 99 100 // Large array should deopt to runtime 101 for (j = 0; j < iteration_count; ++j) { 102 b4 = [0, ,0]; 103 for (i = 3; i < 0x40000; ++i) { 104 b4[i] = 0; 105 } 106 assertTrue(%HasFastSmiElements(b4)); 107 transition2(b4, 0, 2.5); 108 assertEquals(2.5, b4[0]); 109 } 110 111 // 112 // Test PACKED DOUBLE -> PACKED OBJECT 113 // 114 115 function transition3(a, i, v) { 116 a[i] = v; 117 } 118 119 var c1 = [0, 1, 2, 3.5, 4]; 120 transition3(c1, 0, new Object()); 121 var c2 = [0, 1, 2, 3.5, 4]; 122 transition3(c2, 0, new Object()); 123 assertTrue(%HasFastObjectElements(c2)); 124 assertTrue(!%HasFastHoleyElements(c2)); 125 %OptimizeFunctionOnNextCall(transition3); 126 127 var c3 = [0, 1, 2, 3.5, 4]; 128 assertTrue(%HasFastDoubleElements(c3)); 129 assertTrue(!%HasFastHoleyElements(c3)); 130 transition3(c3, 0, new Array()); 131 assertTrue(!%HasFastHoleyElements(c3)); 132 assertTrue(%HasFastObjectElements(c3)); 133 assertEquals(4, c3[4]); 134 assertEquals(0, c3[0].length); 135 136 // Large array under the deopt threshold should be able to trigger GC without 137 // causing crashes. 138 for (j = 0; j < iteration_count; ++j) { 139 c4 = [0, 2.5, 0]; 140 for (i = 3; i < 0xa000; ++i) { 141 c4[i] = 0; 142 } 143 assertTrue(%HasFastDoubleElements(c4)); 144 assertTrue(!%HasFastHoleyElements(c4)); 145 transition3(c4, 0, new Array(5)); 146 assertTrue(!%HasFastHoleyElements(c4)); 147 assertTrue(%HasFastObjectElements(c4)); 148 assertEquals(5, c4[0].length); 149 } 150 151 // Large array should deopt to runtime 152 for (j = 0; j < iteration_count; ++j) { 153 c5 = [0, 2.5, 0]; 154 for (i = 3; i < 0x40000; ++i) { 155 c5[i] = 0; 156 } 157 assertTrue(%HasFastDoubleElements(c5)); 158 assertTrue(!%HasFastHoleyElements(c5)); 159 transition3(c5, 0, new Array(5)); 160 assertTrue(!%HasFastHoleyElements(c5)); 161 assertTrue(%HasFastObjectElements(c5)); 162 assertEquals(5, c5[0].length); 163 } 164 165 // 166 // Test HOLEY DOUBLE -> HOLEY OBJECT 167 // 168 169 function transition4(a, i, v) { 170 a[i] = v; 171 } 172 173 var d1 = [0, 1, , 3.5, 4]; 174 transition4(d1, 0, new Object()); 175 var d2 = [0, 1, , 3.5, 4]; 176 transition4(d2, 0, new Object()); 177 assertTrue(%HasFastObjectElements(d2)); 178 assertTrue(%HasFastHoleyElements(d2)); 179 %OptimizeFunctionOnNextCall(transition4); 180 181 var d3 = [0, 1, , 3.5, 4]; 182 assertTrue(%HasFastDoubleElements(d3)); 183 assertTrue(%HasFastHoleyElements(d3)); 184 transition4(d3, 0, new Array()); 185 assertTrue(%HasFastHoleyElements(d3)); 186 assertTrue(%HasFastObjectElements(d3)); 187 assertEquals(4, d3[4]); 188 assertEquals(0, d3[0].length); 189 190 // Large array under the deopt threshold should be able to trigger GC without 191 // causing crashes. 192 for (j = 0; j < iteration_count; ++j) { 193 d4 = [, 2.5, ,]; 194 for (i = 3; i < 0xa000; ++i) { 195 d4[i] = 0; 196 } 197 assertTrue(%HasFastDoubleElements(d4)); 198 assertTrue(%HasFastHoleyElements(d4)); 199 transition4(d4, 0, new Array(5)); 200 assertTrue(%HasFastHoleyElements(d4)); 201 assertTrue(%HasFastObjectElements(d4)); 202 assertEquals(5, d4[0].length); 203 assertEquals(undefined, d4[2]); 204 } 205 206 // Large array should deopt to runtime 207 for (j = 0; j < iteration_count; ++j) { 208 d5 = [, 2.5, ,]; 209 for (i = 3; i < 0x40000; ++i) { 210 d5[i] = 0; 211 } 212 assertTrue(%HasFastDoubleElements(d5)); 213 assertTrue(%HasFastHoleyElements(d5)); 214 transition4(d5, 0, new Array(5)); 215 assertTrue(%HasFastHoleyElements(d5)); 216 assertTrue(%HasFastObjectElements(d5)); 217 assertEquals(5, d5[0].length); 218 assertEquals(undefined, d5[2]); 219 } 220 221} 222test(); 223