Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / compiler / test-run-inlining.cc
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "test/cctest/compiler/function-tester.h"
8
9 #if V8_TURBOFAN_TARGET
10
11 using namespace v8::internal;
12 using namespace v8::internal::compiler;
13
14 // Helper to determine inline count via JavaScriptFrame::GetInlineCount.
15 // Note that a count of 1 indicates that no inlining has occured.
16 static void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
17   StackTraceFrameIterator it(CcTest::i_isolate());
18   int frames_seen = 0;
19   JavaScriptFrame* topmost = it.frame();
20   while (!it.done()) {
21     JavaScriptFrame* frame = it.frame();
22     PrintF("%d %s, inline count: %d\n", frames_seen,
23            frame->function()->shared()->DebugName()->ToCString().get(),
24            frame->GetInlineCount());
25     frames_seen++;
26     it.Advance();
27   }
28   CHECK_EQ(args[0]->ToInt32()->Value(), topmost->GetInlineCount());
29 }
30
31
32 static void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
33   v8::Local<v8::Context> context = isolate->GetCurrentContext();
34   v8::Local<v8::FunctionTemplate> t =
35       v8::FunctionTemplate::New(isolate, AssertInlineCount);
36   context->Global()->Set(v8_str("AssertInlineCount"), t->GetFunction());
37 }
38
39
40 TEST(SimpleInlining) {
41   FLAG_turbo_deoptimization = true;
42   FunctionTester T(
43       "(function(){"
44       "function foo(s) { AssertInlineCount(2); return s; };"
45       "function bar(s, t) { return foo(s); };"
46       "return bar;})();",
47       CompilationInfo::kInliningEnabled |
48           CompilationInfo::kContextSpecializing |
49           CompilationInfo::kTypingEnabled);
50
51   InstallAssertInlineCountHelper(CcTest::isolate());
52   T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
53 }
54
55
56 TEST(SimpleInliningDeopt) {
57   FLAG_turbo_deoptimization = true;
58   FunctionTester T(
59       "(function(){"
60       "function foo(s) { %DeoptimizeFunction(bar); return "
61       "s; };"
62       "function bar(s, t) { return foo(s); };"
63       "return bar;})();",
64       CompilationInfo::kInliningEnabled |
65           CompilationInfo::kContextSpecializing |
66           CompilationInfo::kTypingEnabled);
67
68   InstallAssertInlineCountHelper(CcTest::isolate());
69   T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
70 }
71
72
73 TEST(SimpleInliningContext) {
74   FLAG_turbo_deoptimization = true;
75   FunctionTester T(
76       "(function () {"
77       "function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
78       "function bar(s, t) { return foo(s); };"
79       "return bar;"
80       "})();",
81       CompilationInfo::kInliningEnabled |
82           CompilationInfo::kContextSpecializing |
83           CompilationInfo::kTypingEnabled);
84
85   InstallAssertInlineCountHelper(CcTest::isolate());
86   T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
87 }
88
89
90 TEST(SimpleInliningContextDeopt) {
91   FLAG_turbo_deoptimization = true;
92   FunctionTester T(
93       "(function () {"
94       "function foo(s) { "
95       "  AssertInlineCount(2); %DeoptimizeFunction(bar); var x = 12;"
96       "  return s + x;"
97       "};"
98       "function bar(s, t) { return foo(s); };"
99       "return bar;"
100       "})();",
101       CompilationInfo::kInliningEnabled |
102           CompilationInfo::kContextSpecializing |
103           CompilationInfo::kTypingEnabled);
104
105   InstallAssertInlineCountHelper(CcTest::isolate());
106   T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
107 }
108
109
110 TEST(CaptureContext) {
111   FLAG_turbo_deoptimization = true;
112   FunctionTester T(
113       "var f = (function () {"
114       "var x = 42;"
115       "function bar(s) { return x + s; };"
116       "return (function (s) { return bar(s); });"
117       "})();"
118       "(function (s) { return f(s)})",
119       CompilationInfo::kInliningEnabled |
120           CompilationInfo::kContextSpecializing |
121           CompilationInfo::kTypingEnabled);
122
123   InstallAssertInlineCountHelper(CcTest::isolate());
124   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
125 }
126
127
128 // TODO(sigurds) For now we do not inline any native functions. If we do at
129 // some point, change this test.
130 TEST(DontInlineEval) {
131   FLAG_turbo_deoptimization = true;
132   FunctionTester T(
133       "var x = 42;"
134       "(function () {"
135       "function bar(s, t) { return eval(\"AssertInlineCount(1); x\") };"
136       "return bar;"
137       "})();",
138       CompilationInfo::kInliningEnabled |
139           CompilationInfo::kContextSpecializing |
140           CompilationInfo::kTypingEnabled);
141
142   InstallAssertInlineCountHelper(CcTest::isolate());
143   T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
144 }
145
146
147 TEST(InlineOmitArguments) {
148   FLAG_turbo_deoptimization = true;
149   FunctionTester T(
150       "(function () {"
151       "var x = 42;"
152       "function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
153       "return (function (s,t) { return bar(s); });"
154       "})();",
155       CompilationInfo::kInliningEnabled |
156           CompilationInfo::kContextSpecializing |
157           CompilationInfo::kTypingEnabled);
158
159   InstallAssertInlineCountHelper(CcTest::isolate());
160   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
161 }
162
163
164 TEST(InlineOmitArgumentsDeopt) {
165   FLAG_turbo_deoptimization = true;
166   FunctionTester T(
167       "(function () {"
168       "function foo(s,t,u,v) { AssertInlineCount(2); %DeoptimizeFunction(bar); "
169       "return baz(); };"
170       "function bar() { return foo(11); };"
171       "function baz() { return foo.arguments.length == 1 && "
172       "                        foo.arguments[0] == 11 ; }"
173       "return bar;"
174       "})();",
175       CompilationInfo::kInliningEnabled |
176           CompilationInfo::kContextSpecializing |
177           CompilationInfo::kTypingEnabled);
178
179   InstallAssertInlineCountHelper(CcTest::isolate());
180   T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
181 }
182
183
184 TEST(InlineSurplusArguments) {
185   FLAG_turbo_deoptimization = true;
186   FunctionTester T(
187       "(function () {"
188       "var x = 42;"
189       "function foo(s) { AssertInlineCount(2); return x + s; };"
190       "function bar(s,t) { return foo(s,t,13); };"
191       "return bar;"
192       "})();",
193       CompilationInfo::kInliningEnabled |
194           CompilationInfo::kContextSpecializing |
195           CompilationInfo::kTypingEnabled);
196
197   InstallAssertInlineCountHelper(CcTest::isolate());
198   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
199 }
200
201
202 TEST(InlineSurplusArgumentsDeopt) {
203   FLAG_turbo_deoptimization = true;
204   FunctionTester T(
205       "(function () {"
206       "function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar); "
207       "return baz(); };"
208       "function bar() { return foo(13, 14, 15); };"
209       "function baz() { return foo.arguments.length == 3 && "
210       "                        foo.arguments[0] == 13 && "
211       "                        foo.arguments[1] == 14 && "
212       "                        foo.arguments[2] == 15; }"
213       "return bar;"
214       "})();",
215       CompilationInfo::kInliningEnabled |
216           CompilationInfo::kContextSpecializing |
217           CompilationInfo::kTypingEnabled);
218
219   InstallAssertInlineCountHelper(CcTest::isolate());
220   T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
221 }
222
223
224 TEST(InlineTwice) {
225   FLAG_turbo_deoptimization = true;
226   FunctionTester T(
227       "(function () {"
228       "var x = 42;"
229       "function bar(s) { AssertInlineCount(2); return x + s; };"
230       "return (function (s,t) { return bar(s) + bar(t); });"
231       "})();",
232       CompilationInfo::kInliningEnabled |
233           CompilationInfo::kContextSpecializing |
234           CompilationInfo::kTypingEnabled);
235
236   InstallAssertInlineCountHelper(CcTest::isolate());
237   T.CheckCall(T.Val(2 * 42 + 12 + 4), T.Val(12), T.Val(4));
238 }
239
240
241 TEST(InlineTwiceDependent) {
242   FLAG_turbo_deoptimization = true;
243   FunctionTester T(
244       "(function () {"
245       "var x = 42;"
246       "function foo(s) { AssertInlineCount(2); return x + s; };"
247       "function bar(s,t) { return foo(foo(s)); };"
248       "return bar;"
249       "})();",
250       CompilationInfo::kInliningEnabled |
251           CompilationInfo::kContextSpecializing |
252           CompilationInfo::kTypingEnabled);
253
254   InstallAssertInlineCountHelper(CcTest::isolate());
255   T.CheckCall(T.Val(42 + 42 + 12), T.Val(12), T.Val(4));
256 }
257
258
259 TEST(InlineTwiceDependentDiamond) {
260   FLAG_turbo_deoptimization = true;
261   FunctionTester T(
262       "(function () {"
263       "var x = 41;"
264       "function foo(s) { AssertInlineCount(2); if (s % 2 == 0) {"
265       "                  return x - s } else { return x + s; } };"
266       "function bar(s,t) { return foo(foo(s)); };"
267       "return bar;"
268       "})();",
269       CompilationInfo::kInliningEnabled |
270           CompilationInfo::kContextSpecializing |
271           CompilationInfo::kTypingEnabled);
272
273   InstallAssertInlineCountHelper(CcTest::isolate());
274   T.CheckCall(T.Val(-11), T.Val(11), T.Val(4));
275 }
276
277
278 TEST(InlineTwiceDependentDiamondDifferent) {
279   FLAG_turbo_deoptimization = true;
280   FunctionTester T(
281       "(function () {"
282       "var x = 41;"
283       "function foo(s,t) { AssertInlineCount(2); if (s % 2 == 0) {"
284       "                    return x - s * t } else { return x + s * t; } };"
285       "function bar(s,t) { return foo(foo(s, 3), 5); };"
286       "return bar;"
287       "})();",
288       CompilationInfo::kInliningEnabled |
289           CompilationInfo::kContextSpecializing |
290           CompilationInfo::kTypingEnabled);
291
292   InstallAssertInlineCountHelper(CcTest::isolate());
293   T.CheckCall(T.Val(-329), T.Val(11), T.Val(4));
294 }
295
296
297 TEST(InlineLoop) {
298   FLAG_turbo_deoptimization = true;
299   FunctionTester T(
300       "(function () {"
301       "var x = 41;"
302       "function foo(s) { AssertInlineCount(2); while (s > 0) {"
303       "                  s = s - 1; }; return s; };"
304       "function bar(s,t) { return foo(foo(s)); };"
305       "return bar;"
306       "})();",
307       CompilationInfo::kInliningEnabled |
308           CompilationInfo::kContextSpecializing |
309           CompilationInfo::kTypingEnabled);
310
311   InstallAssertInlineCountHelper(CcTest::isolate());
312   T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
313 }
314
315
316 TEST(InlineStrictIntoNonStrict) {
317   FLAG_turbo_deoptimization = true;
318   FunctionTester T(
319       "(function () {"
320       "var x = Object.create({}, { y: { value:42, writable:false } });"
321       "function foo(s) { 'use strict';"
322       "                   x.y = 9; };"
323       "function bar(s,t) { return foo(s); };"
324       "return bar;"
325       "})();",
326       CompilationInfo::kInliningEnabled |
327           CompilationInfo::kContextSpecializing |
328           CompilationInfo::kTypingEnabled);
329
330   InstallAssertInlineCountHelper(CcTest::isolate());
331   T.CheckThrows(T.undefined(), T.undefined());
332 }
333
334
335 TEST(InlineNonStrictIntoStrict) {
336   FLAG_turbo_deoptimization = true;
337   FunctionTester T(
338       "(function () {"
339       "var x = Object.create({}, { y: { value:42, writable:false } });"
340       "function foo(s) { x.y = 9; return x.y; };"
341       "function bar(s,t) { \'use strict\'; return foo(s); };"
342       "return bar;"
343       "})();",
344       CompilationInfo::kInliningEnabled |
345           CompilationInfo::kContextSpecializing |
346           CompilationInfo::kTypingEnabled);
347
348   InstallAssertInlineCountHelper(CcTest::isolate());
349   T.CheckCall(T.Val(42), T.undefined(), T.undefined());
350 }
351
352
353 #endif  // V8_TURBOFAN_TARGET