在 node.js --prof 输出中,这个名字奇怪的 C++ 函数在做什么?

In node.js --prof output, what is this strangely-named C++ function doing?

我正在使用 --profJS Interpreter、运行 的 node.js v12.12.0 进行大量修改的分支进行概要分析,同时它运行一个简短的综合基准测试。在 `node --prof-process 的输出中,我看到程序运行时间的 63% 花在了 C++ 中:

 [Summary]:
   ticks  total  nonlib   name
   1503   35.6%   35.9%  JavaScript
   2658   63.0%   63.4%  C++
    119    2.8%    2.8%  GC
     30    0.7%          Shared libraries
     29    0.7%          Unaccounted

特别是有一个C++函数占整个运行时间的59%:

 [C++]:
   ticks  total  nonlib   name
   2504   59.3%   59.8%  t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
     27    0.6%    0.6%  T node::native_module::NativeModuleEnv::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
     23    0.5%    0.5%  T _proc_set_dirty
     16    0.4%    0.4%  T __kernelrpc_vm_remap
      9    0.2%    0.2%  t __malloc_initialize
      9    0.2%    0.2%  T _thread_get_state
      8    0.2%    0.2%  T node::contextify::ContextifyContext::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
  ...

不幸的是,我不太清楚 __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev 可能在做什么。

 [Bottom up (heavy) profile]:
  Note: percentage shows a share of a particular caller in the total
  amount of its parent calls.
  Callers occupying less than 1.0% are not shown.

   ticks parent  name
   2504   59.3%  t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
   1287   51.4%    t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
    785   61.0%      LazyCompile: *intrp.Object.defineProperty /Users/cpcallen/src/CodeCity/server/interpreter.js:4477:51
    226   17.6%      LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
     67    5.2%      LazyCompile: *intrp.Object.getOwnPropertyDescriptor /Users/cpcallen/src/CodeCity/server/interpreter.js:4455:61
     34    2.6%      t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
     22    1.7%      LazyCompile: *stepFuncs_.MemberExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6582:42
    278   11.1%    LazyCompile: *Interpreter.run /Users/cpcallen/src/CodeCity/server/interpreter.js:290:37
    140    5.6%    LazyCompile: *stepFuncs_.Identifier /Users/cpcallen/src/CodeCity/server/interpreter.js:6494:36
    121    4.8%    LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
     91    3.6%    LazyCompile: ~runBench /Users/cpcallen/src/CodeCity/server/tests/interpreter_bench.js:37:18
     79    3.2%    LazyCompile: *intrp.UserFunction.call /Users/cpcallen/src/CodeCity/server/interpreter.js:4782:47
     65    2.6%    LazyCompile: *Interpreter.getBoundNames_ /Users/cpcallen/src/CodeCity/server/interpreter.js:2907:48
     62    2.5%    LazyCompile: *stepFuncs_.CallExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6039:40

我想知道它是否真的是垃圾收集器,但使用 --trace-gc 表明 GC 占用的总运行时间不到 10%。

我如何弄清楚这个 C++ 函数在做什么?

找到 DispatcherImpl 并不难:https://github.com/nodejs/node/search?q=dispatcherimpl&unscoped_q=dispatcherimpl leads straight to https://github.com/nodejs/node/blob/5aaa7fee2e4a075d9123b885f9e8cda3de2a780a/tools/inspector_protocol/templates/TypeBuilder_cpp.template#L218。但这可能不是您真正想要的...

一段时间以来,--prof 系统中存在一个错误,其中 C++ ticks 会被归因于错误的函数——看起来您可能 运行 喜欢它。已 fixed in V8 recently,但修复尚未进入 Node 版本。

作为解决方法,在 Linux 上,您可以使用 perf 分析 C++ 代码 [1],同时仍然使用 --prof 分析 JavaScript; JavaScript ticks 以及 C++/JavaScript 分布在 --prof 的输出中应该可靠地正确。在其他平台上应该有等效的通用分析技术。

[1] 有关详细信息,请阅读手册页。我通常使用类似的东西:

perf record -e cycles -F 10000 <executable and arguments>
perf report -M intel