blob: f3ff6beb0572e5b4a4077b1094fb61fa9a12f7c2 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// 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: --optimize-for-in --allow-natives-syntax
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029// Flags: --no-concurrent-osr
Ben Murdoch3ef787d2012-04-12 10:51:47 +010030
31// Test for-in support in Crankshaft. For simplicity this tests assumes certain
32// fixed iteration order for properties and will have to be adjusted if V8
33// stops following insertion order.
34
35
36function a(t) {
37 var result = [];
38 for (var i in t) {
39 result.push(i + t[i]);
40 }
41 return result.join('');
42}
43
44// Check that we correctly deoptimize on map check.
45function b(t) {
46 var result = [];
47 for (var i in t) {
48 result.push(i + t[i]);
49 delete t[i];
50 }
51 return result.join('');
52}
53
54// Check that we correctly deoptimize during preparation step.
55function c(t) {
56 var result = [];
57 for (var i in t) {
58 result.push(i + t[i]);
59 }
60 return result.join('');
61}
62
63// Check that we deoptimize to the place after side effect in the right state.
64function d(t) {
65 var result = [];
66 var o;
67 for (var i in (o = t())) {
68 result.push(i + o[i]);
69 }
70 return result.join('');
71}
72
73// Check that we correctly deoptimize on map check inserted for fused load.
74function e(t) {
75 var result = [];
76 for (var i in t) {
77 delete t[i];
78 t[i] = i;
79 result.push(i + t[i]);
80 }
81 return result.join('');
82}
83
84// Nested for-in loops.
85function f(t) {
86 var result = [];
87 for (var i in t) {
88 for (var j in t) {
89 result.push(i + j + t[i] + t[j]);
90 }
91 }
92 return result.join('');
93}
94
95// Deoptimization from the inner for-in loop.
96function g(t) {
97 var result = [];
98 for (var i in t) {
99 for (var j in t) {
100 result.push(i + j + t[i] + t[j]);
101 var v = t[i];
102 delete t[i];
103 t[i] = v;
104 }
105 }
106 return result.join('');
107}
108
109
110// Break from the inner for-in loop.
111function h(t, deopt) {
112 var result = [];
113 for (var i in t) {
114 for (var j in t) {
115 result.push(i + j + t[i] + t[j]);
116 break;
117 }
118 }
119 deopt.deopt;
120 return result.join('');
121}
122
123// Continue in the inner loop.
124function j(t, deopt) {
125 var result = [];
126 for (var i in t) {
127 for (var j in t) {
128 result.push(i + j + t[i] + t[j]);
129 continue;
130 }
131 }
132 deopt.deopt;
133 return result.join('');
134}
135
136// Continue of the outer loop.
137function k(t, deopt) {
138 var result = [];
139 outer: for (var i in t) {
140 for (var j in t) {
141 result.push(i + j + t[i] + t[j]);
142 continue outer;
143 }
144 }
145 deopt.deopt;
146 return result.join('');
147}
148
149// Break of the outer loop.
150function l(t, deopt) {
151 var result = [];
152 outer: for (var i in t) {
153 for (var j in t) {
154 result.push(i + j + t[i] + t[j]);
155 break outer;
156 }
157 }
158 deopt.deopt;
159 return result.join('');
160}
161
162// Test deoptimization from inlined frame (currently it is not inlined).
163function m0(t, deopt) {
164 for (var i in t) {
165 for (var j in t) {
166 deopt.deopt;
167 return i + j + t[i] + t[j];
168 }
169 }
170}
171
172function m(t, deopt) {
173 return m0(t, deopt);
174}
175
176
177function tryFunction(s, mkT, f) {
178 var d = {deopt: false};
179 assertEquals(s, f(mkT(), d));
180 assertEquals(s, f(mkT(), d));
181 assertEquals(s, f(mkT(), d));
182 %OptimizeFunctionOnNextCall(f);
183 assertEquals(s, f(mkT(), d));
184 assertEquals(s, f(mkT(), {}));
185}
186
187var s = "a1b2c3d4";
188function mkTable() { return { a: "1", b: "2", c: "3", d: "4" }; }
189
190
191tryFunction(s, mkTable, a);
192tryFunction(s, mkTable, b);
193tryFunction("0a1b2c3d", function () { return "abcd"; }, c);
194tryFunction("0a1b2c3d", function () {
195 var cnt = false;
196 return function () {
197 cnt = true;
198 return "abcd";
199 }
200}, d);
201tryFunction("aabbccdd", mkTable, e);
202
203function mkSmallTable() { return { a: "1", b: "2" }; }
204
205tryFunction("aa11ab12ba21bb22", mkSmallTable, f);
206tryFunction("aa11ab12bb22ba21", mkSmallTable, g);
207tryFunction("aa11ba21", mkSmallTable, h);
208tryFunction("aa11ab12ba21bb22", mkSmallTable, j);
209tryFunction("aa11ba21", mkSmallTable, h);
210tryFunction("aa11ba21", mkSmallTable, k);
211tryFunction("aa11", mkSmallTable, l);
212tryFunction("aa11", mkSmallTable, m);
213
214// Test handling of null.
215tryFunction("", function () {
216 return function () { return null; }
217}, function (t) {
218 for (var i in t()) { return i; }
219 return "";
220});
221
222// Test smis.
223tryFunction("", function () {
224 return function () { return 11; }
225}, function (t) {
226 for (var i in t()) { return i; }
227 return "";
228});
229
230// Test LoadFieldByIndex for out of object properties.
231function O() { this.a = 1; }
232for (var i = 0; i < 10; i++) new O();
233tryFunction("a1b2c3d4e5f6", function () {
234 var o = new O();
235 o.b = 2;
236 o.c = 3;
237 o.d = 4;
238 o.e = 5;
239 o.f = 6;
240 return o;
241}, function (t) {
242 var r = [];
243 for (var i in t) r.push(i + t[i]);
244 return r.join('');
245});
246
247// Test OSR inside for-in.
248function osr_inner(t, limit) {
249 var r = 1;
250 for (var x in t) {
251 if (t.hasOwnProperty(x)) {
252 for (var i = 0; i < t[x].length; i++) {
253 r += t[x][i];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000254 if (i === limit) %OptimizeOsr();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100255 }
256 r += x;
257 }
258 }
259 return r;
260}
261
262function osr_outer(t, osr_after) {
263 var r = 1;
264 for (var x in t) {
265 for (var i = 0; i < t[x].length; i++) {
266 r += t[x][i];
267 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000268 if (x === osr_after) %OptimizeOsr();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100269 r += x;
270 }
271 return r;
272}
273
274function osr_outer_and_deopt(t, osr_after) {
275 var r = 1;
276 for (var x in t) {
277 r += x;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 if (x == osr_after) %OptimizeOsr();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100279 }
280 return r;
281}
282
283function test_osr() {
284 with ({}) {} // Disable optimizations of this function.
285 var arr = new Array(20);
286 for (var i = 0; i < arr.length; i++) {
287 arr[i] = i + 1;
288 }
289 arr.push(":"); // Force deopt at the end of the loop.
290 assertEquals("211:x1234567891011121314151617181920:y", osr_inner({x: arr, y: arr}, (arr.length / 2) | 0));
291 assertEquals("7x456y", osr_outer({x: [1,2,3], y: [4,5,6]}, "x"));
292 assertEquals("101234567", osr_outer_and_deopt([1,2,3,4,5,6,7,8], "5"));
293}
294
295test_osr();