我正在对JS Interpreter进行大量修改的fork进行分析,并使用--prof在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可能在做什么并不很明显。


该名称表明它与检查器协议有关,但是我没有使用--inspect命令行标志,也没有尝试使用检查器将其附加到正在运行的进程中。
我似乎在node.js源代码中找不到包含字符串“ NodeRuntime”和“ DispatcherImpl”的任何文件。
它似乎是从几个不同的地方调用的,通常是从自身递归调用的(列表被修剪为主要显示顶级条目的列表),但是命名的JavaScript函数没有任何明显的共性:


 [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直接导致https://github.com/nodejs/node/blob/5aaa7fee2e4a075d9123b885f9e8cda3de2a780a/tools/inspector_protocol/templates/TypeBuilder_cpp.template#L218。但这可能并不是您真正想要的...

--prof系统中存在一段时间的错误,其中C ++滴答声将归因于错误的功能-看来您可能正在遇到该错误。它已经fixed in V8 recently,但是该修复尚未发布到Node版本中。

解决方法是,在Linux上,您可以使用perf来配置C ++代码[1],同时仍将--prof用于JavaScript; JavaScript刻度以及C ++ / JavaScript发行版在--prof的输出中应该可靠地正确。在其他平台上,应该有等效的通用配置技术。

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

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

07-27 22:44