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
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.
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.
28 // Flags: --allow-natives-syntax
29 // Flags: --nostress-opt
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.
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
39 function testDoubleConversion4(a) {
40 var object = new Object();
45 } while (--count > 0);
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);
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();
68 a.foo = object; // This map check should be hoistable
70 result = a.foo == object && a[1] == object;
71 } while (--count > 0);
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);
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
87 function testExactMapHoisting2(a) {
88 var object = new Object();
94 if (a.bar === undefined) {
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
102 } while (--count > 0);
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);
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();
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);
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);
145 function testDominatingTransitionHoisting1(a) {
146 var object = new Object();
154 } while (--count > 3);
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);
173 function testHoistingWithSideEffect(a) {
174 var object = new Object();
180 } while (--count > 3);
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);
193 function testStraightLineDupeElinination(a,b,c,d,e,f) {
201 a[3] = e; // TransitionElementsKind should be eliminated despite call.
203 } while (--count > 3);
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);
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.
236 %ClearFunctionTypeFeedback(test_wrapper);