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 --smi-only-arrays
29
30support_smi_only_arrays = %HasFastSmiOnlyElements(new Array(1,2,3,4,5,6,7,8));
31
32if (support_smi_only_arrays) {
33  print("Tests include smi-only arrays.");
34} else {
35  print("Tests do NOT include smi-only arrays.");
36}
37
38if (support_smi_only_arrays) {
39  function test(test_double, test_object, set, length) {
40    // We apply the same operations to two identical arrays.  The first array
41    // triggers an IC miss, upon which the conversion stub is generated, but the
42    // actual conversion is done in runtime.  The second array, arriving at
43    // the previously patched IC, is then converted using the conversion stub.
44    var array_1 = new Array(length);
45    var array_2 = new Array(length);
46
47    assertTrue(%HasFastSmiOnlyElements(array_1));
48    assertTrue(%HasFastSmiOnlyElements(array_2));
49    for (var i = 0; i < length; i++) {
50      if (i == length - 5 && test_double) {
51        // Trigger conversion to fast double elements at length-5.
52        set(array_1, i, 0.5);
53        set(array_2, i, 0.5);
54        assertTrue(%HasFastDoubleElements(array_1));
55        assertTrue(%HasFastDoubleElements(array_2));
56      } else if (i == length - 3 && test_object) {
57        // Trigger conversion to fast object elements at length-3.
58        set(array_1, i, 'object');
59        set(array_2, i, 'object');
60        assertTrue(%HasFastElements(array_1));
61        assertTrue(%HasFastElements(array_2));
62      } else if (i != length - 7) {
63        // Set the element to an integer but leave a hole at length-7.
64        set(array_1, i, 2*i+1);
65        set(array_2, i, 2*i+1);
66      }
67    }
68
69    for (var i = 0; i < length; i++) {
70      if (i == length - 5 && test_double) {
71        assertEquals(0.5, array_1[i]);
72        assertEquals(0.5, array_2[i]);
73      } else if (i == length - 3 && test_object) {
74        assertEquals('object', array_1[i]);
75        assertEquals('object', array_2[i]);
76      } else if (i != length - 7) {
77        assertEquals(2*i+1, array_1[i]);
78        assertEquals(2*i+1, array_2[i]);
79      } else {
80        assertEquals(undefined, array_1[i]);
81        assertEquals(undefined, array_2[i]);
82      }
83    }
84
85    assertEquals(length, array_1.length);
86    assertEquals(length, array_2.length);
87  }
88
89  test(false, false, function(a,i,v){ a[i] = v; }, 20);
90  test(true,  false, function(a,i,v){ a[i] = v; }, 20);
91  test(false, true,  function(a,i,v){ a[i] = v; }, 20);
92  test(true,  true,  function(a,i,v){ a[i] = v; }, 20);
93
94  test(false, false, function(a,i,v){ a[i] = v; }, 10000);
95  test(true,  false, function(a,i,v){ a[i] = v; }, 10000);
96  test(false, true,  function(a,i,v){ a[i] = v; }, 10000);
97  test(true,  true,  function(a,i,v){ a[i] = v; }, 10000);
98
99  // Check COW arrays
100  function get_cow() { return [1, 2, 3]; }
101
102  function transition(x) { x[0] = 1.5; }
103
104  var ignore = get_cow();
105  transition(ignore);  // Handled by runtime.
106  var a = get_cow();
107  var b = get_cow();
108  transition(a);  // Handled by IC.
109  assertEquals(1.5, a[0]);
110  assertEquals(1, b[0]);
111} else {
112  print("Test skipped because smi only arrays are not supported.");
113}
114