11510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
21510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Redistribution and use in source and binary forms, with or without
31510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// modification, are permitted provided that the following conditions are
41510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// met:
51510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//
61510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//     * Redistributions of source code must retain the above copyright
71510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       notice, this list of conditions and the following disclaimer.
81510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//     * Redistributions in binary form must reproduce the above
91510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       copyright notice, this list of conditions and the following
101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       disclaimer in the documentation and/or other materials provided
111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       with the distribution.
121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//     * Neither the name of Google Inc. nor the names of its
131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       contributors may be used to endorse or promote products derived
141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//       from this software without specific prior written permission.
151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//
161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Flags: --notrack_allocation_sites
301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Limit the number of stress runs to reduce polymorphism it defeats some of the
321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// assumptions made about how elements transitions work because transition stubs
331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// end up going generic.
341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Flags: --stress-runs=2
351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Test element kind of objects.
371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Since --smi-only-arrays affects builtins, its default setting at compile
381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// time sticks if built with snapshot.  If --smi-only-arrays is deactivated
391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// by default, only a no-snapshot build actually has smi-only arrays enabled
401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// in this test case.  Depending on whether smi-only arrays are actually
411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// enabled, this test takes the appropriate code path to check smi-only arrays.
421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
433d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org// Reset the GC stress mode to be off. Needed because AllocationMementos only
443d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org// live for one gc, so a gc that happens in certain fragile areas of the test
453d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org// can break assumptions.
463d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org%SetFlags("--gc-interval=-1")
473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org
481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgsupport_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgif (support_smi_only_arrays) {
511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  print("Tests include smi-only arrays.");
521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} else {
531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  print("Tests do NOT include smi-only arrays.");
541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvar elements_kind = {
571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  fast_smi_only            :  'fast smi only elements',
581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  fast                     :  'fast elements',
591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  fast_double              :  'fast double elements',
601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  dictionary               :  'dictionary elements',
611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_byte            :  'external byte elements',
621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_unsigned_byte   :  'external unsigned byte elements',
631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_short           :  'external short elements',
641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_unsigned_short  :  'external unsigned short elements',
651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_int             :  'external int elements',
661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_unsigned_int    :  'external unsigned int elements',
671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_float           :  'external float elements',
681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_double          :  'external double elements',
691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  external_pixel           :  'external pixel elements'
701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction getKind(obj) {
731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasFastObjectElements(obj)) return elements_kind.fast;
751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Every external kind is also an external array.
781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertTrue(%HasExternalArrayElements(obj));
791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalByteElements(obj)) {
801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_byte;
811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalUnsignedByteElements(obj)) {
831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_unsigned_byte;
841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalShortElements(obj)) {
861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_short;
871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalUnsignedShortElements(obj)) {
891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_unsigned_short;
901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalIntElements(obj)) {
921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_int;
931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalUnsignedIntElements(obj)) {
951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_unsigned_int;
961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalFloatElements(obj)) {
981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_float;
991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalDoubleElements(obj)) {
1011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_double;
1021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (%HasExternalPixelElements(obj)) {
1041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return elements_kind.external_pixel;
1051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction assertKind(expected, obj, name_opt) {
1091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!support_smi_only_arrays &&
1101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      expected == elements_kind.fast_smi_only) {
1111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    expected = elements_kind.fast;
1121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
1131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertEquals(expected, getKind(obj), name_opt);
1141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
116ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org%NeverOptimizeFunction(construct_smis);
1171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction construct_smis() {
1181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  var a = [0, 0, 0];
1191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  a[0] = 0;  // Send the COW array map to the steak house.
1201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertKind(elements_kind.fast_smi_only, a);
1211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return a;
1221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
124ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org%NeverOptimizeFunction(construct_doubles);
1251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction construct_doubles() {
1261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  var a = construct_smis();
1271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  a[0] = 1.5;
1281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertKind(elements_kind.fast_double, a);
1291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return a;
1301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
132ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org%NeverOptimizeFunction(convert_mixed);
1331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction convert_mixed(array, value, kind) {
1341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  array[1] = value;
1351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertKind(kind, array);
1361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertEquals(value, array[1]);
1371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgfunction test1() {
1401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!support_smi_only_arrays) return;
1411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
1431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // transition to FAST directly).
1441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  var smis = construct_smis();
1451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(smis, 1.5, elements_kind.fast_double);
1461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  var doubles = construct_doubles();
1481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(doubles, "three", elements_kind.fast);
1491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(construct_smis(), "three", elements_kind.fast);
1511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(construct_doubles(), "three", elements_kind.fast);
1521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  smis = construct_smis();
1541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  doubles = construct_doubles();
1551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(smis, 1, elements_kind.fast);
1561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  convert_mixed(doubles, 1, elements_kind.fast);
1571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  assertTrue(%HaveSameMap(smis, doubles));
1581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
1591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtest1();
1611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orggc(); // clear IC state
1621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtest1();
1631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orggc(); // clear IC state
1641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org%OptimizeFunctionOnNextCall(test1);
1651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtest1();
1661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orggc(); // clear IC state
167