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 --expose-gc 29 30 // Test element kind of objects. 31 // Since --smi-only-arrays affects builtins, its default setting at compile 32 // time sticks if built with snapshot. If --smi-only-arrays is deactivated 33 // by default, only a no-snapshot build actually has smi-only arrays enabled 34 // in this test case. Depending on whether smi-only arrays are actually 35 // enabled, 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_literal_test() { 49 var a0 = [1, 2, 3]; 50 assertTrue(%HasFastSmiElements(a0)); 51 var a1 = [get(1), get(2), get(3)]; 52 assertTrue(%HasFastSmiElements(a1)); 53 54 var b0 = [1, 2, get("three")]; 55 assertTrue(%HasFastObjectElements(b0)); 56 var b1 = [get(1), get(2), get("three")]; 57 assertTrue(%HasFastObjectElements(b1)); 58 59 var c0 = [1, 2, get(3.5)]; 60 assertTrue(%HasFastDoubleElements(c0)); 61 assertEquals(3.5, c0[2]); 62 assertEquals(2, c0[1]); 63 assertEquals(1, c0[0]); 64 65 var c1 = [1, 2, 3.5]; 66 assertTrue(%HasFastDoubleElements(c1)); 67 assertEquals(3.5, c1[2]); 68 assertEquals(2, c1[1]); 69 assertEquals(1, c1[0]); 70 71 var c2 = [get(1), get(2), get(3.5)]; 72 assertTrue(%HasFastDoubleElements(c2)); 73 assertEquals(3.5, c2[2]); 74 assertEquals(2, c2[1]); 75 assertEquals(1, c2[0]); 76 77 var object = new Object(); 78 var d0 = [1, 2, object]; 79 assertTrue(%HasFastObjectElements(d0)); 80 assertEquals(object, d0[2]); 81 assertEquals(2, d0[1]); 82 assertEquals(1, d0[0]); 83 84 var e0 = [1, 2, 3.5]; 85 assertTrue(%HasFastDoubleElements(e0)); 86 assertEquals(3.5, e0[2]); 87 assertEquals(2, e0[1]); 88 assertEquals(1, e0[0]); 89 90 var f0 = [1, 2, [1, 2]]; 91 assertTrue(%HasFastObjectElements(f0)); 92 assertEquals([1,2], f0[2]); 93 assertEquals(2, f0[1]); 94 assertEquals(1, f0[0]); 95 } 96 97 if (support_smi_only_arrays) { 98 for (var i = 0; i < 3; i++) { 99 array_literal_test(); 100 } 101 %OptimizeFunctionOnNextCall(array_literal_test); 102 array_literal_test(); 103 104 function test_large_literal() { 105 106 function d() { 107 gc(); 108 return 2.5; 109 } 110 111 function o() { 112 gc(); 113 return new Object(); 114 } 115 116 large = 117 [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ]; 118 assertFalse(%HasDictionaryElements(large)); 119 assertFalse(%HasFastSmiElements(large)); 120 assertFalse(%HasFastDoubleElements(large)); 121 assertTrue(%HasFastObjectElements(large)); 122 assertEquals(large, 123 [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 124 new Object(), new Object(), new Object(), new Object()]); 125 } 126 127 for (var i = 0; i < 3; i++) { 128 test_large_literal(); 129 } 130 %OptimizeFunctionOnNextCall(test_large_literal); 131 test_large_literal(); 132 133 function deopt_array(use_literal) { 134 if (use_literal) { 135 return [.5, 3, 4]; 136 } else { 137 return new Array(); 138 } 139 } 140 141 deopt_array(false); 142 deopt_array(false); 143 deopt_array(false); 144 %OptimizeFunctionOnNextCall(deopt_array); 145 var array = deopt_array(false); 146 assertOptimized(deopt_array); 147 deopt_array(true); 148 assertOptimized(deopt_array); 149 array = deopt_array(false); 150 assertOptimized(deopt_array); 151 152 // Check that unexpected changes in the objects stored into the boilerplate 153 // also force a deopt. 154 function deopt_array_literal_all_smis(a) { 155 return [0, 1, a]; 156 } 157 158 deopt_array_literal_all_smis(2); 159 deopt_array_literal_all_smis(3); 160 deopt_array_literal_all_smis(4); 161 array = deopt_array_literal_all_smis(4); 162 assertEquals(0, array[0]); 163 assertEquals(1, array[1]); 164 assertEquals(4, array[2]); 165 %OptimizeFunctionOnNextCall(deopt_array_literal_all_smis); 166 array = deopt_array_literal_all_smis(5); 167 array = deopt_array_literal_all_smis(6); 168 assertOptimized(deopt_array_literal_all_smis); 169 assertEquals(0, array[0]); 170 assertEquals(1, array[1]); 171 assertEquals(6, array[2]); 172 173 array = deopt_array_literal_all_smis(.5); 174 assertUnoptimized(deopt_array_literal_all_smis); 175 assertEquals(0, array[0]); 176 assertEquals(1, array[1]); 177 assertEquals(.5, array[2]); 178 179 function deopt_array_literal_all_doubles(a) { 180 return [0.5, 1, a]; 181 } 182 183 deopt_array_literal_all_doubles(.5); 184 deopt_array_literal_all_doubles(.5); 185 deopt_array_literal_all_doubles(.5); 186 array = deopt_array_literal_all_doubles(0.5); 187 assertEquals(0.5, array[0]); 188 assertEquals(1, array[1]); 189 assertEquals(0.5, array[2]); 190 %OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles); 191 array = deopt_array_literal_all_doubles(5); 192 array = deopt_array_literal_all_doubles(6); 193 assertOptimized(deopt_array_literal_all_doubles); 194 assertEquals(0.5, array[0]); 195 assertEquals(1, array[1]); 196 assertEquals(6, array[2]); 197 198 var foo = new Object(); 199 array = deopt_array_literal_all_doubles(foo); 200 assertUnoptimized(deopt_array_literal_all_doubles); 201 assertEquals(0.5, array[0]); 202 assertEquals(1, array[1]); 203 assertEquals(foo, array[2]); 204 } 205 206 (function literals_after_osr() { 207 var color = [0]; 208 // Trigger OSR, if optimization is not disabled. 209 if (%GetOptimizationStatus(literals_after_osr) != 4) { 210 while (%GetOptimizationCount(literals_after_osr) == 0) {} 211 } 212 return [color[0]]; 213 })(); 214