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 --smi-only-arrays --expose-gc
     29 
     30 // Limit the number of stress runs to reduce polymorphism it defeats some of the
     31 // assumptions made about how elements transitions work because transition stubs
     32 // end up going generic.
     33 // Flags: --stress-runs=2
     34 
     35 // Test element kind of objects.
     36 // Since --smi-only-arrays affects builtins, its default setting at compile
     37 // time sticks if built with snapshot.  If --smi-only-arrays is deactivated
     38 // by default, only a no-snapshot build actually has smi-only arrays enabled
     39 // in this test case.  Depending on whether smi-only arrays are actually
     40 // enabled, this test takes the appropriate code path to check smi-only arrays.
     41 
     42 support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
     43 
     44 if (support_smi_only_arrays) {
     45   print("Tests include smi-only arrays.");
     46 } else {
     47   print("Tests do NOT include smi-only arrays.");
     48 }
     49 
     50 var elements_kind = {
     51   fast_smi_only            :  'fast smi only elements',
     52   fast                     :  'fast elements',
     53   fast_double              :  'fast double elements',
     54   dictionary               :  'dictionary elements',
     55   external_byte            :  'external byte elements',
     56   external_unsigned_byte   :  'external unsigned byte elements',
     57   external_short           :  'external short elements',
     58   external_unsigned_short  :  'external unsigned short elements',
     59   external_int             :  'external int elements',
     60   external_unsigned_int    :  'external unsigned int elements',
     61   external_float           :  'external float elements',
     62   external_double          :  'external double elements',
     63   external_pixel           :  'external pixel elements'
     64 }
     65 
     66 function getKind(obj) {
     67   if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
     68   if (%HasFastObjectElements(obj)) return elements_kind.fast;
     69   if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
     70   if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
     71   // Every external kind is also an external array.
     72   assertTrue(%HasExternalArrayElements(obj));
     73   if (%HasExternalByteElements(obj)) {
     74     return elements_kind.external_byte;
     75   }
     76   if (%HasExternalUnsignedByteElements(obj)) {
     77     return elements_kind.external_unsigned_byte;
     78   }
     79   if (%HasExternalShortElements(obj)) {
     80     return elements_kind.external_short;
     81   }
     82   if (%HasExternalUnsignedShortElements(obj)) {
     83     return elements_kind.external_unsigned_short;
     84   }
     85   if (%HasExternalIntElements(obj)) {
     86     return elements_kind.external_int;
     87   }
     88   if (%HasExternalUnsignedIntElements(obj)) {
     89     return elements_kind.external_unsigned_int;
     90   }
     91   if (%HasExternalFloatElements(obj)) {
     92     return elements_kind.external_float;
     93   }
     94   if (%HasExternalDoubleElements(obj)) {
     95     return elements_kind.external_double;
     96   }
     97   if (%HasExternalPixelElements(obj)) {
     98     return elements_kind.external_pixel;
     99   }
    100 }
    101 
    102 function assertKind(expected, obj, name_opt) {
    103   if (!support_smi_only_arrays &&
    104       expected == elements_kind.fast_smi_only) {
    105     expected = elements_kind.fast;
    106   }
    107   assertEquals(expected, getKind(obj), name_opt);
    108 }
    109 
    110 %NeverOptimizeFunction(construct_smis);
    111 
    112 // This code exists to eliminate the learning influence of AllocationSites
    113 // on the following tests.
    114 var __sequence = 0;
    115 function make_array_string() {
    116   this.__sequence = this.__sequence + 1;
    117   return "/* " + this.__sequence + " */  [0, 0, 0];"
    118 }
    119 function make_array() {
    120   return eval(make_array_string());
    121 }
    122 
    123 function construct_smis() {
    124   var a = make_array();
    125   a[0] = 0;  // Send the COW array map to the steak house.
    126   assertKind(elements_kind.fast_smi_only, a);
    127   return a;
    128 }
    129 
    130 %NeverOptimizeFunction(construct_doubles);
    131 function construct_doubles() {
    132   var a = construct_smis();
    133   a[0] = 1.5;
    134   assertKind(elements_kind.fast_double, a);
    135   return a;
    136 }
    137 
    138 %NeverOptimizeFunction(convert_mixed);
    139 function convert_mixed(array, value, kind) {
    140   array[1] = value;
    141   assertKind(kind, array);
    142   assertEquals(value, array[1]);
    143 }
    144 
    145 function test1() {
    146   if (!support_smi_only_arrays) return;
    147 
    148   // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
    149   // transition to FAST directly).
    150   var smis = construct_smis();
    151   convert_mixed(smis, 1.5, elements_kind.fast_double);
    152 
    153   var doubles = construct_doubles();
    154   convert_mixed(doubles, "three", elements_kind.fast);
    155 
    156   convert_mixed(construct_smis(), "three", elements_kind.fast);
    157   convert_mixed(construct_doubles(), "three", elements_kind.fast);
    158 
    159   smis = construct_smis();
    160   doubles = construct_doubles();
    161   convert_mixed(smis, 1, elements_kind.fast);
    162   convert_mixed(doubles, 1, elements_kind.fast);
    163   assertTrue(%HaveSameMap(smis, doubles));
    164 }
    165 
    166 test1();
    167 gc(); // clear IC state
    168 test1();
    169 gc(); // clear IC state
    170 %OptimizeFunctionOnNextCall(test1);
    171 test1();
    172 gc(); // clear IC state
    173