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
     29 
     30 // Verifies that the KeyedStoreIC correctly handles out-of-bounds stores
     31 // to an array that grow it by a single element. Test functions are
     32 // called twice to make sure that the IC is used, first call is handled
     33 // by the runtime in the miss stub.
     34 
     35 function array_store_1(a,b,c) {
     36   return (a[b] = c);
     37 }
     38 
     39 // Check handling of the empty array.
     40 var a = [];
     41 array_store_1(a, 0, 1);
     42 a = [];
     43 array_store_1(a, 0, 1);
     44 assertEquals(1, a[0]);
     45 assertEquals(1, array_store_1([], 0, 1));
     46 
     47 a = [];
     48 for (x=0;x<100000;++x) {
     49   assertEquals(x, array_store_1(a, x, x));
     50 }
     51 
     52 for (x=0;x<100000;++x) {
     53   assertEquals(x, array_store_1([], 0, x));
     54 }
     55 
     56 function array_store_2(a,b,c) {
     57   return (a[b] = c);
     58 }
     59 
     60 a = [];
     61 array_store_2(a, 0, 0.5);
     62 a = [];
     63 array_store_2(a, 0, 0.5);
     64 assertEquals(0.5, a[0]);
     65 assertEquals(0.5, array_store_2([], 0, 0.5));
     66 
     67 function array_store_3(a,b,c) {
     68   return (a[b] = c);
     69 }
     70 
     71 x = new Object();
     72 a = [];
     73 array_store_3(a, 0, x);
     74 a = [];
     75 array_store_3(a, 0, x);
     76 assertEquals(x, a[0]);
     77 assertEquals(x, array_store_3([], 0, x));
     78 
     79 // Check the handling of COW arrays
     80 function makeCOW() {
     81   return [1];
     82 }
     83 
     84 function array_store_4(a,b,c) {
     85   return (a[b] = c);
     86 }
     87 
     88 a = makeCOW();
     89 array_store_4(a, 1, 1);
     90 a = makeCOW();
     91 array_store_4(a, 1, 1);
     92 assertEquals(1, a[1]);
     93 assertEquals(1, array_store_4([], 1, 1));
     94 
     95 function array_store_5(a,b,c) {
     96   return (a[b] = c);
     97 }
     98 
     99 a = makeCOW();
    100 array_store_5(a, 1, 0.5);
    101 a = makeCOW();
    102 array_store_5(a, 1, 0.5);
    103 assertEquals(0.5, a[1]);
    104 a = [];
    105 assertEquals(0.5, array_store_5(a, 1, 0.5));
    106 assertEquals(undefined, a[0]);
    107 assertEquals(0.5, a[1]);
    108 
    109 function array_store_6(a,b,c) {
    110   return (a[b] = c);
    111 }
    112 
    113 a = makeCOW();
    114 array_store_6(a, 1, x);
    115 a = makeCOW();
    116 array_store_6(a, 1, x);
    117 assertEquals(x, a[1]);
    118 assertEquals(x, array_store_6([], 1, x));
    119 
    120 // Check the handling of mutable arrays.
    121 a = new Array(1,2,3);
    122 array_store_4(a, 3, 1);
    123 a = new Array(1,2,3);
    124 array_store_4(a, 3, 1);
    125 assertEquals(1, a[3]);
    126 assertEquals(1, array_store_4([], 3, 1));
    127 
    128 function array_store_5(a,b,c) {
    129   return (a[b] = c);
    130 }
    131 
    132 a = new Array(1,2,3);
    133 array_store_5(a, 3, 0.5);
    134 a = new Array(1,2,3);
    135 array_store_5(a, 3, 0.5);
    136 assertEquals(0.5, a[3]);
    137 assertEquals(0.5, array_store_5([], 3, 0.5));
    138 
    139 function array_store_6(a,b,c) {
    140   return (a[b] = c);
    141 }
    142 
    143 a = new Array(1,2,3);
    144 array_store_6(a, 3, x);
    145 a = new Array(1,2,3);
    146 array_store_6(a, 3, x);
    147 assertEquals(x, a[3]);
    148 assertEquals(x, array_store_6([], 3, x));
    149 
    150 function array_store_7(a,b,c) {
    151   return (a[b] = c);
    152 }
    153 
    154 // Check the handling of mutable arrays of doubles
    155 var a = new Array(0.5, 1.5);
    156 array_store_7(a, 2, .5);
    157 a = new Array(0.5, 1.5);
    158 array_store_7(a, 2, .5);
    159 assertEquals(0.5, a[2]);
    160 a = new Array(0.5, 1.5);
    161 assertEquals(0.5, array_store_7(a, 2, 0.5));
    162 
    163 for (x=0;x<100000;++x) {
    164   a = new Array(0.5, 1.5);
    165   assertEquals(x, array_store_7(a, 2, x));
    166 }
    167 
    168 function array_store_8(a,b,c) {
    169   return (a[b] = c);
    170 }
    171 
    172 var a = new Array(0.5, 1.5);
    173 array_store_8(a, 2, .5);
    174 a = new Array(0.5, 1.5);
    175 array_store_8(a, 10, .5);
    176 assertEquals(0.5, a[10]);
    177 
    178 // Grow the empty array with a double store.
    179 function array_store_9(a,b,c) {
    180   return (a[b] = c);
    181 }
    182 
    183 var a = [];
    184 array_store_9(a, 0, 0.5);
    185 a = [];
    186 array_store_1(a, 0, 0.5);
    187 assertEquals(0.5, a[0]);
    188 assertEquals(0.5, array_store_1([], 0, 0.5));
    189 
    190 
    191 // Verify that a grow store will deoptimize if the max gap (difference between
    192 // the end of an array capacity and a new index) is passed. The wrapper is to
    193 // make sure array_store_10 isn't inlined.
    194 
    195 (function() {
    196   function grow_store(a,b,c) {
    197     a[b] = c;
    198   }
    199 
    200   a = new Array(1);
    201   grow_store(a,1,1);
    202   grow_store(a,2,1);
    203   %OptimizeFunctionOnNextCall(grow_store);
    204   grow_store(a,10,1);
    205   assertOptimized(grow_store);
    206   grow_store(a,2048,1);
    207   assertUnoptimized(grow_store);
    208   %ClearFunctionTypeFeedback(grow_store);
    209 })();
    210 
    211 
    212 // Verify that a polymorphic store and grow IC when crankshafted is still
    213 // a grow IC (earlier it would revert to a standard store in the polymorphic
    214 // case).
    215 (function() {
    216   function f(o, k, v) {
    217     o[k] = v;
    218   }
    219 
    220   a = [3.5];
    221   f(a, 1, "hi");  // DOUBLE packed array -> tagged packed grow
    222   a = {};
    223   a.p = "property";
    224   a[0] = 1;
    225   f(a, 0, 5.4);
    226 
    227   %OptimizeFunctionOnNextCall(f);
    228   // Should be a polymorphic grow stub. If not a grow stub it will deopt.
    229   f(new Array("hi"), 1, 3);
    230   assertOptimized(f);
    231   %ClearFunctionTypeFeedback(f);
    232 })();
    233 
    234 
    235 // Now verify that a polymorphic store (non-growing) IC when crankshafted WILL
    236 // deopt if you pass an element out of bounds.
    237 (function() {
    238   function f(o, k, v) {
    239     o[k] = v;
    240   }
    241 
    242   a = [3.5];
    243   f(a, 0, "hi");  // DOUBLE packed array -> tagged packed grow
    244   a = {};
    245   a.p = "property";
    246   a[0] = 1;
    247   f(a, 0, 5.4);
    248 
    249   %OptimizeFunctionOnNextCall(f);
    250   f(new Array("hi"), 0, 3);
    251   assertOptimized(f);
    252   // An attempt to grow should cause deopt
    253   f(new Array("hi"), 1, 3);
    254   assertUnoptimized(f);
    255   %ClearFunctionTypeFeedback(f);
    256 })();
    257