1// Copyright 2013 the V8 project authors. All rights reserved.
2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1.  Redistributions of source code must retain the above copyright
8//     notice, this list of conditions and the following disclaimer.
9// 2.  Redistributions in binary form must reproduce the above copyright
10//     notice, this list of conditions and the following disclaimer in the
11//     documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24description(
25"This tests that register allocation still works under register pressure induced by inlining, out-of-line function calls (i.e. unconditional register flushing), and slow paths for object creation (i.e. conditional register flushing)."
26);
27
28// Inlineable constructor.
29function foo(a, b, c) {
30    this.a = a;
31    this.b = b;
32    this.c = c;
33}
34
35// Non-inlineable function. This relies on a size limit for inlining, but still
36// produces integers. It also relies on the VM not reasoning about Math.log deeply
37// enough to find some way of optimizing this code to be small enough to inline.
38function bar(a, b) {
39    a += b;
40    a -= b;
41    b ^= a;
42    a += Math.log(b);
43    b += a;
44    b -= a;
45    a ^= b;
46    a += b;
47    a -= b;
48    b ^= a;
49    a += Math.log(b);
50    b += a;
51    b -= a;
52    a ^= b;
53    a += b;
54    a -= b;
55    b ^= a;
56    a += Math.log(b);
57    b += a;
58    b -= a;
59    a ^= b;
60    a += b;
61    a -= b;
62    b ^= a;
63    a += Math.log(b);
64    b += a;
65    b -= a;
66    a ^= b;
67    a += b;
68    a -= b;
69    b ^= a;
70    a += Math.log(b);
71    b += a;
72    b -= a;
73    a ^= b;
74    a += b;
75    a -= b;
76    b ^= a;
77    a += Math.log(b);
78    b += a;
79    b -= a;
80    a ^= b;
81    a += b;
82    a -= b;
83    b ^= a;
84    a += Math.log(b);
85    b += a;
86    b -= a;
87    a ^= b;
88    a += b;
89    a -= b;
90    b ^= a;
91    a += Math.log(b);
92    b += a;
93    b -= a;
94    a ^= b;
95    a += b;
96    a -= b;
97    b ^= a;
98    a += Math.log(b);
99    b += a;
100    b -= a;
101    a ^= b;
102    a += b;
103    a -= b;
104    b ^= a;
105    a += Math.log(b);
106    b += a;
107    b -= a;
108    a ^= b;
109    a += b;
110    a -= b;
111    b ^= a;
112    a += Math.log(b);
113    b += a;
114    b -= a;
115    a ^= b;
116    a += b;
117    a -= b;
118    b ^= a;
119    a += Math.log(b);
120    b += a;
121    b -= a;
122    a ^= b;
123    a += b;
124    a -= b;
125    b ^= a;
126    a += Math.log(b);
127    b += a;
128    b -= a;
129    a ^= b;
130    a += b;
131    a -= b;
132    b ^= a;
133    a += Math.log(b);
134    b += a;
135    b -= a;
136    a ^= b;
137    a += b;
138    a -= b;
139    b ^= a;
140    a += Math.log(b);
141    b += a;
142    b -= a;
143    a ^= b;
144    a += b;
145    a -= b;
146    b ^= a;
147    a += Math.log(b);
148    b += a;
149    b -= a;
150    a ^= b;
151    return (a - b) | 0;
152}
153
154// Function into which we will inline foo but not bar.
155function baz(a, b) {
156    return new foo(bar(2 * a + 1, b - 1), bar(2 * a, b - 1), a);
157}
158
159// Do the test. It's crucial that o.a, o.b, and o.c are checked on each
160// loop iteration.
161for (var i = 0; i < 1000; ++i) {
162    var o = baz(i, i + 1);
163    shouldBe("o.a", "bar(2 * i + 1, i)");
164    shouldBe("o.b", "bar(2 * i, i)");
165    shouldBe("o.c", "i");
166}
167