blob: 9f229d2e17bbd863bd0b1909ab0e4c017b24a77b [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002// 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028// Flags: --allow-natives-syntax
29// Flags: --nostress-opt
Ben Murdoch3ef787d2012-04-12 10:51:47 +010030
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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035function test_wrapper() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010036 // 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));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049 testDoubleConversion4(new Array(5)); // Call twice to make sure that second
50 // store is a transition and not
51 // optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +010052 %OptimizeFunctionOnNextCall(testDoubleConversion4);
53 testDoubleConversion4(new Array(5));
54 testDoubleConversion4(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055 assertOptimized(testDoubleConversion4);
56 %ClearFunctionTypeFeedback(testDoubleConversion4);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010057
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();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 a.foo = {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +010064 a[0] = 0;
65 a[1] = 1;
66 var count = 3;
67 do {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 a.foo = object; // This map check should be hoistable
Ben Murdoch3ef787d2012-04-12 10:51:47 +010069 a[1] = object;
70 result = a.foo == object && a[1] == object;
71 } while (--count > 0);
72 }
73
74 testExactMapHoisting(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 testExactMapHoisting(new Array(5)); // Call twice to make sure that second
76 // store is a transition and not
77 // optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +010078 %OptimizeFunctionOnNextCall(testExactMapHoisting);
79 testExactMapHoisting(new Array(5));
80 testExactMapHoisting(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 assertOptimized(testExactMapHoisting);
82 %ClearFunctionTypeFeedback(testExactMapHoisting);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010083
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 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097 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.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100102 } while (--count > 0);
103 }
104
105 testExactMapHoisting2(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 testExactMapHoisting2(new Array(5)); // Call twice to make sure that second
107 // store is a transition and not
108 // optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100109 %OptimizeFunctionOnNextCall(testExactMapHoisting2);
110 testExactMapHoisting2(new Array(5));
111 testExactMapHoisting2(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 // Temporarily disabled - see bug 2176.
113 // assertOptimized(testExactMapHoisting2);
114 %ClearFunctionTypeFeedback(testExactMapHoisting2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100115
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();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 a.foo = null;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100122 a[0] = 0;
123 a[1] = 1;
124 var count = 3;
125 do {
126 a[1] = 2.5;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 a.foo = object; // This map check should be hoistable because all elements
128 // transitions in the loop can also be hoisted.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100129 } while (--count > 0);
130 }
131
132 var add_transition = new Array(5);
133 add_transition.foo = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 add_transition[0] = new Object(); // For FAST_ELEMENT transition to be created
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100135 testExactMapHoisting3(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 testExactMapHoisting3(new Array(5)); // Call twice to make sure that second
137 // store is a transition and not
138 // optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100139 %OptimizeFunctionOnNextCall(testExactMapHoisting3);
140 testExactMapHoisting3(new Array(5));
141 testExactMapHoisting3(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 assertOptimized(testExactMapHoisting3);
143 %ClearFunctionTypeFeedback(testExactMapHoisting3);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100144
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
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 /*
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100158 testDominatingTransitionHoisting1(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159 testDominatingTransitionHoisting1(new Array(5)); // Call twice to make sure
160 // that second store is a
161 // transition and not
162 // optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100163 %OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1);
164 testDominatingTransitionHoisting1(new Array(5));
165 testDominatingTransitionHoisting1(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166 // 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 */
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100172
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));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 testHoistingWithSideEffect(new Array(5)); // Call twice to make sure that
185 // second store is a transition and
186 // not optimistically MONOMORPHIC
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100187 %OptimizeFunctionOnNextCall(testHoistingWithSideEffect);
188 testHoistingWithSideEffect(new Array(5));
189 testHoistingWithSideEffect(new Array(5));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 assertOptimized(testHoistingWithSideEffect);
191 %ClearFunctionTypeFeedback(testHoistingWithSideEffect);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100192
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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201 a[3] = e; // TransitionElementsKind should be eliminated despite call.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100202 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000227 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);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100231}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000232
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.
235test_wrapper();
236%ClearFunctionTypeFeedback(test_wrapper);