blob: 1337ab237a4cadd8a053e6e95d0d58ffff717ccb [file] [log] [blame]
Steve Block1e0659c2011-05-24 12:43:12 +01001// Copyright 2011 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028// Flags: --allow-natives-syntax --max-opt-count=100
Steve Block1e0659c2011-05-24 12:43:12 +010029
Ben Murdoch3ef787d2012-04-12 10:51:47 +010030function A() {
31}
Ben Murdoche0cee9b2011-05-25 10:26:03 +010032
Ben Murdoch3ef787d2012-04-12 10:51:47 +010033A.prototype.X = function (a, b, c) {
34 assertTrue(this instanceof A);
35 assertEquals(1, a);
36 assertEquals(2, b);
37 assertEquals(3, c);
38};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000039
Ben Murdoch3ef787d2012-04-12 10:51:47 +010040A.prototype.Y = function () {
41 this.X.apply(this, arguments);
42};
43
44A.prototype.Z = function () {
45 this.Y(1,2,3);
46};
47
48var a = new A();
49a.Z(4,5,6);
50a.Z(4,5,6);
51%OptimizeFunctionOnNextCall(a.Z);
52a.Z(4,5,6);
53A.prototype.X.apply = function (receiver, args) {
54 return Function.prototype.apply.call(this, receiver, args);
55};
56a.Z(4,5,6);
57
58
59// Ensure that HArgumentsObject is inserted in a correct place
60// and dominates all uses.
61function F1() { }
62function F2() { F1.apply(this, arguments); }
63function F3(x, y) {
64 if (x) {
65 F2(y);
66 }
67}
68
69function F31() {
70 return F1.apply(this, arguments);
71}
72
73function F4() {
74 F3(true, false);
75 return F31(1);
76}
77
78F4(1);
79F4(1);
80F4(1);
81%OptimizeFunctionOnNextCall(F4);
82F4(1);
83
84
85// Test correct adapation of arguments.
86// Strict mode prevents arguments object from shadowing parameters.
87(function () {
88 "use strict";
89
90 function G2() {
91 assertArrayEquals([1,2], arguments);
92 }
93
94 function G4() {
95 assertArrayEquals([1,2,3,4], arguments);
96 }
97
98 function adapt2to4(a, b, c, d) {
99 G2.apply(this, arguments);
100 }
101
102 function adapt4to2(a, b) {
103 G4.apply(this, arguments);
104 }
105
106 function test_adaptation() {
107 adapt2to4(1, 2);
108 adapt4to2(1, 2, 3, 4);
109 }
110
111 test_adaptation();
112 test_adaptation();
113 %OptimizeFunctionOnNextCall(test_adaptation);
114 test_adaptation();
115})();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000116
117// Test arguments access from the inlined function.
118%NeverOptimizeFunction(uninlinable);
119function uninlinable(v) {
120 assertEquals(0, v);
121 return 0;
122}
123
124function toarr_inner() {
125 var a = arguments;
126 var marker = a[0];
127 uninlinable(uninlinable(0, 0), marker.x);
128
129 var r = new Array();
130 for (var i = a.length - 1; i >= 1; i--) {
131 r.push(a[i]);
132 }
133
134 return r;
135}
136
137function toarr1(marker, a, b, c) {
138 return toarr_inner(marker, a / 2, b / 2, c / 2);
139}
140
141function toarr2(marker, a, b, c) {
142 var x = 0;
143 return uninlinable(uninlinable(0, 0),
144 x = toarr_inner(marker, a / 2, b / 2, c / 2)), x;
145}
146
147function test_toarr(toarr) {
148 var marker = { x: 0 };
149 assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6));
150 assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6));
151 %OptimizeFunctionOnNextCall(toarr);
152 assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6));
153 delete marker.x;
154 assertArrayEquals([3, 2, 1], toarr(marker, 2, 4, 6));
155}
156
157test_toarr(toarr1);
158test_toarr(toarr2);
159
160
161// Test that arguments access from inlined function uses correct values.
162(function () {
163 function inner(x, y) {
164 "use strict";
165 x = 10;
166 y = 20;
167 for (var i = 0; i < 1; i++) {
168 for (var j = 1; j <= arguments.length; j++) {
169 return arguments[arguments.length - j];
170 }
171 }
172 }
173
174 function outer(x, y) {
175 return inner(x, y);
176 }
177
178 %OptimizeFunctionOnNextCall(outer);
179 %OptimizeFunctionOnNextCall(inner);
180 assertEquals(2, outer(1, 2));
181})();
182
183
184(function () {
185 function inner(x, y) {
186 "use strict";
187 x = 10;
188 y = 20;
189 for (var i = 0; i < 1; i++) {
190 for (var j = 1; j <= arguments.length; j++) {
191 return arguments[arguments.length - j];
192 }
193 }
194 }
195
196 function outer(x, y) {
197 return inner(x, y);
198 }
199
200 assertEquals(2, outer(1, 2));
201 assertEquals(2, outer(1, 2));
202 assertEquals(2, outer(1, 2));
203 %OptimizeFunctionOnNextCall(outer);
204 assertEquals(2, outer(1, 2));
205})();
206
207
208// Test inlining and deoptimization of functions accessing and modifying
209// the arguments object in strict mode with mismatched arguments count.
210(function () {
211 "use strict";
212 function test(outerCount, middleCount, innerCount) {
213 var forceDeopt = { deopt:false };
214 function inner(x,y) {
215 x = 0; y = 0;
216 forceDeopt.deopt;
217 assertSame(innerCount, arguments.length);
218 for (var i = 0; i < arguments.length; i++) {
219 assertSame(30 + i, arguments[i]);
220 }
221 }
222
223 function middle(x,y) {
224 x = 0; y = 0;
225 if (innerCount == 1) inner(30);
226 if (innerCount == 2) inner(30, 31);
227 if (innerCount == 3) inner(30, 31, 32);
228 assertSame(middleCount, arguments.length);
229 for (var i = 0; i < arguments.length; i++) {
230 assertSame(20 + i, arguments[i]);
231 }
232 }
233
234 function outer(x,y) {
235 x = 0; y = 0;
236 if (middleCount == 1) middle(20);
237 if (middleCount == 2) middle(20, 21);
238 if (middleCount == 3) middle(20, 21, 22);
239 assertSame(outerCount, arguments.length);
240 for (var i = 0; i < arguments.length; i++) {
241 assertSame(10 + i, arguments[i]);
242 }
243 }
244
245 for (var step = 0; step < 4; step++) {
246 if (outerCount == 1) outer(10);
247 if (outerCount == 2) outer(10, 11);
248 if (outerCount == 3) outer(10, 11, 12);
249 if (step == 1) %OptimizeFunctionOnNextCall(outer);
250 if (step == 2) delete forceDeopt.deopt;
251 }
252
253 %DeoptimizeFunction(outer);
254 %DeoptimizeFunction(middle);
255 %DeoptimizeFunction(inner);
256 %ClearFunctionTypeFeedback(outer);
257 %ClearFunctionTypeFeedback(middle);
258 %ClearFunctionTypeFeedback(inner);
259 }
260
261 for (var a = 1; a <= 3; a++) {
262 for (var b = 1; b <= 3; b++) {
263 for (var c = 1; c <= 3; c++) {
264 test(a,b,c);
265 }
266 }
267 }
268})();
269
270
271// Test materialization of arguments object with values in registers.
272(function () {
273 "use strict";
274 var forceDeopt = { deopt:false };
275 function inner(a,b,c,d,e,f,g,h,i,j) {
276 var args = arguments;
277 forceDeopt.deopt;
278 assertSame(10, args.length);
279 assertSame(a, args[0]);
280 assertSame(b, args[1]);
281 assertSame(c, args[2]);
282 assertSame(d, args[3]);
283 assertSame(e, args[4]);
284 assertSame(f, args[5]);
285 assertSame(g, args[6]);
286 assertSame(h, args[7]);
287 assertSame(i, args[8]);
288 assertSame(j, args[9]);
289 }
290
291 var a = 0.5;
292 var b = 1.7;
293 var c = 123;
294 function outer() {
295 inner(
296 a - 0.3, // double in double register
297 b + 2.3, // integer in double register
298 c + 321, // integer in general register
299 c - 456, // integer in stack slot
300 a + 0.1, a + 0.2, a + 0.3, a + 0.4, a + 0.5,
301 a + 0.6 // double in stack slot
302 );
303 }
304
305 outer();
306 outer();
307 %OptimizeFunctionOnNextCall(outer);
308 outer();
309 delete forceDeopt.deopt;
310 outer();
311})();