1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions of source code must retain the above copyright
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       notice, this list of conditions and the following disclaimer.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions in binary form must reproduce the above
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       copyright notice, this list of conditions and the following
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       disclaimer in the documentation and/or other materials provided
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       with the distribution.
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Neither the name of Google Inc. nor the names of its
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       contributors may be used to endorse or promote products derived
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       from this software without specific prior written permission.
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test stores on a join path.
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testJoin() {
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 0;
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function join(mode, expected) {
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var object = new constructor();
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (mode) {
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object.a = 1;
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object.a = 2;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(expected, object.a);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  join(true, 1); join(true, 1);
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  join(false, 2); join(false, 2);
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(join);
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  join(true, 1); join(false, 2);
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test loads and stores inside a loop.
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testLoop() {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 0;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = 23;
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function loop() {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var object = new constructor();
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 1; i < 10; i++) {
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object.a = object.a + i;
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i*(i+1)/2, object.a);
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(23, object.b);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(45, object.a);
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, object.b);
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  loop(); loop();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(loop);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  loop(); loop();
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test loads and stores inside nested loop.
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testNested() {
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 0;
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = 0;
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.c = 23;
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function nested() {
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var object = new constructor();
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 1; i < 10; i++) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object.a = object.a + i;
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i*(i+1)/2, object.a);
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals((i-1)*6, object.b);
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(23, object.c);
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (var j = 1; j < 4; j++) {
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        object.b = object.b + j;
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assertEquals(i*(i+1)/2, object.a);
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assertEquals((i-1)*6+j*(j+1)/2, object.b);
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assertEquals(23, object.c);
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i*(i+1)/2, object.a);
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(i*6, object.b);
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(23, object.c);
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(45, object.a);
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(54, object.b);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, object.c);
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nested(); nested();
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(nested);
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  nested(); nested();
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test deoptimization with captured objects in local variables.
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testDeoptLocal() {
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var deopt = { deopt:false };
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor1() {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 1.0;
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = 2.3;
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.c = 3.0;
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor2(o) {
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.d = o;
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.e = 4.5;
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function func() {
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o1 = new constructor1();
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o2 = new constructor2(o1);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt.deopt;
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1.0, o1.a);
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2.3, o2.d.b);
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3.0, o2.d.c);
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4.5, o2.e);
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(func);
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete deopt.deopt;
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test deoptimization with captured objects on operand stack.
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testDeoptOperand() {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var deopt = { deopt:false };
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor1() {
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 1.0;
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = 2.3;
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt.deopt;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1.0, this.a);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2.3, this.b);
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = 2.7;
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.c = 3.0;
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.d = 4.5;
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor2() {
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.e = 5.0;
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.f = new constructor1();
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1.0, this.f.a);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2.7, this.f.b);
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3.0, this.f.c);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4.5, this.f.d);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5.0, this.e);
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.e = 5.9;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.g = 6.7;
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function func() {
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor2();
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1.0, o.f.a);
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(2.7, o.f.b);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3.0, o.f.c);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(4.5, o.f.d);
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(5.9, o.e);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(6.7, o.g);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(func);
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete deopt.deopt;
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  func(); func();
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test map checks on captured objects.
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testMapCheck() {
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var sum = 0;
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function getter() { return 27; }
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function setter(v) { sum += v; }
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = 23;
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.y = 42;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function check(x, y) {
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor();
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(x, o.x);
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(y, o.y);
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var monkey = Object.create(null, {
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x: { get:getter, set:setter },
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    y: { get:getter, set:setter }
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  });
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(23, 42); check(23, 42);
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(check);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(23, 42); check(23, 42);
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  constructor.prototype = monkey;
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(27, 27); check(27, 27);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(130, sum);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test OSR into a loop with captured objects.
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testOSR() {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 23;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function osr1(length) {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, (new constructor()).a);
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var result = 0;
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < length; i++) {
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result = (result + i) % 99;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function osr2(length) {
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var result = 0;
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < length; i++) {
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result = (result + i) % 99;
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, (new constructor()).a);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function osr3(length) {
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var result = 0;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor();
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (var i = 0; i < length; i++) {
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result = (result + i) % 99;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, o.a);
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function test(closure) {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(45, closure(10));
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(45, closure(10));
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(10, closure(50000));
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test(osr1);
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test(osr2);
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test(osr3);
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test out-of-bounds access on captured objects.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testOOB() {
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function cons1() {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = 1;
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.y = 2;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.z = 3;
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function cons2() {
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 7;
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function oob(constructor, branch) {
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor();
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (branch) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return o.a;
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return o.z;
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(3, oob(cons1, false));
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(3, oob(cons1, false));
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(7, oob(cons2, true));
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(7, oob(cons2, true));
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  gc();  // Clears type feedback of constructor call.
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(7, oob(cons2, true));
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(7, oob(cons2, true));
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(oob);
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assertEquals(7, oob(cons2, true));
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test non-shallow nested graph of captured objects.
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testDeep() {
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var deopt = { deopt:false };
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor1() {
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = 23;
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor2(nested) {
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 17;
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = nested;
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.c = 42;
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function deep() {
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o1 = new constructor1();
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o2 = new constructor2(o1);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(17, o2.a);
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, o2.b.x);
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(42, o2.c);
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o1.x = 99;
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt.deopt;
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(99, o1.x);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(99, o2.b.x);
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(); deep();
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(deep);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(); deep();
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete deopt.deopt;
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(); deep();
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test non-shallow nested graph of captured objects with duplicates
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testDeepDuplicate() {
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor1() {
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = 23;
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor2(nested) {
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.a = 17;
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.b = nested;
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.c = 42;
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function deep(shouldDeopt) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o1 = new constructor1();
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o2 = new constructor2(o1);
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o3 = new constructor2(o1);
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(17, o2.a);
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(23, o2.b.x);
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(42, o2.c);
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o3.c = 54;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o1.x = 99;
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shouldDeopt) %DeoptimizeFunction(deep);
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(99, o1.x);
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(99, o2.b.x);
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(99, o3.b.x);
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(54, o3.c);
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(17, o3.a);
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(42, o2.c);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(17, o2.a);
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o3.b.x = 1;
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(1, o1.x);
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(false); deep(false);
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(deep);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(false); deep(false);
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  deep(true); deep(true);
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test non-shallow nested graph of captured objects with inline
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testDeepInline() {
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function h() {
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return { y : 3 };
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function g(x) {
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var u = { x : h() };
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    %DeoptimizeFunction(f);
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return u;
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function f() {
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var l = { dummy : { } };
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var r = g(l);
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(3, r.x.y);
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f(); f(); f();
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(f);
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f();
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test two nested objects
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testTwoNestedObjects() {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function f() {
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var l = { x : { y : 111 } };
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var l2 = { x : { y : 111 } };
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    %DeoptimizeFunction(f);
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(111, l.x.y);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(111, l2.x.y);
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f(); f(); f();
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(f);
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f();
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test a nested object and a duplicate
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testTwoObjectsWithDuplicate() {
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function f() {
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var l = { x : { y : 111 } };
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var dummy = { d : 0 };
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var l2 = l.x;
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    %DeoptimizeFunction(f);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(111, l.x.y);
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(111, l2.y);
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(0, dummy.d);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f(); f(); f();
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(f);
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  f();
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test materialization of a field that requires a Smi value.
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testSmiField() {
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var deopt = { deopt:false };
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = 1;
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function field(x) {
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor();
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o.x = x;
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt.deopt
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(x, o.x);
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field(1); field(2);
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(field);
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field(3); field(4);
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete deopt.deopt;
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field(5.5); field(6.5);
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test materialization of a field that requires a heap object value.
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch(function testHeapObjectField() {
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var deopt = { deopt:false };
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function constructor() {
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    this.x = {};
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function field(x) {
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    var o = new constructor();
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    o.x = x;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deopt.deopt
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(x, o.x);
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field({}); field({});
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(field);
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field({}); field({});
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete deopt.deopt;
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  field(1); field(2);
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch})();
439