- add third_party src.
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / array-constructor-feedback.js
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 // Flags: --track-allocation-sites --noalways-opt
30
31 // Test element kind of objects.
32 // Since --smi-only-arrays affects builtins, its default setting at compile
33 // time sticks if built with snapshot.  If --smi-only-arrays is deactivated
34 // by default, only a no-snapshot build actually has smi-only arrays enabled
35 // in this test case.  Depending on whether smi-only arrays are actually
36 // enabled, this test takes the appropriate code path to check smi-only arrays.
37
38 // Reset the GC stress mode to be off. Needed because AllocationMementos only
39 // live for one gc, so a gc that happens in certain fragile areas of the test
40 // can break assumptions.
41 %SetFlags("--gc-interval=-1")
42
43 // support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8));
44 support_smi_only_arrays = true;
45
46 if (support_smi_only_arrays) {
47   print("Tests include smi-only arrays.");
48 } else {
49   print("Tests do NOT include smi-only arrays.");
50 }
51
52 var elements_kind = {
53   fast_smi_only            :  'fast smi only elements',
54   fast                     :  'fast elements',
55   fast_double              :  'fast double elements',
56   dictionary               :  'dictionary elements',
57   external_byte            :  'external byte elements',
58   external_unsigned_byte   :  'external unsigned byte elements',
59   external_short           :  'external short elements',
60   external_unsigned_short  :  'external unsigned short elements',
61   external_int             :  'external int elements',
62   external_unsigned_int    :  'external unsigned int elements',
63   external_float           :  'external float elements',
64   external_double          :  'external double elements',
65   external_pixel           :  'external pixel elements'
66 }
67
68 function getKind(obj) {
69   if (%HasFastSmiElements(obj)) return elements_kind.fast_smi_only;
70   if (%HasFastObjectElements(obj)) return elements_kind.fast;
71   if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
72   if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
73 }
74
75 function isHoley(obj) {
76   if (%HasFastHoleyElements(obj)) return true;
77   return false;
78 }
79
80 function assertKind(expected, obj, name_opt) {
81   if (!support_smi_only_arrays &&
82       expected == elements_kind.fast_smi_only) {
83     expected = elements_kind.fast;
84   }
85   assertEquals(expected, getKind(obj), name_opt);
86 }
87
88 if (support_smi_only_arrays) {
89
90   // Test: If a call site goes megamorphic, it loses the ability to
91   // use allocation site feedback.
92   (function() {
93     function bar(t, len) {
94       return new t(len);
95     }
96
97     a = bar(Array, 10);
98     a[0] = 3.5;
99     b = bar(Array, 1);
100     assertKind(elements_kind.fast_double, b);
101     c = bar(Object, 3);
102     b = bar(Array, 10);
103     assertKind(elements_kind.fast_smi_only, b);
104     b[0] = 3.5;
105     c = bar(Array, 10);
106     assertKind(elements_kind.fast_smi_only, c);
107   })();
108
109
110   // Test: ensure that crankshafted array constructor sites are deopted
111   // if another function is used.
112   (function() {
113     function bar0(t) {
114       return new t();
115     }
116     a = bar0(Array);
117     a[0] = 3.5;
118     b = bar0(Array);
119     assertKind(elements_kind.fast_double, b);
120     %OptimizeFunctionOnNextCall(bar0);
121     b = bar0(Array);
122     assertKind(elements_kind.fast_double, b);
123     assertOptimized(bar0);
124     // bar0 should deopt
125     b = bar0(Object);
126     assertUnoptimized(bar0)
127     // When it's re-optimized, we should call through the full stub
128     bar0(Array);
129     %OptimizeFunctionOnNextCall(bar0);
130     b = bar0(Array);
131     // We also lost our ability to record kind feedback, as the site
132     // is megamorphic now.
133     assertKind(elements_kind.fast_smi_only, b);
134     assertOptimized(bar0);
135     b[0] = 3.5;
136     c = bar0(Array);
137     assertKind(elements_kind.fast_smi_only, c);
138   })();
139
140
141   // Test: Ensure that bailouts from the stub don't deopt a crankshafted
142   // method with a call to that stub.
143   (function() {
144     function bar(len) {
145       return new Array(len);
146     }
147     a = bar(10);
148     a[0] = "a string";
149     a = bar(10);
150     assertKind(elements_kind.fast, a);
151     %OptimizeFunctionOnNextCall(bar);
152     a = bar(10);
153     assertKind(elements_kind.fast, a);
154     assertOptimized(bar);
155     // The stub bails out, but the method call should be fine.
156     a = bar(100000);
157     assertOptimized(bar);
158     assertKind(elements_kind.dictionary, a);
159
160     // If the argument isn't a smi, it bails out as well
161     a = bar("oops");
162     assertOptimized(bar);
163     assertKind(elements_kind.fast, a);
164
165     function barn(one, two, three) {
166       return new Array(one, two, three);
167     }
168
169     barn(1, 2, 3);
170     barn(1, 2, 3);
171     %OptimizeFunctionOnNextCall(barn);
172     barn(1, 2, 3);
173     assertOptimized(barn);
174     a = barn(1, "oops", 3);
175     // The stub should bail out but the method should remain optimized.
176     assertKind(elements_kind.fast, a);
177     assertOptimized(barn);
178   })();
179
180
181   // Test: When a method with array constructor is crankshafted, the type
182   // feedback for elements kind is baked in. Verify that transitions don't
183   // change it anymore
184   (function() {
185     function bar() {
186       return new Array();
187     }
188     a = bar();
189     bar();
190     %OptimizeFunctionOnNextCall(bar);
191     b = bar();
192     // This only makes sense to test if we allow crankshafting
193     if (4 != %GetOptimizationStatus(bar)) {
194       assertOptimized(bar);
195       %DebugPrint(3);
196       b[0] = 3.5;
197       c = bar();
198       assertKind(elements_kind.fast_smi_only, c);
199       assertOptimized(bar);
200     }
201   })();
202
203
204   // Test: create arrays in two contexts, verifying that the correct
205   // map for Array in that context will be used.
206   (function() {
207     function bar() { return new Array(); }
208     bar();
209     bar();
210     %OptimizeFunctionOnNextCall(bar);
211     a = bar();
212     assertTrue(a instanceof Array);
213
214     var contextB = Realm.create();
215     Realm.eval(contextB, "function bar2() { return new Array(); };");
216     Realm.eval(contextB, "bar2(); bar2();");
217     Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);");
218     Realm.eval(contextB, "bar2();");
219     assertFalse(Realm.eval(contextB, "bar2();") instanceof Array);
220     assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
221   })();
222 }