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// Flags: --notrack-allocation-sites 30 31// Test element kind of objects. 32// Since --smi-only-arrays affects builtins, its default setting at compile time 33// sticks if built with snapshot. If --smi-only-arrays is deactivated by 34// default, only a no-snapshot build actually has smi-only arrays enabled in 35// this test case. Depending on whether smi-only arrays are actually enabled, 36// this test takes the appropriate code path to check smi-only arrays. 37 38support_smi_only_arrays = %HasFastSmiElements([1,2,3,4,5,6,7,8,9,10]); 39 40if (support_smi_only_arrays) { 41 print("Tests include smi-only arrays."); 42} else { 43 print("Tests do NOT include smi-only arrays."); 44} 45 46// IC and Crankshaft support for smi-only elements in dynamic array literals. 47function get(foo) { return foo; } // Used to generate dynamic values. 48 49function array_natives_test() { 50 51 // Ensure small array literals start in specific element kind mode. 52 assertTrue(%HasFastSmiElements([])); 53 assertTrue(%HasFastSmiElements([1])); 54 assertTrue(%HasFastSmiElements([1,2])); 55 assertTrue(%HasFastDoubleElements([1.1])); 56 assertTrue(%HasFastDoubleElements([1.1,2])); 57 58 // Push 59 var a0 = [1, 2, 3]; 60 if (%HasFastSmiElements(a0)) { 61 assertTrue(%HasFastSmiElements(a0)); 62 a0.push(4); 63 assertTrue(%HasFastSmiElements(a0)); 64 a0.push(1.3); 65 assertTrue(%HasFastDoubleElements(a0)); 66 a0.push(1.5); 67 assertTrue(%HasFastDoubleElements(a0)); 68 a0.push({}); 69 assertTrue(%HasFastObjectElements(a0)); 70 a0.push({}); 71 assertTrue(%HasFastObjectElements(a0)); 72 } else { 73 assertTrue(%HasFastObjectElements(a0)); 74 a0.push(4); 75 a0.push(1.3); 76 a0.push(1.5); 77 a0.push({}); 78 a0.push({}); 79 assertTrue(%HasFastObjectElements(a0)); 80 } 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 311if (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