Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / elements-transition-hoisting.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
29 // Flags: --nostress-opt
30
31 // Ensure that ElementsKind transitions in various situations are hoisted (or
32 // not hoisted) correctly, don't change the semantics programs and don't trigger
33 // deopt through hoisting in important situations.
34
35 function test_wrapper() {
36   // Make sure that a simple elements array transitions inside a loop before
37   // stores to an array gets hoisted in a way that doesn't generate a deopt in
38   // simple cases.}
39   function testDoubleConversion4(a) {
40     var object = new Object();
41     a[0] = 0;
42     var count = 3;
43     do {
44       a[0] = object;
45     } while (--count > 0);
46   }
47
48   testDoubleConversion4(new Array(5));
49   testDoubleConversion4(new Array(5));  // Call twice to make sure that second
50                                         // store is a transition and not
51                                         // optimistically MONOMORPHIC
52   %OptimizeFunctionOnNextCall(testDoubleConversion4);
53   testDoubleConversion4(new Array(5));
54   testDoubleConversion4(new Array(5));
55   assertOptimized(testDoubleConversion4);
56   %ClearFunctionTypeFeedback(testDoubleConversion4);
57
58   // Make sure that non-element related map checks that are not preceded by
59   // transitions in a loop still get hoisted in a way that doesn't generate a
60   // deopt in simple cases.
61   function testExactMapHoisting(a) {
62     var object = new Object();
63     a.foo = {};
64     a[0] = 0;
65     a[1] = 1;
66     var count = 3;
67     do {
68       a.foo = object;  // This map check should be hoistable
69       a[1] = object;
70       result = a.foo == object && a[1] == object;
71     } while (--count > 0);
72   }
73
74   testExactMapHoisting(new Array(5));
75   testExactMapHoisting(new Array(5));  // Call twice to make sure that second
76                                        // store is a transition and not
77                                        // optimistically MONOMORPHIC
78   %OptimizeFunctionOnNextCall(testExactMapHoisting);
79   testExactMapHoisting(new Array(5));
80   testExactMapHoisting(new Array(5));
81   assertOptimized(testExactMapHoisting);
82   %ClearFunctionTypeFeedback(testExactMapHoisting);
83
84   // Make sure that non-element related map checks do NOT get hoisted if they
85   // depend on an elements transition before them and it's not possible to hoist
86   // that transition.
87   function testExactMapHoisting2(a) {
88     var object = new Object();
89     a.foo = 0;
90     a[0] = 0;
91     a[1] = 1;
92     var count = 3;
93     do {
94       if (a.bar === undefined) {
95         a[1] = 2.5;
96       }
97       a.foo = object;  // This map check should NOT be hoistable because it
98                        // includes a check for the FAST_ELEMENTS map as well as
99                        // the FAST_DOUBLE_ELEMENTS map, which depends on the
100                        // double transition above in the if, which cannot be
101                        // hoisted.
102     } while (--count > 0);
103   }
104
105   testExactMapHoisting2(new Array(5));
106   testExactMapHoisting2(new Array(5));  // Call twice to make sure that second
107                                         // store is a transition and not
108                                         // optimistically MONOMORPHIC
109   %OptimizeFunctionOnNextCall(testExactMapHoisting2);
110   testExactMapHoisting2(new Array(5));
111   testExactMapHoisting2(new Array(5));
112   // Temporarily disabled - see bug 2176.
113   // assertOptimized(testExactMapHoisting2);
114   %ClearFunctionTypeFeedback(testExactMapHoisting2);
115
116   // Make sure that non-element related map checks do get hoisted if they use
117   // the transitioned map for the check and all transitions that they depend
118   // upon can hoisted, too.
119   function testExactMapHoisting3(a) {
120     var object = new Object();
121     a.foo = null;
122     a[0] = 0;
123     a[1] = 1;
124     var count = 3;
125     do {
126       a[1] = 2.5;
127       a.foo = object;  // This map check should be hoistable because all elements
128                        // transitions in the loop can also be hoisted.
129     } while (--count > 0);
130   }
131
132   var add_transition = new Array(5);
133   add_transition.foo = 0;
134   add_transition[0] = new Object();  // For FAST_ELEMENT transition to be created
135   testExactMapHoisting3(new Array(5));
136   testExactMapHoisting3(new Array(5));  // Call twice to make sure that second
137                                         // store is a transition and not
138                                         // optimistically MONOMORPHIC
139   %OptimizeFunctionOnNextCall(testExactMapHoisting3);
140   testExactMapHoisting3(new Array(5));
141   testExactMapHoisting3(new Array(5));
142   assertOptimized(testExactMapHoisting3);
143   %ClearFunctionTypeFeedback(testExactMapHoisting3);
144
145   function testDominatingTransitionHoisting1(a) {
146     var object = new Object();
147     a[0] = 0;
148     var count = 3;
149     do {
150       if (a.baz != true) {
151         a[1] = 2.5;
152       }
153       a[0] = object;
154     } while (--count > 3);
155   }
156
157   /*
158   testDominatingTransitionHoisting1(new Array(5));
159   testDominatingTransitionHoisting1(new Array(5));  // Call twice to make sure
160                                                     // that second store is a
161                                                     // transition and not
162                                                     // optimistically MONOMORPHIC
163   %OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1);
164   testDominatingTransitionHoisting1(new Array(5));
165   testDominatingTransitionHoisting1(new Array(5));
166   // TODO(verwaest) With current changes the elements transition gets hoisted
167   // above the access, causing a deopt. We should update the type of access
168   // rather than forbid hoisting the transition.
169   assertOptimized(testDominatingTransitionHoisting1);
170   %ClearFunctionTypeFeedback(testDominatingTransitionHoisting1);
171   */
172
173   function testHoistingWithSideEffect(a) {
174     var object = new Object();
175     a[0] = 0;
176     var count = 3;
177     do {
178       assertTrue(true);
179       a[0] = object;
180     } while (--count > 3);
181   }
182
183   testHoistingWithSideEffect(new Array(5));
184   testHoistingWithSideEffect(new Array(5));  // Call twice to make sure that
185                                              // second store is a transition and
186                                              // not optimistically MONOMORPHIC
187   %OptimizeFunctionOnNextCall(testHoistingWithSideEffect);
188   testHoistingWithSideEffect(new Array(5));
189   testHoistingWithSideEffect(new Array(5));
190   assertOptimized(testHoistingWithSideEffect);
191   %ClearFunctionTypeFeedback(testHoistingWithSideEffect);
192
193   function testStraightLineDupeElinination(a,b,c,d,e,f) {
194     var count = 3;
195     do {
196       assertTrue(true);
197       a[0] = b;
198       a[1] = c;
199       a[2] = d;
200       assertTrue(true);
201       a[3] = e;  // TransitionElementsKind should be eliminated despite call.
202       a[4] = f;
203     } while (--count > 3);
204   }
205
206   testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,0,.5);
207   testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,.5,0);
208   testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,.5,0,0);
209   testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,.5,0,0,0);
210   testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),.5,0,0,0,0);
211   testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,0,.5);
212   testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,.5,0);
213   testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,.5,0,0);
214   testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,.5,0,0,0);
215   testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),.5,0,0,0,0);
216   testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
217   testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
218   testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
219   testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
220   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
221   testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
222   testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
223   testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
224   testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
225   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
226   %OptimizeFunctionOnNextCall(testStraightLineDupeElinination);
227   testStraightLineDupeElinination(new Array(5),0,0,0,0,0);
228   testStraightLineDupeElinination(new Array(5),0,0,0,0,0);
229   assertOptimized(testStraightLineDupeElinination);
230   %ClearFunctionTypeFeedback(testStraightLineDupeElinination);
231 }
232
233 // The test is called in a test wrapper that has type feedback cleared to
234 // prevent the influence of allocation-sites, which learn from transitions.
235 test_wrapper();
236 %ClearFunctionTypeFeedback(test_wrapper);