【问题标题】:Are there ways to see the assembly code for the code generated by any of the JavaScript jits, especially V8's?有没有办法查看由任何 JavaScript jit(尤其是 V8)生成的代码的汇编代码?
【发布时间】:2018-06-08 23:27:55
【问题描述】:
Web 浏览器的主要JavaScript 引擎和nodeJS 多年来一直拥有just-in-time 编译器。
我刚刚在Compiler Explorer 上观看了一段视频,展示了许多编译器为各种 CPU 输出的汇编代码。
这让我想起了我一直对 JS 引擎的 jit 生成的代码感到好奇。
这些引擎是否有办法让我们查看生成的低级代码?
(如果这在 SO 上不合适,请随时将其迁移到正确的 SE 站点。)
【问题讨论】:
标签:
javascript
assembly
v8
jit
javascript-engine
【解决方案1】:
对于 V8,有一个标志 --print-opt-code,它会为每个经过优化的函数打印生成的优化汇编代码。请注意,函数只有在“热”时才会得到优化,而不是立即得到优化,因此对于简短的“hello, world”风格的程序,标志不会打印任何内容。您可以通过多次调用函数来使函数“热”。
在旧版本中,未优化代码有一个 --print-code 标志,但由于基线(非优化)编译器已被解释器替换,因此不再有未优化代码。您可以使用--print-bytecode 打印生成的字节码。
如果您使用的是 Chrome,您可以通过将它们包装在 --js-flags 中来指定要传递给 V8 的标志,例如--js-flags="--print-opt-code".
【解决方案2】:
你总是可以做的一件事是interrupt your program while it's running, using a debugger。
如果它大部分时间都花在 JIT 编译的代码上,那么当前指令指针值 (RIP) 可能会在一些 JIT 编译的机器代码中,您的调试器会为您反汇编。 (或者至少在当前 RIP: x86 机器代码之后的部分使用可变长度指令,因此没有可靠的方法可以向后退。您可以单步执行,直到到达一个向后分支以到达循环的顶部。)
但是没有任何方法可以确定您看到 JITed asm 的函数名称,除非您只有一个热循环(例如在人工测试/微基准测试中),否则这可能不是很有用。
让 JIT 引擎在生成 asm 时打印它(@jmrk 的回答)更多更有用;我只提到这种技术是因为它无需 JIT 引擎的任何支持即可工作,因此它可以在任何情况下工作。