Home | History | Annotate | Download | only in mjsunit
      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);
     31 function 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 }
    222 test();
    223