1// Copyright 2010 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: --allow-natives-syntax
29
30// Test deopt with count operation on parameter.
31var max_smi = 1073741823;
32var o = {x:0};
33
34function inc1(x) { x++; o.x = x; }
35inc1(max_smi);
36assertEquals(max_smi + 1, o.x);
37
38inc1(1.1);
39assertEquals(2.1, o.x);
40
41
42// Test deopt with count operation on named property.
43function inc2(p) { p.x++ }
44
45o.x = "42";
46inc2(o);
47assertEquals(43, o.x);
48
49var s = max_smi - 10;
50o.x = s;
51for(var i = 0; i < 20; i++) {
52  inc2(o);
53  if (i == 4) {
54    %OptimizeFunctionOnNextCall(inc2);
55  }
56}
57assertEquals(max_smi + 10, o.x);
58
59
60// Test deopt with count operation on keyed property.
61function inc3(a, b) { a[b]++; }
62
63o = ["42"];
64inc3(o, 0);
65assertEquals(43, o[0]);
66
67var s = max_smi - 10;
68o[0] = s;
69for(var i = 0; i < 20; i++) {
70  inc3(o, 0);
71  if (i == 4) {
72    %OptimizeFunctionOnNextCall(inc3);
73  }
74}
75assertEquals(max_smi + 10, o[0]);
76
77inc3(o,"0");
78
79assertEquals(max_smi + 11, o[0]);
80
81// Test bailout when accessing a non-existing array element.
82o[0] = 0;
83for(var i = 0; i < 5; i++) {
84  inc3(o, 0);
85}
86%OptimizeFunctionOnNextCall(inc3);
87inc3(o, 0);
88inc3(o, 1);
89
90// Test bailout with count operation in a value context.
91function inc4(x,y) { return (x++) + y; }
92for (var i = 0; i < 5; ++i) assertEquals(3, inc4(2, 1));
93%OptimizeFunctionOnNextCall(inc4);
94inc4(2, 1);
95assertEquals(3.1, inc4(2, 1.1));
96
97function inc5(x,y) { return (++x) + y; }
98for (var i = 0; i < 5; ++i) assertEquals(4, inc5(2, 1));
99%OptimizeFunctionOnNextCall(inc5);
100assertEquals(4, inc5(2, 1));
101assertEquals(4.1, inc5(2, 1.1));
102assertEquals(4.1, inc5(2.1, 1));
103
104function inc6(o,y) { return (o.x++) + y; }
105o = {x:0};
106for (var i = 0; i < 5; ++i) {
107  o.x = 42;
108  assertEquals(43, inc6(o, 1));
109}
110%OptimizeFunctionOnNextCall(inc6);
111o.x = 42;
112assertEquals(43, inc6(o, 1));
113o.x = 42;
114assertEquals(43.1, inc6(o, 1.1));
115o.x = 42.1;
116assertEquals(43.1, inc6(o, 1));
117
118function inc7(o,y) { return (++o.x) + y; }
119o = {x:0};
120for (var i = 0; i < 5; ++i) {
121  o.x = 42;
122  assertEquals(44, inc7(o, 1));
123}
124%OptimizeFunctionOnNextCall(inc7);
125o.x = 42;
126assertEquals(44, inc7(o, 1));
127o.x = 42;
128assertEquals(44.1, inc7(o, 1.1));
129o.x = 42.1;
130assertEquals(44.1, inc7(o, 1));
131
132function inc8(o,y) { return (o[0]++) + y; }
133var q = [0];
134for (var i = 0; i < 5; ++i) {
135  q[0] = 42;
136  assertEquals(43, inc8(q, 1));
137}
138%OptimizeFunctionOnNextCall(inc8);
139q[0] = 42;
140assertEquals(43, inc8(q, 1));
141q[0] = 42;
142assertEquals(43.1, inc8(q, 1.1));
143q[0] = 42.1;
144assertEquals(43.1, inc8(q, 1));
145
146function inc9(o,y) { return (++o[0]) + y; }
147q = [0];
148for (var i = 0; i < 5; ++i) {
149  q[0] = 42;
150  assertEquals(44, inc9(q, 1));
151}
152%OptimizeFunctionOnNextCall(inc9);
153q[0] = 42;
154assertEquals(44, inc9(q, 1));
155q[0] = 42;
156assertEquals(44.1, inc9(q, 1.1));
157q[0] = 42.1;
158assertEquals(44.1, inc9(q, 1));
159
160// Test deopt because of a failed map check.
161function inc10(p) { return p.x++ }
162var g1 = {x:0};
163var g2 = {y:0, x:42}
164for (var i = 0; i < 5; ++i) {
165  g1.x = 42;
166  assertEquals(42, inc10(g1));
167  assertEquals(43, g1.x);
168}
169%OptimizeFunctionOnNextCall(inc10);
170g1.x = 42;
171assertEquals(42, inc10(g1));
172assertEquals(43, g1.x);
173assertEquals(42, inc10(g2));
174assertEquals(43, g2.x);
175
176// Test deoptimization with postfix operation in a value context.
177function inc11(a) { return a[this.x++]; }
178var g3 = {x:null, f:inc11};
179var g4 = [42];
180assertEquals(42, g3.f(g4));
181