blob: 19b96bad504afd5277650e147da1e7566da59417 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
11using namespace v8::internal;
12using 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.
16static 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 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028 CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(),
29 topmost->GetInlineCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030}
31
32
33static void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
34 v8::Local<v8::Context> context = isolate->GetCurrentContext();
35 v8::Local<v8::FunctionTemplate> t =
36 v8::FunctionTemplate::New(isolate, AssertInlineCount);
37 context->Global()->Set(v8_str("AssertInlineCount"), t->GetFunction());
38}
39
40
Emily Bernierd0a1eb72015-03-24 16:35:39 -040041static uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
42 CompilationInfo::kContextSpecializing |
43 CompilationInfo::kTypingEnabled;
44
45
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046TEST(SimpleInlining) {
47 FLAG_turbo_deoptimization = true;
48 FunctionTester T(
49 "(function(){"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050 " function foo(s) { AssertInlineCount(2); return s; };"
51 " function bar(s, t) { return foo(s); };"
52 " return bar;"
53 "})();",
54 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055
56 InstallAssertInlineCountHelper(CcTest::isolate());
57 T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
58}
59
60
61TEST(SimpleInliningDeopt) {
62 FLAG_turbo_deoptimization = true;
63 FunctionTester T(
64 "(function(){"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040065 " function foo(s) { %DeoptimizeFunction(bar); return s; };"
66 " function bar(s, t) { return foo(s); };"
67 " return bar;"
68 "})();",
69 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070
71 InstallAssertInlineCountHelper(CcTest::isolate());
72 T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
73}
74
75
76TEST(SimpleInliningContext) {
77 FLAG_turbo_deoptimization = true;
78 FunctionTester T(
79 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040080 " function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
81 " function bar(s, t) { return foo(s); };"
82 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085
86 InstallAssertInlineCountHelper(CcTest::isolate());
87 T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
88}
89
90
91TEST(SimpleInliningContextDeopt) {
92 FLAG_turbo_deoptimization = true;
93 FunctionTester T(
94 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095 " function foo(s) {"
96 " AssertInlineCount(2); %DeoptimizeFunction(bar); var x = 12;"
97 " return s + x;"
98 " };"
99 " function bar(s, t) { return foo(s); };"
100 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400102 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103
104 InstallAssertInlineCountHelper(CcTest::isolate());
105 T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
106}
107
108
109TEST(CaptureContext) {
110 FLAG_turbo_deoptimization = true;
111 FunctionTester T(
112 "var f = (function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 " var x = 42;"
114 " function bar(s) { return x + s; };"
115 " return (function (s) { return bar(s); });"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000116 "})();"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117 "(function (s) { return f(s) })",
118 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119
120 InstallAssertInlineCountHelper(CcTest::isolate());
121 T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
122}
123
124
125// TODO(sigurds) For now we do not inline any native functions. If we do at
126// some point, change this test.
127TEST(DontInlineEval) {
128 FLAG_turbo_deoptimization = true;
129 FunctionTester T(
130 "var x = 42;"
131 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 " function bar(s, t) { return eval(\"AssertInlineCount(1); x\") };"
133 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400135 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136
137 InstallAssertInlineCountHelper(CcTest::isolate());
138 T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
139}
140
141
142TEST(InlineOmitArguments) {
143 FLAG_turbo_deoptimization = true;
144 FunctionTester T(
145 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400146 " var x = 42;"
147 " function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
148 " return (function (s,t) { return bar(s); });"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400150 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151
152 InstallAssertInlineCountHelper(CcTest::isolate());
153 T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
154}
155
156
157TEST(InlineOmitArgumentsDeopt) {
158 FLAG_turbo_deoptimization = true;
159 FunctionTester T(
160 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400161 " function foo(s,t,u,v) { AssertInlineCount(2);"
162 " %DeoptimizeFunction(bar); return baz(); };"
163 " function bar() { return foo(11); };"
164 " function baz() { return foo.arguments.length == 1 &&"
165 " foo.arguments[0] == 11; }"
166 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169
170 InstallAssertInlineCountHelper(CcTest::isolate());
171 T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
172}
173
174
175TEST(InlineSurplusArguments) {
176 FLAG_turbo_deoptimization = true;
177 FunctionTester T(
178 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179 " var x = 42;"
180 " function foo(s) { AssertInlineCount(2); return x + s; };"
181 " function bar(s,t) { return foo(s,t,13); };"
182 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
186 InstallAssertInlineCountHelper(CcTest::isolate());
187 T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
188}
189
190
191TEST(InlineSurplusArgumentsDeopt) {
192 FLAG_turbo_deoptimization = true;
193 FunctionTester T(
194 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195 " function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
196 " return baz(); };"
197 " function bar() { return foo(13, 14, 15); };"
198 " function baz() { return foo.arguments.length == 3 &&"
199 " foo.arguments[0] == 13 &&"
200 " foo.arguments[1] == 14 &&"
201 " foo.arguments[2] == 15; }"
202 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400204 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000205
206 InstallAssertInlineCountHelper(CcTest::isolate());
207 T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
208}
209
210
211TEST(InlineTwice) {
212 FLAG_turbo_deoptimization = true;
213 FunctionTester T(
214 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215 " var x = 42;"
216 " function bar(s) { AssertInlineCount(2); return x + s; };"
217 " return (function (s,t) { return bar(s) + bar(t); });"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400219 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220
221 InstallAssertInlineCountHelper(CcTest::isolate());
222 T.CheckCall(T.Val(2 * 42 + 12 + 4), T.Val(12), T.Val(4));
223}
224
225
226TEST(InlineTwiceDependent) {
227 FLAG_turbo_deoptimization = true;
228 FunctionTester T(
229 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400230 " var x = 42;"
231 " function foo(s) { AssertInlineCount(2); return x + s; };"
232 " function bar(s,t) { return foo(foo(s)); };"
233 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400235 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236
237 InstallAssertInlineCountHelper(CcTest::isolate());
238 T.CheckCall(T.Val(42 + 42 + 12), T.Val(12), T.Val(4));
239}
240
241
242TEST(InlineTwiceDependentDiamond) {
243 FLAG_turbo_deoptimization = true;
244 FunctionTester T(
245 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400246 " var x = 41;"
247 " function foo(s) { AssertInlineCount(2); if (s % 2 == 0) {"
248 " return x - s } else { return x + s; } };"
249 " function bar(s,t) { return foo(foo(s)); };"
250 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000251 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253
254 InstallAssertInlineCountHelper(CcTest::isolate());
255 T.CheckCall(T.Val(-11), T.Val(11), T.Val(4));
256}
257
258
259TEST(InlineTwiceDependentDiamondDifferent) {
260 FLAG_turbo_deoptimization = true;
261 FunctionTester T(
262 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400263 " var x = 41;"
264 " function foo(s,t) { AssertInlineCount(2); if (s % 2 == 0) {"
265 " return x - s * t } else { return x + s * t; } };"
266 " function bar(s,t) { return foo(foo(s, 3), 5); };"
267 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000268 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400269 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270
271 InstallAssertInlineCountHelper(CcTest::isolate());
272 T.CheckCall(T.Val(-329), T.Val(11), T.Val(4));
273}
274
275
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400276TEST(InlineLoopGuardedEmpty) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277 FLAG_turbo_deoptimization = true;
278 FunctionTester T(
279 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400280 " function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
281 " function bar(s,t) { return foo(s); };"
282 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000283 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400284 kInlineFlags);
285
286 InstallAssertInlineCountHelper(CcTest::isolate());
287 T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
288}
289
290
291TEST(InlineLoopGuardedOnce) {
292 FLAG_turbo_deoptimization = true;
293 FunctionTester T(
294 "(function () {"
295 " function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
296 " s = s - 1; }; return s; };"
297 " function bar(s,t) { return foo(s,t); };"
298 " return bar;"
299 "})();",
300 kInlineFlags);
301
302 InstallAssertInlineCountHelper(CcTest::isolate());
303 T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
304}
305
306
307TEST(InlineLoopGuardedTwice) {
308 FLAG_turbo_deoptimization = true;
309 FunctionTester T(
310 "(function () {"
311 " function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
312 " s = s - 1; }; return s; };"
313 " function bar(s,t) { return foo(foo(s,t),t); };"
314 " return bar;"
315 "})();",
316 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000317
318 InstallAssertInlineCountHelper(CcTest::isolate());
319 T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
320}
321
322
323TEST(InlineStrictIntoNonStrict) {
324 FLAG_turbo_deoptimization = true;
325 FunctionTester T(
326 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400327 " var x = Object.create({}, { y: { value:42, writable:false } });"
328 " function foo(s) { 'use strict';"
329 " x.y = 9; };"
330 " function bar(s,t) { return foo(s); };"
331 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000332 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400333 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334
335 InstallAssertInlineCountHelper(CcTest::isolate());
336 T.CheckThrows(T.undefined(), T.undefined());
337}
338
339
340TEST(InlineNonStrictIntoStrict) {
341 FLAG_turbo_deoptimization = true;
342 FunctionTester T(
343 "(function () {"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400344 " var x = Object.create({}, { y: { value:42, writable:false } });"
345 " function foo(s) { x.y = 9; return x.y; };"
346 " function bar(s,t) { \'use strict\'; return foo(s); };"
347 " return bar;"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 "})();",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400349 kInlineFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000350
351 InstallAssertInlineCountHelper(CcTest::isolate());
352 T.CheckCall(T.Val(42), T.undefined(), T.undefined());
353}
354
355
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400356TEST(InlineIntrinsicIsSmi) {
357 FLAG_turbo_deoptimization = true;
358 FunctionTester T(
359 "(function () {"
360 " var x = 42;"
361 " function bar(s,t) { return %_IsSmi(x); };"
362 " return bar;"
363 "})();",
364 kInlineFlags);
365
366 InstallAssertInlineCountHelper(CcTest::isolate());
367 T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
368}
369
370
371TEST(InlineIntrinsicIsNonNegativeSmi) {
372 FLAG_turbo_deoptimization = true;
373 FunctionTester T(
374 "(function () {"
375 " var x = 42;"
376 " function bar(s,t) { return %_IsNonNegativeSmi(x); };"
377 " return bar;"
378 "})();",
379 kInlineFlags);
380
381 InstallAssertInlineCountHelper(CcTest::isolate());
382 T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
383}
384
385
386TEST(InlineIntrinsicIsArray) {
387 FLAG_turbo_deoptimization = true;
388 FunctionTester T(
389 "(function () {"
390 " var x = [1,2,3];"
391 " function bar(s,t) { return %_IsArray(x); };"
392 " return bar;"
393 "})();",
394 kInlineFlags);
395
396 InstallAssertInlineCountHelper(CcTest::isolate());
397 T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
398
399 FunctionTester T2(
400 "(function () {"
401 " var x = 32;"
402 " function bar(s,t) { return %_IsArray(x); };"
403 " return bar;"
404 "})();",
405 kInlineFlags);
406
407 T2.CheckCall(T.false_value(), T.Val(12), T.Val(4));
408
409 FunctionTester T3(
410 "(function () {"
411 " var x = bar;"
412 " function bar(s,t) { return %_IsArray(x); };"
413 " return bar;"
414 "})();",
415 kInlineFlags);
416
417 T3.CheckCall(T.false_value(), T.Val(12), T.Val(4));
418}
419
420
421TEST(InlineWithArguments) {
422 FLAG_turbo_deoptimization = true;
423 FunctionTester T(
424 "(function () {"
425 " function foo(s,t,u) { AssertInlineCount(2);"
426 " return foo.arguments.length == 3 &&"
427 " foo.arguments[0] == 13 &&"
428 " foo.arguments[1] == 14 &&"
429 " foo.arguments[2] == 15;"
430 " }"
431 " function bar() { return foo(13, 14, 15); };"
432 " return bar;"
433 "})();",
434 kInlineFlags);
435
436 InstallAssertInlineCountHelper(CcTest::isolate());
437 T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
438}
439
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000440#endif // V8_TURBOFAN_TARGET