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: --optimize-for-in --allow-natives-syntax
29
// Flags: --no-concurrent-osr
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.
39
result.push(i + t[i]);
41
return result.join('');
44
// Check that we correctly deoptimize on map check.
48
result.push(i + t[i]);
51
return result.join('');
54
// Check that we correctly deoptimize during preparation step.
58
result.push(i + t[i]);
60
return result.join('');
63
// Check that we deoptimize to the place after side effect in the right state.
67
for (var i in (o = t())) {
68
result.push(i + o[i]);
70
return result.join('');
73
// Check that we correctly deoptimize on map check inserted for fused load.
79
result.push(i + t[i]);
81
return result.join('');
84
// Nested for-in loops.
89
result.push(i + j + t[i] + t[j]);
92
return result.join('');
95
// Deoptimization from the inner for-in loop.
100
result.push(i + j + t[i] + t[j]);
106
return result.join('');
110
// Break from the inner for-in loop.
111
function h(t, deopt) {
115
result.push(i + j + t[i] + t[j]);
120
return result.join('');
123
// Continue in the inner loop.
124
function j(t, deopt) {
128
result.push(i + j + t[i] + t[j]);
133
return result.join('');
136
// Continue of the outer loop.
137
function k(t, deopt) {
139
outer: for (var i in t) {
141
result.push(i + j + t[i] + t[j]);
146
return result.join('');
149
// Break of the outer loop.
150
function l(t, deopt) {
152
outer: for (var i in t) {
154
result.push(i + j + t[i] + t[j]);
159
return result.join('');
162
// Test deoptimization from inlined frame (currently it is not inlined).
163
function m0(t, deopt) {
167
return i + j + t[i] + t[j];
172
function m(t, deopt) {
177
function 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(), {}));
188
function mkTable() { return { a: "1", b: "2", c: "3", d: "4" }; }
191
tryFunction(s, mkTable, a);
192
tryFunction(s, mkTable, b);
193
tryFunction("0a1b2c3d", function () { return "abcd"; }, c);
194
tryFunction("0a1b2c3d", function () {
201
tryFunction("aabbccdd", mkTable, e);
203
function mkSmallTable() { return { a: "1", b: "2" }; }
205
tryFunction("aa11ab12ba21bb22", mkSmallTable, f);
206
tryFunction("aa11ab12bb22ba21", mkSmallTable, g);
207
tryFunction("aa11ba21", mkSmallTable, h);
208
tryFunction("aa11ab12ba21bb22", mkSmallTable, j);
209
tryFunction("aa11ba21", mkSmallTable, h);
210
tryFunction("aa11ba21", mkSmallTable, k);
211
tryFunction("aa11", mkSmallTable, l);
212
tryFunction("aa11", mkSmallTable, m);
214
// Test handling of null.
215
tryFunction("", function () {
216
return function () { return null; }
218
for (var i in t()) { return i; }
223
tryFunction("", function () {
224
return function () { return 11; }
226
for (var i in t()) { return i; }
230
// Test LoadFieldByIndex for out of object properties.
231
function O() { this.a = 1; }
232
for (var i = 0; i < 10; i++) new O();
233
tryFunction("a1b2c3d4e5f6", function () {
243
for (var i in t) r.push(i + t[i]);
247
// Test OSR inside for-in.
248
function osr_inner(t, limit) {
251
if (t.hasOwnProperty(x)) {
252
for (var i = 0; i < t[x].length; i++) {
254
if (i === limit) %OptimizeOsr();
262
function osr_outer(t, osr_after) {
265
for (var i = 0; i < t[x].length; i++) {
268
if (x === osr_after) %OptimizeOsr();
274
function osr_outer_and_deopt(t, osr_after) {
278
if (x == osr_after) %OptimizeOsr();
283
function test_osr() {
284
with ({}) {} // Disable optimizations of this function.
285
var arr = new Array(20);
286
for (var i = 0; i < arr.length; i++) {
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"));