1// Copyright 2013 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// Flags: --noalways-opt
30
31var elements_kind = {
32  fast_smi_only            :  'fast smi only elements',
33  fast                     :  'fast elements',
34  fast_double              :  'fast double elements',
35  dictionary               :  'dictionary elements',
36  external_byte            :  'external byte elements',
37  external_unsigned_byte   :  'external unsigned byte elements',
38  external_short           :  'external short elements',
39  external_unsigned_short  :  'external unsigned short elements',
40  external_int             :  'external int elements',
41  external_unsigned_int    :  'external unsigned int elements',
42  external_float           :  'external float elements',
43  external_double          :  'external double elements',
44  external_pixel           :  'external pixel elements'
45}
46
47function getKind(obj) {
48  if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
49  if (%HasFastObjectElements(obj)) return elements_kind.fast;
50  if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
51  if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
52}
53
54function isHoley(obj) {
55  if (%HasFastHoleyElements(obj)) return true;
56  return false;
57}
58
59function assertKind(expected, obj, name_opt) {
60  assertEquals(expected, getKind(obj), name_opt);
61}
62
63function get_literal(x) {
64  var literal = [1, 2, x];
65  return literal;
66}
67
68get_literal(3);
69// It's important to store a from before we crankshaft get_literal, because
70// mementos won't be created from crankshafted code at all.
71a = get_literal(3);
72  %OptimizeFunctionOnNextCall(get_literal);
73get_literal(3);
74assertOptimized(get_literal);
75assertTrue(%HasFastSmiElements(a));
76// a has a memento so the transition caused by the store will affect the
77// boilerplate.
78a[0] = 3.5;
79
80// We should have transitioned the boilerplate array to double, and
81// crankshafted code should de-opt on the unexpected elements kind
82b = get_literal(3);
83assertTrue(%HasFastDoubleElements(b));
84assertEquals([1, 2, 3], b);
85assertUnoptimized(get_literal);
86
87// Optimize again
88get_literal(3);
89  %OptimizeFunctionOnNextCall(get_literal);
90b = get_literal(3);
91assertTrue(%HasFastDoubleElements(b));
92assertOptimized(get_literal);
93
94
95// Test: make sure allocation site information is updated through a
96// transition from SMI->DOUBLE->FAST
97(function() {
98  function bar(a, b, c) {
99    return [a, b, c];
100  }
101
102  a = bar(1, 2, 3);
103  a[0] = 3.5;
104  a[1] = 'hi';
105  b = bar(1, 2, 3);
106  assertKind(elements_kind.fast, b);
107})();
108