Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1543)

Unified Diff: test/cctest/test-cpu-profiler.cc

Issue 1013143003: CpuProfiler: push the collected information about deopts to cpu profiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: comments addressed Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/compiler.h ('K') | « src/profile-generator.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-cpu-profiler.cc
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 249221d192f8fe42c9403cbaed2d94ab00dcaa07..a8cbdd505cfe0626de7669c6d952a5cccd8dca52 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -56,6 +56,11 @@ static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) {
}
+static int offset(const char* src, const char* substring) {
+ return static_cast<int>(strstr(src, substring) - src);
+}
+
+
static const char* reason(const i::Deoptimizer::DeoptReason reason) {
return i::Deoptimizer::GetDeoptReason(reason);
}
@@ -1714,7 +1719,7 @@ const char* GetBranchDeoptReason(i::CpuProfile* iprofile, const char* branch[],
v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
const ProfileNode* iopt_function = NULL;
iopt_function = GetSimpleBranch(profile, branch, length);
- CHECK_EQ(1, iopt_function->deopt_infos().length());
+ CHECK_EQ(1, iopt_function->deopt_infos().size());
return iopt_function->deopt_infos()[0].deopt_reason;
}
@@ -1777,6 +1782,24 @@ TEST(CollectDeoptEvents) {
v8::Script::Compile(v8_str(source))->Run();
i::CpuProfile* iprofile = iprofiler->GetProfile(0);
iprofile->Print();
+ /* The expected profile
+ [Top down]:
+ 0 (root) 0 #1
+ 23 32 #2
+ 1 opt_function2 31 #7
+ 1 opt_function2 31 #8
+ ;;; deopted at script_id: 31 position: 106 with reason
+ 'division by zero'.
+ 2 opt_function0 29 #3
+ 4 opt_function0 29 #4
+ ;;; deopted at script_id: 29 position: 108 with reason 'not a
+ heap number'.
+ 0 opt_function1 30 #5
+ 1 opt_function1 30 #6
+ ;;; deopted at script_id: 30 position: 108 with reason 'lost
+ precision or NaN'.
+ */
+
{
const char* branch[] = {"", "opt_function0", "opt_function0"};
CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber),
@@ -1814,3 +1837,197 @@ TEST(SourceLocation) {
v8::Script::Compile(v8_str(source))->Run();
}
+
+
+static const char* inlined_source =
+ "function opt_function(left, right) { var k = left / 10; var r = 10 / "
+ "right; return k + r; }\n";
+// 0.........1.........2.........3.........4....*....5.........6......*..7
+
+
+// deopt at the first level inlined function
+TEST(DeoptAtFirstLevelInlinedSource) {
+ if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
+ 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);
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
+ i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
+
+ // 0.........1.........2.........3.........4.........5.........6.........7
+ const char* source =
+ "function test(left, right) { return opt_function(left, right); }\n"
+ "\n"
+ "startProfiling();\n"
+ "\n"
+ "test(10, 10);\n"
+ "\n"
+ "%OptimizeFunctionOnNextCall(test)\n"
+ "\n"
+ "test(10, 10);\n"
+ "\n"
+ "test(undefined, 10);\n"
+ "\n"
+ "stopProfiling();\n"
+ "\n";
+
+ v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
+ inlined_script->Run();
+ int inlined_script_id = inlined_script->GetUnboundScript()->GetId();
+
+ v8::Handle<v8::Script> script = v8_compile(source);
+ script->Run();
+ int script_id = script->GetUnboundScript()->GetId();
+
+ i::CpuProfile* iprofile = iprofiler->GetProfile(0);
+ iprofile->Print();
+ /* The expected profile output
+ [Top down]:
+ 0 (root) 0 #1
+ 10 30 #2
+ 1 test 30 #3
+ ;;; deopted at script_id: 29 position: 45 with reason 'not a
+ heap number'.
+ ;;; Inline point: script_id 30 position: 36.
+ 4 opt_function 29 #4
+ */
+ v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
+
+ const char* branch[] = {"", "test"};
+ const ProfileNode* itest_node =
+ GetSimpleBranch(profile, branch, arraysize(branch));
+ const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos();
+ CHECK_EQ(1, deopt_infos.size());
+
+ const i::DeoptInfo& info = deopt_infos[0];
+ CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
+ CHECK_EQ(2, info.stack.size());
+ CHECK_EQ(inlined_script_id, info.stack[0].script_id);
+ CHECK_EQ(offset(inlined_source, "left /"), info.stack[0].position);
+ CHECK_EQ(script_id, info.stack[1].script_id);
+ CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position);
+
+ iprofiler->DeleteProfile(iprofile);
+}
+
+
+// deopt at the second level inlined function
+TEST(DeoptAtSecondLevelInlinedSource) {
+ if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
+ 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);
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
+ i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
+
+ // 0.........1.........2.........3.........4.........5.........6.........7
+ const char* source =
+ "function test2(left, right) { return opt_function(left, right); }\n"
+ "function test1(left, right) { return test2(left, right); }\n"
+ "\n"
+ "startProfiling();\n"
+ "\n"
+ "test1(10, 10);\n"
+ "\n"
+ "%OptimizeFunctionOnNextCall(test1)\n"
+ "\n"
+ "test1(10, 10);\n"
+ "\n"
+ "test1(undefined, 10);\n"
+ "\n"
+ "stopProfiling();\n"
+ "\n";
+
+ v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
+ inlined_script->Run();
+ int inlined_script_id = inlined_script->GetUnboundScript()->GetId();
+
+ v8::Handle<v8::Script> script = v8_compile(source);
+ script->Run();
+ int script_id = script->GetUnboundScript()->GetId();
+
+ i::CpuProfile* iprofile = iprofiler->GetProfile(0);
+ iprofile->Print();
+ /* The expected profile output
+ [Top down]:
+ 0 (root) 0 #1
+ 11 30 #2
+ 1 test1 30 #3
+ ;;; deopted at script_id: 29 position: 45 with reason 'not a
+ heap number'.
+ ;;; Inline point: script_id 30 position: 37.
+ ;;; Inline point: script_id 30 position: 103.
+ 1 test2 30 #4
+ 3 opt_function 29 #5
+ */
+
+ v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
+
+ const char* branch[] = {"", "test1"};
+ const ProfileNode* itest_node =
+ GetSimpleBranch(profile, branch, arraysize(branch));
+ const std::vector<i::DeoptInfo>& deopt_infos = itest_node->deopt_infos();
+ CHECK_EQ(1, deopt_infos.size());
+
+ const i::DeoptInfo info = deopt_infos[0];
+ CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), info.deopt_reason);
+ CHECK_EQ(3, info.stack.size());
+ CHECK_EQ(inlined_script_id, info.stack[0].script_id);
+ CHECK_EQ(offset(inlined_source, "left /"), info.stack[0].position);
+ CHECK_EQ(script_id, info.stack[1].script_id);
+ CHECK_EQ(offset(source, "opt_function(left,"), info.stack[1].position);
+ CHECK_EQ(offset(source, "test2(left, right);"), info.stack[2].position);
+
+ iprofiler->DeleteProfile(iprofile);
+}
+
+
+// deopt in untracked function
+TEST(DeoptUntrackedFunction) {
+ if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return;
+ 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);
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::CpuProfiler* profiler = isolate->GetCpuProfiler();
+ i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler);
+
+ // 0.........1.........2.........3.........4.........5.........6.........7
+ const char* source =
+ "function test(left, right) { return opt_function(left, right); }\n"
+ "\n"
+ "test(10, 10);\n"
+ "\n"
+ "%OptimizeFunctionOnNextCall(test)\n"
+ "\n"
+ "test(10, 10);\n"
+ "\n"
+ "startProfiling();\n" // profiler started after compilation.
+ "\n"
+ "test(undefined, 10);\n"
+ "\n"
+ "stopProfiling();\n"
+ "\n";
+
+ v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source);
+ inlined_script->Run();
+
+ v8::Handle<v8::Script> script = v8_compile(source);
+ script->Run();
+
+ i::CpuProfile* iprofile = iprofiler->GetProfile(0);
+ iprofile->Print();
+ v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile);
+
+ const char* branch[] = {"", "test"};
+ const ProfileNode* itest_node =
+ GetSimpleBranch(profile, branch, arraysize(branch));
+ CHECK_EQ(0, itest_node->deopt_infos().size());
+
+ iprofiler->DeleteProfile(iprofile);
+}
« src/compiler.h ('K') | « src/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698