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 --expose-gc
29
30// Test element kind of objects.
31// Since --smi-only-arrays affects builtins, its default setting at compile
32// time sticks if built with snapshot.  If --smi-only-arrays is deactivated
33// by default, only a no-snapshot build actually has smi-only arrays enabled
34// in this test case.  Depending on whether smi-only arrays are actually
35// enabled, this test takes the appropriate code path to check smi-only arrays.
36
37support_smi_only_arrays = %HasFastSmiElements([1,2,3,4,5,6,7,8,9,10]);
38
39if (support_smi_only_arrays) {
40  print("Tests include smi-only arrays.");
41} else {
42  print("Tests do NOT include smi-only arrays.");
43}
44
45// IC and Crankshaft support for smi-only elements in dynamic array literals.
46function get(foo) { return foo; }  // Used to generate dynamic values.
47
48function array_literal_test() {
49  var a0 = [1, 2, 3];
50  assertTrue(%HasFastSmiElements(a0));
51  var a1 = [get(1), get(2), get(3)];
52  assertTrue(%HasFastSmiElements(a1));
53
54  var b0 = [1, 2, get("three")];
55  assertTrue(%HasFastObjectElements(b0));
56  var b1 = [get(1), get(2), get("three")];
57  assertTrue(%HasFastObjectElements(b1));
58
59  var c0 = [1, 2, get(3.5)];
60  assertTrue(%HasFastDoubleElements(c0));
61  assertEquals(3.5, c0[2]);
62  assertEquals(2, c0[1]);
63  assertEquals(1, c0[0]);
64
65  var c1 = [1, 2, 3.5];
66  assertTrue(%HasFastDoubleElements(c1));
67  assertEquals(3.5, c1[2]);
68  assertEquals(2, c1[1]);
69  assertEquals(1, c1[0]);
70
71  var c2 = [get(1), get(2), get(3.5)];
72  assertTrue(%HasFastDoubleElements(c2));
73  assertEquals(3.5, c2[2]);
74  assertEquals(2, c2[1]);
75  assertEquals(1, c2[0]);
76
77  var object = new Object();
78  var d0 = [1, 2, object];
79  assertTrue(%HasFastObjectElements(d0));
80  assertEquals(object, d0[2]);
81  assertEquals(2, d0[1]);
82  assertEquals(1, d0[0]);
83
84  var e0 = [1, 2, 3.5];
85  assertTrue(%HasFastDoubleElements(e0));
86  assertEquals(3.5, e0[2]);
87  assertEquals(2, e0[1]);
88  assertEquals(1, e0[0]);
89
90  var f0 = [1, 2, [1, 2]];
91  assertTrue(%HasFastObjectElements(f0));
92  assertEquals([1,2], f0[2]);
93  assertEquals(2, f0[1]);
94  assertEquals(1, f0[0]);
95}
96
97if (support_smi_only_arrays) {
98  for (var i = 0; i < 3; i++) {
99    array_literal_test();
100  }
101  %OptimizeFunctionOnNextCall(array_literal_test);
102  array_literal_test();
103
104  function test_large_literal() {
105
106    function d() {
107      gc();
108      return 2.5;
109    }
110
111    function o() {
112      gc();
113      return new Object();
114    }
115
116    large =
117        [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
118    assertFalse(%HasDictionaryElements(large));
119    assertFalse(%HasFastSmiElements(large));
120    assertFalse(%HasFastDoubleElements(large));
121    assertTrue(%HasFastObjectElements(large));
122    assertEquals(large,
123                 [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
124                  new Object(), new Object(), new Object(), new Object()]);
125  }
126
127  for (var i = 0; i < 3; i++) {
128    test_large_literal();
129  }
130  %OptimizeFunctionOnNextCall(test_large_literal);
131  test_large_literal();
132
133  function deopt_array(use_literal) {
134    if (use_literal) {
135      return [.5, 3, 4];
136    }  else {
137      return new Array();
138    }
139  }
140
141  deopt_array(false);
142  deopt_array(false);
143  deopt_array(false);
144  %OptimizeFunctionOnNextCall(deopt_array);
145  var array = deopt_array(false);
146  assertOptimized(deopt_array);
147  deopt_array(true);
148  assertOptimized(deopt_array);
149  array = deopt_array(false);
150  assertOptimized(deopt_array);
151
152  // Check that unexpected changes in the objects stored into the boilerplate
153  // also force a deopt.
154  function deopt_array_literal_all_smis(a) {
155    return [0, 1, a];
156  }
157
158  deopt_array_literal_all_smis(2);
159  deopt_array_literal_all_smis(3);
160  deopt_array_literal_all_smis(4);
161  array = deopt_array_literal_all_smis(4);
162  assertEquals(0, array[0]);
163  assertEquals(1, array[1]);
164  assertEquals(4, array[2]);
165  %OptimizeFunctionOnNextCall(deopt_array_literal_all_smis);
166  array = deopt_array_literal_all_smis(5);
167  array = deopt_array_literal_all_smis(6);
168  assertOptimized(deopt_array_literal_all_smis);
169  assertEquals(0, array[0]);
170  assertEquals(1, array[1]);
171  assertEquals(6, array[2]);
172
173  array = deopt_array_literal_all_smis(.5);
174  assertUnoptimized(deopt_array_literal_all_smis);
175  assertEquals(0, array[0]);
176  assertEquals(1, array[1]);
177  assertEquals(.5, array[2]);
178
179  function deopt_array_literal_all_doubles(a) {
180    return [0.5, 1, a];
181  }
182
183  deopt_array_literal_all_doubles(.5);
184  deopt_array_literal_all_doubles(.5);
185  deopt_array_literal_all_doubles(.5);
186  array = deopt_array_literal_all_doubles(0.5);
187  assertEquals(0.5, array[0]);
188  assertEquals(1, array[1]);
189  assertEquals(0.5, array[2]);
190  %OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles);
191  array = deopt_array_literal_all_doubles(5);
192  array = deopt_array_literal_all_doubles(6);
193  assertOptimized(deopt_array_literal_all_doubles);
194  assertEquals(0.5, array[0]);
195  assertEquals(1, array[1]);
196  assertEquals(6, array[2]);
197
198  var foo = new Object();
199  array = deopt_array_literal_all_doubles(foo);
200  assertUnoptimized(deopt_array_literal_all_doubles);
201  assertEquals(0.5, array[0]);
202  assertEquals(1, array[1]);
203  assertEquals(foo, array[2]);
204}
205
206(function literals_after_osr() {
207  var color = [0];
208  // Trigger OSR, if optimization is not disabled.
209  if (%GetOptimizationStatus(literals_after_osr) != 4) {
210    while (%GetOptimizationCount(literals_after_osr) == 0) {}
211  }
212  return [color[0]];
213})();
214