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 --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 var elements_kind = {
     36   fast_smi_only             :  'fast smi only elements',
     37   fast                      :  'fast elements',
     38   fast_double               :  'fast double elements',
     39   dictionary                :  'dictionary elements',
     40   fixed_int32               :  'fixed int8 elements',
     41   fixed_uint8               :  'fixed uint8 elements',
     42   fixed_int16               :  'fixed int16 elements',
     43   fixed_uint16              :  'fixed uint16 elements',
     44   fixed_int32               :  'fixed int32 elements',
     45   fixed_uint32              :  'fixed uint32 elements',
     46   fixed_float32             :  'fixed float32 elements',
     47   fixed_float64             :  'fixed float64 elements',
     48   fixed_uint8_clamped       :  'fixed uint8_clamped elements'
     49 }
     50 
     51 function getKind(obj) {
     52   if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
     53   if (%HasFastObjectElements(obj)) return elements_kind.fast;
     54   if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
     55   if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
     56 
     57   if (%HasFixedInt8Elements(obj)) {
     58     return elements_kind.fixed_int8;
     59   }
     60   if (%HasFixedUint8Elements(obj)) {
     61     return elements_kind.fixed_uint8;
     62   }
     63   if (%HasFixedInt16Elements(obj)) {
     64     return elements_kind.fixed_int16;
     65   }
     66   if (%HasFixedUint16Elements(obj)) {
     67     return elements_kind.fixed_uint16;
     68   }
     69   if (%HasFixedInt32Elements(obj)) {
     70     return elements_kind.fixed_int32;
     71   }
     72   if (%HasFixedUint32Elements(obj)) {
     73     return elements_kind.fixed_uint32;
     74   }
     75   if (%HasFixedFloat32Elements(obj)) {
     76     return elements_kind.fixed_float32;
     77   }
     78   if (%HasFixedFloat64Elements(obj)) {
     79     return elements_kind.fixed_float64;
     80   }
     81   if (%HasFixedUint8ClampedElements(obj)) {
     82     return elements_kind.fixed_uint8_clamped;
     83   }
     84 }
     85 
     86 function assertKind(expected, obj, name_opt) {
     87   assertEquals(expected, getKind(obj), name_opt);
     88 }
     89 
     90 %NeverOptimizeFunction(construct_smis);
     91 
     92 // This code exists to eliminate the learning influence of AllocationSites
     93 // on the following tests.
     94 var __sequence = 0;
     95 function make_array_string() {
     96   this.__sequence = this.__sequence + 1;
     97   return "/* " + this.__sequence + " */  [0, 0, 0];"
     98 }
     99 function make_array() {
    100   return eval(make_array_string());
    101 }
    102 
    103 function construct_smis() {
    104   var a = make_array();
    105   a[0] = 0;  // Send the COW array map to the steak house.
    106   assertKind(elements_kind.fast_smi_only, a);
    107   return a;
    108 }
    109 
    110 %NeverOptimizeFunction(construct_doubles);
    111 function construct_doubles() {
    112   var a = construct_smis();
    113   a[0] = 1.5;
    114   assertKind(elements_kind.fast_double, a);
    115   return a;
    116 }
    117 
    118 %NeverOptimizeFunction(convert_mixed);
    119 function convert_mixed(array, value, kind) {
    120   array[1] = value;
    121   assertKind(kind, array);
    122   assertEquals(value, array[1]);
    123 }
    124 
    125 function test1() {
    126   // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
    127   // transition to FAST directly).
    128   var smis = construct_smis();
    129   convert_mixed(smis, 1.5, elements_kind.fast_double);
    130 
    131   var doubles = construct_doubles();
    132   convert_mixed(doubles, "three", elements_kind.fast);
    133 
    134   convert_mixed(construct_smis(), "three", elements_kind.fast);
    135   convert_mixed(construct_doubles(), "three", elements_kind.fast);
    136 
    137   smis = construct_smis();
    138   doubles = construct_doubles();
    139   convert_mixed(smis, 1, elements_kind.fast);
    140   convert_mixed(doubles, 1, elements_kind.fast);
    141   assertTrue(%HaveSameMap(smis, doubles));
    142 }
    143 
    144 function clear_ic_state() {
    145   %ClearFunctionTypeFeedback(construct_smis);
    146   %ClearFunctionTypeFeedback(construct_doubles);
    147   %ClearFunctionTypeFeedback(convert_mixed);
    148 }
    149 
    150 test1();
    151 clear_ic_state();
    152 test1();
    153 clear_ic_state();
    154 %OptimizeFunctionOnNextCall(test1);
    155 test1();
    156 clear_ic_state();
    157