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