有没有办法查看任何 JavaScript jit 生成的代码的汇编代码,尤其是 V8 的?

Are there ways to see the assembly code for the code generated by any of the JavaScript jits, especially V8's?

Web 浏览器和 nodeJS 的主要 JavaScript 引擎已经有 just-in-time 编译器多年了。

我刚刚在 Compiler Explorer 上观看了一个视频,其中显示了许多编译器为各种 CPU 输出的汇编代码。

这让我想起了我一直对 JS 引擎的 jits 生成的代码感到好奇。

这些引擎中的任何一个都能让我们看到生成的低级代码吗?

(如果这在 SO 上不合适,请随时将其迁移到正确的 SE 站点。)

对于 V8,有一个标志 --print-opt-code,它会为每个优化的函数打印生成的优化汇编代码。请注意,函数仅在 "hot" 时才得到优化,而不是立即优化,因此对于简短的 "hello, world" 样式程序,该标志不会打印任何内容。您可以通过多次调用来创建函数 "hot"。

在旧版本中,未优化代码有一个 --print-code 标记,但由于基线(非优化)编译器已被解释器取代,因此不再有未优化代码。您可以使用 --print-bytecode.

打印生成的字节码

如果您使用 Chrome,您可以通过将它们包装在 --js-flags 中来指定要传递给 V8 的标志,例如--js-flags="--print-opt-code".

你总能做的一件事是interrupt your program while it's running, using a debugger

如果它大部分时间都花在 JIT 编译的代码中,那么当前指令指针值 (RIP) 很可能会在一些 JIT 编译的机器代码中,您的调试器会为您反汇编这些代码。 (或者至少是当前 RIP 之后的部分:x86 机器代码使用可变长度指令,因此没有可靠的方法向后移动。您可能会单步执行直到到达向后分支以到达循环的顶部。)

但是没有任何方法可以确定您看到的 JIT asm 是哪个函数名称,除非您只有一个热循环(例如在人工测试/微基准测试中),否则这可能不是很有用。


让 JIT 引擎在生成 asm 时打印它(@jmrk 的回答)更有用;我只提到这项技术是因为它可以在没有任何 JIT 引擎支持的情况下工作,所以它可以在任何地方工作。