Skip to content

Commit 76c3ac5

Browse files
fhinkelCommit Bot
authored andcommitted
[cpu-profiler] Fix script name when recording inlining info
Use the script name from the shared function info to create an inline entry. Otherwise functions are attributed to the wrong file in the CpuProfileNode. See googleapis/cloud-profiler-nodejs#89 Bug: v8:7203, v8:7241 Change-Id: I8ea31943741770e6611275a9c93375922b934547 Reviewed-on: https://chromium-review.googlesource.com/848093 Reviewed-by: Jaroslav Sevcik <[email protected]> Commit-Queue: Franziska Hinkelmann <[email protected]> Cr-Commit-Position: refs/heads/master@{#50339}
1 parent 10a8ae4 commit 76c3ac5

2 files changed

Lines changed: 87 additions & 1 deletion

File tree

src/profiler/profiler-listener.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,16 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
213213
SharedFunctionInfo* shared_info = SharedFunctionInfo::cast(
214214
deopt_input_data->LiteralArray()->get(shared_info_id));
215215
if (!depth++) continue; // Skip the current function itself.
216+
217+
const char* resource_name =
218+
(shared_info->script()->IsScript() &&
219+
Script::cast(shared_info->script())->name()->IsName())
220+
? GetName(Name::cast(Script::cast(shared_info->script())->name()))
221+
: CodeEntry::kEmptyResourceName;
222+
216223
CodeEntry* inline_entry =
217224
new CodeEntry(entry->tag(), GetFunctionName(shared_info->DebugName()),
218-
CodeEntry::kEmptyNamePrefix, entry->resource_name(),
225+
CodeEntry::kEmptyNamePrefix, resource_name,
219226
CpuProfileNode::kNoLineNumberInfo,
220227
CpuProfileNode::kNoColumnNumberInfo, nullptr,
221228
code->instruction_start());

test/cctest/test-cpu-profiler.cc

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,85 @@ TEST(FunctionDetails) {
17411741
script_a->GetUnboundScript()->GetId(), 5, 14);
17421742
}
17431743

1744+
TEST(FunctionDetailsInlining) {
1745+
if (!CcTest::i_isolate()->use_optimizer() || i::FLAG_always_opt) return;
1746+
i::FLAG_allow_natives_syntax = true;
1747+
v8::HandleScope scope(CcTest::isolate());
1748+
v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION);
1749+
v8::Context::Scope context_scope(env);
1750+
ProfilerHelper helper(env);
1751+
1752+
// alpha is in a_script, beta in b_script. beta is
1753+
// inlined in alpha, but it should be attributed to b_script.
1754+
1755+
v8::Local<v8::Script> script_b = CompileWithOrigin(
1756+
"function beta(k) {\n"
1757+
" let sum = 2;\n"
1758+
" for(let i = 0; i < k; i ++) {\n"
1759+
" sum += i;\n"
1760+
" sum = sum + 'a';\n"
1761+
" }\n"
1762+
" return sum;\n"
1763+
"}\n"
1764+
"\n",
1765+
"script_b");
1766+
1767+
v8::Local<v8::Script> script_a = CompileWithOrigin(
1768+
"function alpha(p) {\n"
1769+
" let res = beta(p);\n"
1770+
" res = res + res;\n"
1771+
" return res;\n"
1772+
"}\n"
1773+
"let p = 2;\n"
1774+
"\n"
1775+
"\n"
1776+
"// Warm up before profiling or the inlining doesn't happen.\n"
1777+
"p = alpha(p);\n"
1778+
"p = alpha(p);\n"
1779+
"%OptimizeFunctionOnNextCall(alpha);\n"
1780+
"p = alpha(p);\n"
1781+
"\n"
1782+
"\n"
1783+
"startProfiling();\n"
1784+
"for(let i = 0; i < 10000; i++) {\n"
1785+
" p = alpha(p);\n"
1786+
"}\n"
1787+
"stopProfiling();\n"
1788+
"\n"
1789+
"\n",
1790+
"script_a");
1791+
1792+
script_b->Run(env).ToLocalChecked();
1793+
script_a->Run(env).ToLocalChecked();
1794+
1795+
const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
1796+
const v8::CpuProfileNode* current = profile->GetTopDownRoot();
1797+
reinterpret_cast<ProfileNode*>(const_cast<v8::CpuProfileNode*>(current))
1798+
->Print(0);
1799+
// The tree should look like this:
1800+
// 0 (root) 0 #1
1801+
// 5 (program) 0 #6
1802+
// 2 14 #2 script_a:1
1803+
// ;;; deopted at script_id: 14 position: 299 with reason 'Insufficient
1804+
// type feedback for call'.
1805+
// 1 alpha 14 #4 script_a:1
1806+
// 9 beta 13 #5 script_b:0
1807+
// 0 startProfiling 0 #3
1808+
1809+
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
1810+
const v8::CpuProfileNode* script = GetChild(env, root, "");
1811+
CheckFunctionDetails(env->GetIsolate(), script, "", "script_a",
1812+
script_a->GetUnboundScript()->GetId(), 1, 1);
1813+
const v8::CpuProfileNode* alpha = FindChild(env, script, "alpha");
1814+
// Return early if profiling didn't sample alpha.
1815+
if (!alpha) return;
1816+
CheckFunctionDetails(env->GetIsolate(), alpha, "alpha", "script_a",
1817+
script_a->GetUnboundScript()->GetId(), 1, 15);
1818+
const v8::CpuProfileNode* beta = FindChild(env, alpha, "beta");
1819+
if (!beta) return;
1820+
CheckFunctionDetails(env->GetIsolate(), beta, "beta", "script_b",
1821+
script_b->GetUnboundScript()->GetId(), 0, 0);
1822+
}
17441823

17451824
TEST(DontStopOnFinishedProfileDelete) {
17461825
v8::HandleScope scope(CcTest::isolate());

0 commit comments

Comments
 (0)