Home | History | Annotate | Download | only in mjsunit
      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 --expose-gc
     29 
     30 // IC and Crankshaft support for smi-only elements in dynamic array literals.
     31 function get(foo) { return foo; }  // Used to generate dynamic values.
     32 
     33 function array_literal_test() {
     34   var a0 = [1, 2, 3];
     35   assertTrue(%HasFastSmiElements(a0));
     36   var a1 = [get(1), get(2), get(3)];
     37   assertTrue(%HasFastSmiElements(a1));
     38 
     39   var b0 = [1, 2, get("three")];
     40   assertTrue(%HasFastObjectElements(b0));
     41   var b1 = [get(1), get(2), get("three")];
     42   assertTrue(%HasFastObjectElements(b1));
     43 
     44   var c0 = [1, 2, get(3.5)];
     45   assertTrue(%HasFastDoubleElements(c0));
     46   assertEquals(3.5, c0[2]);
     47   assertEquals(2, c0[1]);
     48   assertEquals(1, c0[0]);
     49 
     50   var c1 = [1, 2, 3.5];
     51   assertTrue(%HasFastDoubleElements(c1));
     52   assertEquals(3.5, c1[2]);
     53   assertEquals(2, c1[1]);
     54   assertEquals(1, c1[0]);
     55 
     56   var c2 = [get(1), get(2), get(3.5)];
     57   assertTrue(%HasFastDoubleElements(c2));
     58   assertEquals(3.5, c2[2]);
     59   assertEquals(2, c2[1]);
     60   assertEquals(1, c2[0]);
     61 
     62   var object = new Object();
     63   var d0 = [1, 2, object];
     64   assertTrue(%HasFastObjectElements(d0));
     65   assertEquals(object, d0[2]);
     66   assertEquals(2, d0[1]);
     67   assertEquals(1, d0[0]);
     68 
     69   var e0 = [1, 2, 3.5];
     70   assertTrue(%HasFastDoubleElements(e0));
     71   assertEquals(3.5, e0[2]);
     72   assertEquals(2, e0[1]);
     73   assertEquals(1, e0[0]);
     74 
     75   var f0 = [1, 2, [1, 2]];
     76   assertTrue(%HasFastObjectElements(f0));
     77   assertEquals([1,2], f0[2]);
     78   assertEquals(2, f0[1]);
     79   assertEquals(1, f0[0]);
     80 }
     81 
     82 for (var i = 0; i < 3; i++) {
     83   array_literal_test();
     84 }
     85   %OptimizeFunctionOnNextCall(array_literal_test);
     86 array_literal_test();
     87 
     88 function test_large_literal() {
     89 
     90   function d() {
     91     gc();
     92     return 2.5;
     93   }
     94 
     95   function o() {
     96     gc();
     97     return new Object();
     98   }
     99 
    100   large =
    101     [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
    102   assertFalse(%HasDictionaryElements(large));
    103   assertFalse(%HasFastSmiElements(large));
    104   assertFalse(%HasFastDoubleElements(large));
    105   assertTrue(%HasFastObjectElements(large));
    106   assertEquals(large,
    107                [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
    108                 new Object(), new Object(), new Object(), new Object()]);
    109 }
    110 
    111 for (var i = 0; i < 3; i++) {
    112   test_large_literal();
    113 }
    114   %OptimizeFunctionOnNextCall(test_large_literal);
    115 test_large_literal();
    116 
    117 function deopt_array(use_literal) {
    118   if (use_literal) {
    119     return [.5, 3, 4];
    120   }  else {
    121     return new Array();
    122   }
    123 }
    124 
    125 deopt_array(false);
    126 deopt_array(false);
    127 deopt_array(false);
    128   %OptimizeFunctionOnNextCall(deopt_array);
    129 var array = deopt_array(false);
    130 assertOptimized(deopt_array);
    131 deopt_array(true);
    132 assertOptimized(deopt_array);
    133 array = deopt_array(false);
    134 assertOptimized(deopt_array);
    135 
    136 // Check that unexpected changes in the objects stored into the boilerplate
    137 // also force a deopt.
    138 function deopt_array_literal_all_smis(a) {
    139   return [0, 1, a];
    140 }
    141 
    142 deopt_array_literal_all_smis(2);
    143 deopt_array_literal_all_smis(3);
    144 deopt_array_literal_all_smis(4);
    145 array = deopt_array_literal_all_smis(4);
    146 assertEquals(0, array[0]);
    147 assertEquals(1, array[1]);
    148 assertEquals(4, array[2]);
    149   %OptimizeFunctionOnNextCall(deopt_array_literal_all_smis);
    150 array = deopt_array_literal_all_smis(5);
    151 array = deopt_array_literal_all_smis(6);
    152 assertOptimized(deopt_array_literal_all_smis);
    153 assertEquals(0, array[0]);
    154 assertEquals(1, array[1]);
    155 assertEquals(6, array[2]);
    156 
    157 array = deopt_array_literal_all_smis(.5);
    158 assertUnoptimized(deopt_array_literal_all_smis);
    159 assertEquals(0, array[0]);
    160 assertEquals(1, array[1]);
    161 assertEquals(.5, array[2]);
    162 
    163 function deopt_array_literal_all_doubles(a) {
    164   return [0.5, 1, a];
    165 }
    166 
    167 deopt_array_literal_all_doubles(.5);
    168 deopt_array_literal_all_doubles(.5);
    169 deopt_array_literal_all_doubles(.5);
    170 array = deopt_array_literal_all_doubles(0.5);
    171 assertEquals(0.5, array[0]);
    172 assertEquals(1, array[1]);
    173 assertEquals(0.5, array[2]);
    174   %OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles);
    175 array = deopt_array_literal_all_doubles(5);
    176 array = deopt_array_literal_all_doubles(6);
    177 assertOptimized(deopt_array_literal_all_doubles);
    178 assertEquals(0.5, array[0]);
    179 assertEquals(1, array[1]);
    180 assertEquals(6, array[2]);
    181 
    182 var foo = new Object();
    183 array = deopt_array_literal_all_doubles(foo);
    184 assertUnoptimized(deopt_array_literal_all_doubles);
    185 assertEquals(0.5, array[0]);
    186 assertEquals(1, array[1]);
    187 assertEquals(foo, array[2]);
    188 
    189 (function literals_after_osr() {
    190   var color = [0];
    191   // Trigger OSR, if optimization is not disabled.
    192   if (%GetOptimizationStatus(literals_after_osr) != 4) {
    193     while (%GetOptimizationCount(literals_after_osr) == 0) {}
    194   }
    195   return [color[0]];
    196 })();
    197