• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 --expose-gc
29
30var elements_kind = {
31  fast_smi_only            :  'fast smi only elements',
32  fast                     :  'fast elements',
33  fast_double              :  'fast double elements',
34  dictionary               :  'dictionary elements',
35  external_byte            :  'external byte elements',
36  external_unsigned_byte   :  'external unsigned byte elements',
37  external_short           :  'external short elements',
38  external_unsigned_short  :  'external unsigned short elements',
39  external_int             :  'external int elements',
40  external_unsigned_int    :  'external unsigned int elements',
41  external_float           :  'external float elements',
42  external_double          :  'external double elements',
43  external_pixel           :  'external pixel elements'
44}
45
46function getKind(obj) {
47  if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
48  if (%HasFastObjectElements(obj)) return elements_kind.fast;
49  if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
50  if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
51}
52
53function isHoley(obj) {
54  if (%HasFastHoleyElements(obj)) return true;
55  return false;
56}
57
58function assertKind(expected, obj, name_opt) {
59  assertEquals(expected, getKind(obj), name_opt);
60}
61
62// Verify that basic elements kind feedback works for non-constructor
63// array calls (as long as the call is made through an IC, and not
64// a CallStub).
65(function (){
66  function create0() {
67    return Array();
68  }
69
70  // Calls through ICs need warm up through uninitialized, then
71  // premonomorphic first.
72  create0();
73  a = create0();
74  assertKind(elements_kind.fast_smi_only, a);
75  a[0] = 3.5;
76  b = create0();
77  assertKind(elements_kind.fast_double, b);
78
79  function create1(arg) {
80    return Array(arg);
81  }
82
83  create1(0);
84  create1(0);
85  a = create1(0);
86  assertFalse(isHoley(a));
87  assertKind(elements_kind.fast_smi_only, a);
88  a[0] = "hello";
89  b = create1(10);
90  assertTrue(isHoley(b));
91  assertKind(elements_kind.fast, b);
92
93  a = create1(100000);
94  assertKind(elements_kind.fast, a);
95
96  function create3(arg1, arg2, arg3) {
97    return Array(arg1, arg2, arg3);
98  }
99
100  create3(1,2,3);
101  create3(1,2,3);
102  a = create3(1,2,3);
103  a[0] = 3.035;
104  assertKind(elements_kind.fast_double, a);
105  b = create3(1,2,3);
106  assertKind(elements_kind.fast_double, b);
107  assertFalse(isHoley(b));
108})();
109
110
111// Verify that keyed calls work
112(function (){
113  function create0(name) {
114    return this[name]();
115  }
116
117  name = "Array";
118  create0(name);
119  create0(name);
120  a = create0(name);
121  a[0] = 3.5;
122  b = create0(name);
123  assertKind(elements_kind.fast_double, b);
124})();
125
126
127// Verify that feedback is turned off if the call site goes megamorphic.
128(function (){
129  function foo(arg) { return arg(); }
130  foo(Array);
131  foo(function() {});
132  foo(Array);
133
134  gc();
135
136  a = foo(Array);
137  a[0] = 3.5;
138  b = foo(Array);
139  // b doesn't benefit from elements kind feedback at a megamorphic site.
140  assertKind(elements_kind.fast_smi_only, b);
141})();
142
143
144// Verify that crankshaft consumes type feedback.
145(function (){
146  function create0() {
147    return Array();
148  }
149
150  create0();
151  create0();
152  a = create0();
153  a[0] = 3.5;
154    %OptimizeFunctionOnNextCall(create0);
155  create0();
156  create0();
157  b = create0();
158  assertKind(elements_kind.fast_double, b);
159  assertOptimized(create0);
160
161  function create1(arg) {
162    return Array(arg);
163  }
164
165  create1(8);
166  create1(8);
167  a = create1(8);
168  a[0] = 3.5;
169    %OptimizeFunctionOnNextCall(create1);
170  b = create1(8);
171  assertKind(elements_kind.fast_double, b);
172  assertOptimized(create1);
173
174  function createN(arg1, arg2, arg3) {
175    return Array(arg1, arg2, arg3);
176  }
177
178  createN(1, 2, 3);
179  createN(1, 2, 3);
180  a = createN(1, 2, 3);
181  a[0] = 3.5;
182    %OptimizeFunctionOnNextCall(createN);
183  b = createN(1, 2, 3);
184  assertKind(elements_kind.fast_double, b);
185  assertOptimized(createN);
186})();
187
188// Verify that cross context calls work
189(function (){
190  var realmA = Realm.current();
191  var realmB = Realm.create();
192  assertEquals(0, realmA);
193  assertEquals(1, realmB);
194
195  function instanceof_check(type) {
196    assertTrue(type() instanceof type);
197    assertTrue(type(5) instanceof type);
198    assertTrue(type(1,2,3) instanceof type);
199  }
200
201  var realmBArray = Realm.eval(realmB, "Array");
202  instanceof_check(Array);
203  instanceof_check(Array);
204  instanceof_check(Array);
205  instanceof_check(realmBArray);
206  instanceof_check(realmBArray);
207  instanceof_check(realmBArray);
208})();
209