Index: test/cctest/test-cpu-profiler.cc |
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc |
index e1f7e6adb912515d45d7a5d733703cf6d8e05f42..79ac32e4e2c7fe426fdad77898a00f97e621424c 100644 |
--- a/test/cctest/test-cpu-profiler.cc |
+++ b/test/cctest/test-cpu-profiler.cc |
@@ -1504,6 +1504,68 @@ TEST(JsNativeJsRuntimeJsSampleMultiple) { |
profile->Delete(); |
} |
+static const char* inlining_test_source = |
+ "%NeverOptimizeFunction(action);\n" |
+ "%NeverOptimizeFunction(start);\n" |
+ "%OptimizeFunctionOnNextCall(level1);\n" |
+ "%OptimizeFunctionOnNextCall(level2);\n" |
+ "%OptimizeFunctionOnNextCall(level3);\n" |
+ "var finish = false;\n" |
+ "function action(n) {\n" |
+ " var s = 0;\n" |
+ " for (var i = 0; i < n; ++i) s += i*i*i;\n" |
+ " if (finish)\n" |
+ " startProfiling('my_profile');\n" |
+ " return s;\n" |
+ "}\n" |
+ "function level3() { return action(100); }\n" |
+ "function level2() { return level3() * 2; }\n" |
+ "function level1() { return level2(); }\n" |
+ "function start() {\n" |
+ " var n = 100;\n" |
+ " while (--n)\n" |
+ " level1();\n" |
+ " finish = true;\n" |
+ " level1();\n" |
+ "}"; |
+ |
+// The test check multiple entrances/exits between JS and native code. |
+// |
+// [Top down]: |
+// (root) #0 1 |
+// start #16 3 |
+// level1 #0 4 |
+// level2 #16 5 |
+// level3 #16 6 |
+// action #16 7 |
+// (program) #0 2 |
+TEST(Inlining) { |
+ i::FLAG_allow_natives_syntax = true; |
+ v8::HandleScope scope(CcTest::isolate()); |
+ v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); |
+ v8::Context::Scope context_scope(env); |
+ |
+ CompileRun(inlining_test_source); |
+ v8::Local<v8::Function> function = GetFunction(env, "start"); |
+ |
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); |
+ v8::Local<v8::String> profile_name = v8_str("my_profile"); |
+ function->Call(env, env->Global(), 0, NULL).ToLocalChecked(); |
+ v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name); |
+ CHECK(profile); |
+ // Dump collected profile to have a better diagnostic in case of failure. |
+ reinterpret_cast<i::CpuProfile*>(profile)->Print(); |
+ |
+ const v8::CpuProfileNode* root = profile->GetTopDownRoot(); |
+ const v8::CpuProfileNode* start_node = GetChild(env, root, "start"); |
+ const v8::CpuProfileNode* level1_node = GetChild(env, start_node, "level1"); |
+ const v8::CpuProfileNode* level2_node = GetChild(env, level1_node, "level2"); |
+ const v8::CpuProfileNode* level3_node = GetChild(env, level2_node, "level3"); |
+ GetChild(env, level3_node, "action"); |
+ |
+ profile->Delete(); |
+} |
+ |
// [Top down]: |
// 0 (root) #0 1 |
// 2 (program) #0 2 |