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 // Flags: --track-allocation-sites --noalways-opt
     30 
     31 // Test element kind of objects.
     32 // Since --smi-only-arrays affects builtins, its default setting at compile
     33 // time sticks if built with snapshot.  If --smi-only-arrays is deactivated
     34 // by default, only a no-snapshot build actually has smi-only arrays enabled
     35 // in this test case.  Depending on whether smi-only arrays are actually
     36 // enabled, this test takes the appropriate code path to check smi-only arrays.
     37 
     38 // Reset the GC stress mode to be off. Needed because AllocationMementos only
     39 // live for one gc, so a gc that happens in certain fragile areas of the test
     40 // can break assumptions.
     41 %SetFlags("--gc-interval=-1")
     42 
     43 // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
     44 support_smi_only_arrays = true;
     45 
     46 if (support_smi_only_arrays) {
     47   print("Tests include smi-only arrays.");
     48 } else {
     49   print("Tests do NOT include smi-only arrays.");
     50 }
     51 
     52 var elements_kind = {
     53   fast_smi_only            :  'fast smi only elements',
     54   fast                     :  'fast elements',
     55   fast_double              :  'fast double elements',
     56   dictionary               :  'dictionary elements',
     57   external_byte            :  'external byte elements',
     58   external_unsigned_byte   :  'external unsigned byte elements',
     59   external_short           :  'external short elements',
     60   external_unsigned_short  :  'external unsigned short elements',
     61   external_int             :  'external int elements',
     62   external_unsigned_int    :  'external unsigned int elements',
     63   external_float           :  'external float elements',
     64   external_double          :  'external double elements',
     65   external_pixel           :  'external pixel elements'
     66 }
     67 
     68 function getKind(obj) {
     69   if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
     70   if (%HasFastObjectElements(obj)) return elements_kind.fast;
     71   if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
     72   if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
     73 }
     74 
     75 function isHoley(obj) {
     76   if (%HasFastHoleyElements(obj)) return true;
     77   return false;
     78 }
     79 
     80 function assertKind(expected, obj, name_opt) {
     81   if (!support_smi_only_arrays &&
     82       expected == elements_kind.fast_smi_only) {
     83     expected = elements_kind.fast;
     84   }
     85   assertEquals(expected, getKind(obj), name_opt);
     86 }
     87 
     88 if (support_smi_only_arrays) {
     89 
     90   function get_literal(x) {
     91     var literal = [1, 2, x];
     92     return literal;
     93   }
     94 
     95   get_literal(3);
     96   // It's important to store a from before we crankshaft get_literal, because
     97   // mementos won't be created from crankshafted code at all.
     98   a = get_literal(3);
     99   %OptimizeFunctionOnNextCall(get_literal);
    100   get_literal(3);
    101   assertOptimized(get_literal);
    102   assertTrue(%HasFastSmiElements(a));
    103   // a has a memento so the transition caused by the store will affect the
    104   // boilerplate.
    105   a[0] = 3.5;
    106 
    107   // We should have transitioned the boilerplate array to double, and
    108   // crankshafted code should de-opt on the unexpected elements kind
    109   b = get_literal(3);
    110   assertTrue(%HasFastDoubleElements(b));
    111   assertEquals([1, 2, 3], b);
    112   assertUnoptimized(get_literal);
    113 
    114   // Optimize again
    115   get_literal(3);
    116   %OptimizeFunctionOnNextCall(get_literal);
    117   b = get_literal(3);
    118   assertTrue(%HasFastDoubleElements(b));
    119   assertOptimized(get_literal);
    120 
    121 
    122   // Test: make sure allocation site information is updated through a
    123   // transition from SMI->DOUBLE->FAST
    124   (function() {
    125     function bar(a, b, c) {
    126       return [a, b, c];
    127     }
    128 
    129     a = bar(1, 2, 3);
    130     a[0] = 3.5;
    131     a[1] = 'hi';
    132     b = bar(1, 2, 3);
    133     assertKind(elements_kind.fast, b);
    134   })();
    135 }
    136