Skip to content

Commit 00687fb

Browse files
committed
deps: V8: backport 76c3ac5 from upstream
This fixes a bug in the CPU profiler where some ticks were attributed to the wrong file. Original commit message: [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@{nodejs#50339} Refs: v8/v8@76c3ac5 PR-URL: nodejs#18298 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 98d9540 commit 00687fb

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
# Reset this number to 0 on major V8 upgrades.
2929
# Increment by one for each non-official patch applied to deps/v8.
30-
'v8_embedder_string': '-node.8',
30+
'v8_embedder_string': '-node.9',
3131

3232
# Enable disassembler for `--print-code` v8 options
3333
'v8_enable_disassembler': 1,

deps/v8/src/profiler/profiler-listener.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,18 @@ void ProfilerListener::RecordInliningInfo(CodeEntry* entry,
230230
SharedFunctionInfo* shared_info = SharedFunctionInfo::cast(
231231
deopt_input_data->LiteralArray()->get(shared_info_id));
232232
if (!depth++) continue; // Skip the current function itself.
233-
CodeEntry* inline_entry = new CodeEntry(
234-
entry->tag(), GetFunctionName(shared_info->DebugName()),
235-
CodeEntry::kEmptyNamePrefix, entry->resource_name(),
236-
CpuProfileNode::kNoLineNumberInfo,
237-
CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
233+
const char* resource_name =
234+
(shared_info->script()->IsScript() &&
235+
Script::cast(shared_info->script())->name()->IsName())
236+
? GetName(Name::cast(Script::cast(shared_info->script())->name()))
237+
: CodeEntry::kEmptyResourceName;
238+
239+
CodeEntry* inline_entry =
240+
new CodeEntry(entry->tag(), GetFunctionName(shared_info->DebugName()),
241+
CodeEntry::kEmptyNamePrefix, resource_name,
242+
CpuProfileNode::kNoLineNumberInfo,
243+
CpuProfileNode::kNoColumnNumberInfo, nullptr,
244+
code->instruction_start());
238245
inline_entry->FillFunctionInfo(shared_info);
239246
inline_stack.push_back(inline_entry);
240247
}

deps/v8/test/cctest/test-cpu-profiler.cc

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

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

17421821
TEST(DontStopOnFinishedProfileDelete) {
17431822
v8::HandleScope scope(CcTest::isolate());

0 commit comments

Comments
 (0)