1 // Copyright 2012 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 --smi-only-arrays 29 30 // Test element kind of objects. 31 // Since --smi-only-arrays affects builtins, its default setting at compile time 32 // sticks if built with snapshot. If --smi-only-arrays is deactivated by 33 // default, only a no-snapshot build actually has smi-only arrays enabled in 34 // this test case. Depending on whether smi-only arrays are actually enabled, 35 // this test takes the appropriate code path to check smi-only arrays. 36 37 support_smi_only_arrays = %HasFastSmiElements([1,2,3,4,5,6,7,8,9,10]); 38 39 if (support_smi_only_arrays) { 40 print("Tests include smi-only arrays."); 41 } else { 42 print("Tests do NOT include smi-only arrays."); 43 } 44 45 // IC and Crankshaft support for smi-only elements in dynamic array literals. 46 function get(foo) { return foo; } // Used to generate dynamic values. 47 48 function array_natives_test() { 49 50 // Ensure small array literals start in specific element kind mode. 51 assertTrue(%HasFastSmiElements([])); 52 assertTrue(%HasFastSmiElements([1])); 53 assertTrue(%HasFastSmiElements([1,2])); 54 assertTrue(%HasFastDoubleElements([1.1])); 55 assertTrue(%HasFastDoubleElements([1.1,2])); 56 57 // This code exists to eliminate the learning influence of AllocationSites 58 // on the following tests. 59 var __sequence = 0; 60 function make_array_string(literal) { 61 this.__sequence = this.__sequence + 1; 62 return "/* " + this.__sequence + " */ " + literal; 63 } 64 function make_array(literal) { 65 return eval(make_array_string(literal)); 66 } 67 68 // Push 69 var a0 = make_array("[1, 2, 3]"); 70 assertTrue(%HasFastSmiElements(a0)); 71 a0.push(4); 72 assertTrue(%HasFastSmiElements(a0)); 73 a0.push(1.3); 74 assertTrue(%HasFastDoubleElements(a0)); 75 a0.push(1.5); 76 assertTrue(%HasFastDoubleElements(a0)); 77 a0.push({}); 78 assertTrue(%HasFastObjectElements(a0)); 79 a0.push({}); 80 assertTrue(%HasFastObjectElements(a0)); 81 assertEquals([1,2,3,4,1.3,1.5,{},{}], a0); 82 83 // Concat 84 var a1; 85 a1 = [1,2,3].concat([]); 86 assertTrue(%HasFastSmiElements(a1)); 87 assertEquals([1,2,3], a1); 88 a1 = [1,2,3].concat([4,5,6]); 89 assertTrue(%HasFastSmiElements(a1)); 90 assertEquals([1,2,3,4,5,6], a1); 91 a1 = [1,2,3].concat([4,5,6], [7,8,9]); 92 assertTrue(%HasFastSmiElements(a1)); 93 assertEquals([1,2,3,4,5,6,7,8,9], a1); 94 a1 = [1.1,2,3].concat([]); 95 assertTrue(%HasFastDoubleElements(a1)); 96 assertEquals([1.1,2,3], a1); 97 a1 = [1,2,3].concat([1.1, 2]); 98 assertTrue(%HasFastDoubleElements(a1)); 99 assertEquals([1,2,3,1.1,2], a1); 100 a1 = [1.1,2,3].concat([1, 2]); 101 assertTrue(%HasFastDoubleElements(a1)); 102 assertEquals([1.1,2,3,1,2], a1); 103 a1 = [1.1,2,3].concat([1.2, 2]); 104 assertTrue(%HasFastDoubleElements(a1)); 105 assertEquals([1.1,2,3,1.2,2], a1); 106 107 a1 = [1,2,3].concat([{}]); 108 assertTrue(%HasFastObjectElements(a1)); 109 assertEquals([1,2,3,{}], a1); 110 a1 = [1.1,2,3].concat([{}]); 111 assertTrue(%HasFastObjectElements(a1)); 112 assertEquals([1.1,2,3,{}], a1); 113 a1 = [{}].concat([1,2,3]); 114 assertTrue(%HasFastObjectElements(a1)); 115 assertEquals([{},1,2,3], a1); 116 a1 = [{}].concat([1.1,2,3]); 117 assertTrue(%HasFastObjectElements(a1)); 118 assertEquals([{},1.1,2,3], a1); 119 120 // Slice 121 var a2 = [1,2,3]; 122 assertTrue(%HasFastSmiElements(a2.slice())); 123 assertTrue(%HasFastSmiElements(a2.slice(1))); 124 assertTrue(%HasFastSmiElements(a2.slice(1, 2))); 125 assertEquals([1,2,3], a2.slice()); 126 assertEquals([2,3], a2.slice(1)); 127 assertEquals([2], a2.slice(1,2)); 128 a2 = [1.1,2,3]; 129 assertTrue(%HasFastDoubleElements(a2.slice())); 130 assertTrue(%HasFastDoubleElements(a2.slice(1))); 131 assertTrue(%HasFastDoubleElements(a2.slice(1, 2))); 132 assertEquals([1.1,2,3], a2.slice()); 133 assertEquals([2,3], a2.slice(1)); 134 assertEquals([2], a2.slice(1,2)); 135 a2 = [{},2,3]; 136 assertTrue(%HasFastObjectElements(a2.slice())); 137 assertTrue(%HasFastObjectElements(a2.slice(1))); 138 assertTrue(%HasFastObjectElements(a2.slice(1, 2))); 139 assertEquals([{},2,3], a2.slice()); 140 assertEquals([2,3], a2.slice(1)); 141 assertEquals([2], a2.slice(1,2)); 142 143 // Splice 144 var a3 = [1,2,3]; 145 var a3r; 146 a3r = a3.splice(0, 0); 147 assertTrue(%HasFastSmiElements(a3r)); 148 assertTrue(%HasFastSmiElements(a3)); 149 assertEquals([], a3r); 150 assertEquals([1, 2, 3], a3); 151 a3 = [1,2,3]; 152 a3r = a3.splice(0, 1); 153 assertTrue(%HasFastSmiElements(a3r)); 154 assertTrue(%HasFastSmiElements(a3)); 155 assertEquals([1], a3r); 156 assertEquals([2, 3], a3); 157 a3 = [1,2,3]; 158 a3r = a3.splice(0, 0, 2); 159 assertTrue(%HasFastSmiElements(a3r)); 160 assertTrue(%HasFastSmiElements(a3)); 161 assertEquals([], a3r); 162 assertEquals([2, 1, 2, 3], a3); 163 a3 = [1,2,3]; 164 a3r = a3.splice(0, 1, 2); 165 assertTrue(%HasFastSmiElements(a3r)); 166 assertTrue(%HasFastSmiElements(a3)); 167 assertEquals([1], a3r); 168 assertEquals([2, 2, 3], a3); 169 170 a3 = [1.1,2,3]; 171 a3r = a3.splice(0, 0); 172 assertTrue(%HasFastDoubleElements(a3r)); 173 assertTrue(%HasFastDoubleElements(a3)); 174 assertEquals([], a3r); 175 assertEquals([1.1, 2, 3], a3); 176 a3 = [1.1,2,3]; 177 a3r = a3.splice(0, 1); 178 assertTrue(%HasFastDoubleElements(a3r)); 179 assertTrue(%HasFastDoubleElements(a3)); 180 assertEquals([1.1], a3r); 181 assertEquals([2, 3], a3); 182 a3 = [1.1,2,3]; 183 a3r = a3.splice(0, 0, 2); 184 // Commented out since handled in js, which takes the best fit. 185 // assertTrue(%HasFastDoubleElements(a3r)); 186 assertTrue(%HasFastSmiElements(a3r)); 187 assertTrue(%HasFastDoubleElements(a3)); 188 assertEquals([], a3r); 189 assertEquals([2, 1.1, 2, 3], a3); 190 a3 = [1.1,2,3]; 191 a3r = a3.splice(0, 1, 2); 192 assertTrue(%HasFastDoubleElements(a3r)); 193 assertTrue(%HasFastDoubleElements(a3)); 194 assertEquals([1.1], a3r); 195 assertEquals([2, 2, 3], a3); 196 a3 = [1.1,2,3]; 197 a3r = a3.splice(0, 0, 2.1); 198 // Commented out since handled in js, which takes the best fit. 199 // assertTrue(%HasFastDoubleElements(a3r)); 200 assertTrue(%HasFastSmiElements(a3r)); 201 assertTrue(%HasFastDoubleElements(a3)); 202 assertEquals([], a3r); 203 assertEquals([2.1, 1.1, 2, 3], a3); 204 a3 = [1.1,2,3]; 205 a3r = a3.splice(0, 1, 2.2); 206 assertTrue(%HasFastDoubleElements(a3r)); 207 assertTrue(%HasFastDoubleElements(a3)); 208 assertEquals([1.1], a3r); 209 assertEquals([2.2, 2, 3], a3); 210 a3 = [1,2,3]; 211 a3r = a3.splice(0, 0, 2.1); 212 // Commented out since handled in js, which takes the best fit. 213 // assertTrue(%HasFastDoubleElements(a3r)); 214 assertTrue(%HasFastSmiElements(a3r)); 215 assertTrue(%HasFastDoubleElements(a3)); 216 assertEquals([], a3r); 217 assertEquals([2.1, 1, 2, 3], a3); 218 a3 = [1,2,3]; 219 a3r = a3.splice(0, 1, 2.2); 220 assertTrue(%HasFastDoubleElements(a3r)); 221 assertTrue(%HasFastDoubleElements(a3)); 222 assertEquals([1], a3r); 223 assertEquals([2.2, 2, 3], a3); 224 225 a3 = [{},2,3]; 226 a3r = a3.splice(0, 0); 227 assertTrue(%HasFastObjectElements(a3r)); 228 assertTrue(%HasFastObjectElements(a3)); 229 assertEquals([], a3r); 230 assertEquals([{}, 2, 3], a3); 231 a3 = [1,2,{}]; 232 a3r = a3.splice(0, 1); 233 assertTrue(%HasFastObjectElements(a3r)); 234 assertTrue(%HasFastObjectElements(a3)); 235 assertEquals([1], a3r); 236 assertEquals([2, {}], a3); 237 a3 = [1,2,3]; 238 a3r = a3.splice(0, 0, {}); 239 assertTrue(%HasFastObjectElements(a3r)); 240 assertTrue(%HasFastObjectElements(a3)); 241 assertEquals([], a3r); 242 assertEquals([{}, 1, 2, 3], a3); 243 a3 = [1,2,3]; 244 a3r = a3.splice(0, 1, {}); 245 assertTrue(%HasFastObjectElements(a3r)); 246 assertTrue(%HasFastObjectElements(a3)); 247 assertEquals([1], a3r); 248 assertEquals([{}, 2, 3], a3); 249 250 a3 = [1.1,2,3]; 251 a3r = a3.splice(0, 0, {}); 252 assertTrue(%HasFastObjectElements(a3r)); 253 assertTrue(%HasFastObjectElements(a3)); 254 assertEquals([], a3r); 255 assertEquals([{}, 1.1, 2, 3], a3); 256 a3 = [1.1,2,3]; 257 a3r = a3.splice(0, 1, {}); 258 assertTrue(%HasFastObjectElements(a3r)); 259 assertTrue(%HasFastObjectElements(a3)); 260 assertEquals([1.1], a3r); 261 assertEquals([{}, 2, 3], a3); 262 263 // Pop 264 var a4 = [1,2,3]; 265 assertEquals(3, a4.pop()); 266 assertTrue(%HasFastSmiElements(a4)); 267 a4 = [1.1,2,3]; 268 assertEquals(3, a4.pop()); 269 assertTrue(%HasFastDoubleElements(a4)); 270 a4 = [{},2,3]; 271 assertEquals(3, a4.pop()); 272 assertTrue(%HasFastObjectElements(a4)); 273 274 // Shift 275 var a4 = [1,2,3]; 276 assertEquals(1, a4.shift()); 277 assertTrue(%HasFastSmiElements(a4)); 278 a4 = [1.1,2,3]; 279 assertEquals(1.1, a4.shift()); 280 assertTrue(%HasFastDoubleElements(a4)); 281 a4 = [{},2,3]; 282 assertEquals({}, a4.shift()); 283 assertTrue(%HasFastObjectElements(a4)); 284 285 // Unshift 286 var a4 = [1,2,3]; 287 a4.unshift(1); 288 assertTrue(%HasFastSmiElements(a4)); 289 assertEquals([1,1,2,3], a4); 290 a4 = [1,2,3]; 291 a4.unshift(1.1); 292 // TODO(verwaest): We'll want to support double unshifting as well. 293 // assertTrue(%HasFastDoubleElements(a4)); 294 assertTrue(%HasFastObjectElements(a4)); 295 assertEquals([1.1,1,2,3], a4); 296 a4 = [1.1,2,3]; 297 a4.unshift(1); 298 // assertTrue(%HasFastDoubleElements(a4)); 299 assertTrue(%HasFastObjectElements(a4)); 300 assertEquals([1,1.1,2,3], a4); 301 a4 = [{},2,3]; 302 a4.unshift(1); 303 assertTrue(%HasFastObjectElements(a4)); 304 assertEquals([1,{},2,3], a4); 305 a4 = [{},2,3]; 306 a4.unshift(1.1); 307 assertTrue(%HasFastObjectElements(a4)); 308 assertEquals([1.1,{},2,3], a4); 309 } 310 311 if (support_smi_only_arrays) { 312 for (var i = 0; i < 3; i++) { 313 array_natives_test(); 314 } 315 %OptimizeFunctionOnNextCall(array_natives_test); 316 array_natives_test(); 317 } 318