如何查看v8生成的机器代码?

时间:2022-01-31 07:11:03

Does anybody know how I can see the actual machine code that v8 generates from Javascript? I've gotten as far as Script::Compile() in src/api.cc but I can't figure out where to go from there.

有谁知道我怎么能看到v8从Javascript生成的实际机器代码?我已经在src / api.cc中得到了Script :: Compile(),但我无法弄清楚从哪里去。

5 个解决方案

#1


12  

I don't know how to invoke the disassembler from C++ code, but there is a quick-and-dirty way to get a disassembly from the shell.

我不知道如何从C ++代码中调用反汇编程序,但有一种快速而肮脏的方法从shell中获取反汇编。

First, compile v8 with disassembler support:

首先,使用反汇编程序支持编译v8:

scons [your v8 build options here] disassembler=on sample=shell

Now you can invoke the shell with the "--print_code" option:

现在,您可以使用“--print_code”选项调用shell:

./shell --print_code hello.js

Which should give you something like this:

哪个应该给你这样的东西:

--- Raw source ---
print("hello world");

--- Code ---
kind = FUNCTION
Instructions (size = 134)
0x2ad0a77ceea0     0  55             push rbp
0x2ad0a77ceea1     1  488bec         REX.W movq rbp,rsp
0x2ad0a77ceea4     4  56             push rsi
0x2ad0a77ceea5     5  57             push rdi
0x2ad0a77ceea6     6  49ba59c13da9d02a0000 REX.W movq r10,0x2ad0a93dc159    ;; object: 0xa93dc159 <undefined>
0x2ad0a77ceeb0    16  4952           REX.W push r10
0x2ad0a77ceeb2    18  49ba688b700000000000 REX.W movq r10,0x708b68
0x2ad0a77ceebc    28  493b22         REX.W cmpq rsp,[r10]
0x2ad0a77ceebf    31  0f824e000000   jc 115  (0x2ad0a77cef13)
0x2ad0a77ceec5    37  488b462f       REX.W movq rax,[rsi+0x2f]
0x2ad0a77ceec9    41  4883ec18       REX.W subq rsp,0xlx
0x2ad0a77ceecd    45  49ba094b3ea9d02a0000 REX.W movq r10,0x2ad0a93e4b09    ;; object: 0xa93e4b09 <String[5]: print>
0x2ad0a77ceed7    55  4c8955e0       REX.W movq [rbp-0x20],r10
0x2ad0a77ceedb    59  488945d8       REX.W movq [rbp-0x28],rax
0x2ad0a77ceedf    63  49ba014d3ea9d02a0000 REX.W movq r10,0x2ad0a93e4d01    ;; object: 0xa93e4d01 <String[11]: hello world>
0x2ad0a77ceee9    73  4c8955d0       REX.W movq [rbp-0x30],r10
0x2ad0a77ceeed    77  49baa06c7ba7d02a0000 REX.W movq r10,0x2ad0a77b6ca0    ;; debug: statement 0
                                 ;; code: contextual, CALL_IC, UNINITIALIZED, argc = 1
0x2ad0a77ceef7    87  49ffd2         REX.W call r10
0x2ad0a77ceefa    90  488b75f8       REX.W movq rsi,[rbp-0x8]
0x2ad0a77ceefe    94  4883c408       REX.W addq rsp,0xlx
0x2ad0a77cef02    98  488945e8       REX.W movq [rbp-0x18],rax
0x2ad0a77cef06   102  488be5         REX.W movq rsp,rbp      ;; js return
0x2ad0a77cef09   105  5d             pop rbp
0x2ad0a77cef0a   106  c20800         ret 0x8
0x2ad0a77cef0d   109  cc             int3
0x2ad0a77cef0e   110  cc             int3
0x2ad0a77cef0f   111  cc             int3
0x2ad0a77cef10   112  cc             int3
0x2ad0a77cef11   113  cc             int3
0x2ad0a77cef12   114  cc             int3
0x2ad0a77cef13   115  49ba60657ba7d02a0000 REX.W movq r10,0x2ad0a77b6560    ;; code: STUB, StackCheck, minor: 0
0x2ad0a77cef1d   125  49ffd2         REX.W call r10
0x2ad0a77cef20   128  488b7df0       REX.W movq rdi,[rbp-0x10]
0x2ad0a77cef24   132  eb9f           jmp 37  (0x2ad0a77ceec5)

RelocInfo (size = 10)
0x2ad0a77ceea8  embedded object  (0xa93dc159 <undefined>)
0x2ad0a77ceecf  embedded object  (0xa93e4b09 <String[5]: print>)
0x2ad0a77ceee1  embedded object  (0xa93e4d01 <String[11]: hello world>)
0x2ad0a77ceeed  statement position  (0)
0x2ad0a77ceeef  code target (context) (CALL_IC)  (0x2ad0a77b6ca0)
0x2ad0a77cef06  js return
0x2ad0a77cef15  code target (STUB)  (0x2ad0a77b6560)

hello world

Your output will vary, of course. The above is from the v8 trunk compiled for Linux x64.

当然,你的输出会有所不同。以上是为Linux x64编译的v8 trunk。

#2


6  

You need to build v8 with disassembler support.

您需要使用反汇编程序支持构建v8。

Download v8 source code.

下载v8源代码。

git clone https://chromium.googlesource.com/v8/v8.git

Build with disassembler support.

使用反汇编程序支持构建。

make dependencies
make ia32.release objectprint=on disassembler=on

Call d8 (v8 shell) using certain flags, depending on what you want.

根据您的需要,使用某些标志调用d8(v8 shell)。

out/ia32.release/d8 --code-comments --print-code <app.js>

For reference:

  • --code-comments: includes code comments.
  • --code-comments:包括代码注释。

  • --print-code: prints out code to stdout.
  • --print-code:将代码打印到stdout。

  • --print-code-stubs: prints code stubs.
  • --print-code-stubs:打印代码存根。

  • --print-opt-code: prints optimized code.
  • --print-opt-code:打印优化代码。

  • --trace-hydrogen: prints IR (intermediate representation) code to hydrogen.cfg. This file can be opened with Java's C1Visualizer.
  • --trace-hydrogen:将IR(中间表示)代码打印到hydrogen.cfg。可以使用Java的C1Visualizer打开此文件。

#3


2  

Try with NodeJS or Chrome:

尝试使用NodeJS或Chrome:

  1. -print-opt-code: Code generated by optimizing compiler.
  2. -print-opt-code:优化编译器生成的代码。

  3. -print-bytecode: Byte code generated by interpreter.
  4. -print-bytecode:解释器生成的字节码。

  5. -trace-opt and -trace-depot : which functions are (de)optimized.
  6. -trace-opt和-trace-depot:哪些功能被(de)优化。

Check this article by @Franziska Hinkelmann :

查看@Franziska Hinkelmann撰写的这篇文章:

https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775

Additionally you can also try

另外你也可以试试

D8: It will help you compile V8 and view the assembly code generated from JavaScript.

D8:它将帮助您编译V8并查看从JavaScript生成的汇编代码。

For usage and details:

用法和细节:

http://www.mattzeunert.com/2015/08/19/viewing-assembly-code-generated-by-v8.html

#4


1  

You're on the right track, I think.

我想你是在正确的轨道上。

It looks like you need to get from Script::Compile to Compiler::Compile, which will lead you to the code generators (codegen*.cc and .h).

看起来你需要从Script :: Compile到Compiler :: Compile,它将引导你进入代码生成器(codegen * .cc和.h)。

All of this to say that, looking at codegen-ia32.cc, if you define ENABLE_DISASSEMBLER when you build, your disassembly should get printed, I think.

所有这些都说,看看codegen-ia32.cc,如果你在构建时定义ENABLE_DISASSEMBLER,我认为你的反汇编应该打印出来。

Of course, all of this is just from a quick browse of an old copy of the source I have here, so YMMV, but I think this should work.

当然,所有这些只是通过快速浏览我在这里的源代码的旧副本,所以YMMV,但我认为这应该工作。

(Looking at your post again, I see you're looking for the machine language, not the assembler -- I'm not sure, but you might have to modify the logic if you want the assembled code output rather than its disassembly)

(再次查看你的帖子,我看到你正在寻找机器语言,而不是汇编程序 - 我不确定,但如果你想要汇编的代码输出而不是它的反汇编你可能需要修改逻辑)

#5


0  

Take a look at v8_root/build/features.gypi, and you will find disassembler related and many other compile time feature switches for V8.

看看v8_root / build / features.gypi,您会发现V8的反汇编程序和许多其他编译时功能开关。

#1


12  

I don't know how to invoke the disassembler from C++ code, but there is a quick-and-dirty way to get a disassembly from the shell.

我不知道如何从C ++代码中调用反汇编程序,但有一种快速而肮脏的方法从shell中获取反汇编。

First, compile v8 with disassembler support:

首先,使用反汇编程序支持编译v8:

scons [your v8 build options here] disassembler=on sample=shell

Now you can invoke the shell with the "--print_code" option:

现在,您可以使用“--print_code”选项调用shell:

./shell --print_code hello.js

Which should give you something like this:

哪个应该给你这样的东西:

--- Raw source ---
print("hello world");

--- Code ---
kind = FUNCTION
Instructions (size = 134)
0x2ad0a77ceea0     0  55             push rbp
0x2ad0a77ceea1     1  488bec         REX.W movq rbp,rsp
0x2ad0a77ceea4     4  56             push rsi
0x2ad0a77ceea5     5  57             push rdi
0x2ad0a77ceea6     6  49ba59c13da9d02a0000 REX.W movq r10,0x2ad0a93dc159    ;; object: 0xa93dc159 <undefined>
0x2ad0a77ceeb0    16  4952           REX.W push r10
0x2ad0a77ceeb2    18  49ba688b700000000000 REX.W movq r10,0x708b68
0x2ad0a77ceebc    28  493b22         REX.W cmpq rsp,[r10]
0x2ad0a77ceebf    31  0f824e000000   jc 115  (0x2ad0a77cef13)
0x2ad0a77ceec5    37  488b462f       REX.W movq rax,[rsi+0x2f]
0x2ad0a77ceec9    41  4883ec18       REX.W subq rsp,0xlx
0x2ad0a77ceecd    45  49ba094b3ea9d02a0000 REX.W movq r10,0x2ad0a93e4b09    ;; object: 0xa93e4b09 <String[5]: print>
0x2ad0a77ceed7    55  4c8955e0       REX.W movq [rbp-0x20],r10
0x2ad0a77ceedb    59  488945d8       REX.W movq [rbp-0x28],rax
0x2ad0a77ceedf    63  49ba014d3ea9d02a0000 REX.W movq r10,0x2ad0a93e4d01    ;; object: 0xa93e4d01 <String[11]: hello world>
0x2ad0a77ceee9    73  4c8955d0       REX.W movq [rbp-0x30],r10
0x2ad0a77ceeed    77  49baa06c7ba7d02a0000 REX.W movq r10,0x2ad0a77b6ca0    ;; debug: statement 0
                                 ;; code: contextual, CALL_IC, UNINITIALIZED, argc = 1
0x2ad0a77ceef7    87  49ffd2         REX.W call r10
0x2ad0a77ceefa    90  488b75f8       REX.W movq rsi,[rbp-0x8]
0x2ad0a77ceefe    94  4883c408       REX.W addq rsp,0xlx
0x2ad0a77cef02    98  488945e8       REX.W movq [rbp-0x18],rax
0x2ad0a77cef06   102  488be5         REX.W movq rsp,rbp      ;; js return
0x2ad0a77cef09   105  5d             pop rbp
0x2ad0a77cef0a   106  c20800         ret 0x8
0x2ad0a77cef0d   109  cc             int3
0x2ad0a77cef0e   110  cc             int3
0x2ad0a77cef0f   111  cc             int3
0x2ad0a77cef10   112  cc             int3
0x2ad0a77cef11   113  cc             int3
0x2ad0a77cef12   114  cc             int3
0x2ad0a77cef13   115  49ba60657ba7d02a0000 REX.W movq r10,0x2ad0a77b6560    ;; code: STUB, StackCheck, minor: 0
0x2ad0a77cef1d   125  49ffd2         REX.W call r10
0x2ad0a77cef20   128  488b7df0       REX.W movq rdi,[rbp-0x10]
0x2ad0a77cef24   132  eb9f           jmp 37  (0x2ad0a77ceec5)

RelocInfo (size = 10)
0x2ad0a77ceea8  embedded object  (0xa93dc159 <undefined>)
0x2ad0a77ceecf  embedded object  (0xa93e4b09 <String[5]: print>)
0x2ad0a77ceee1  embedded object  (0xa93e4d01 <String[11]: hello world>)
0x2ad0a77ceeed  statement position  (0)
0x2ad0a77ceeef  code target (context) (CALL_IC)  (0x2ad0a77b6ca0)
0x2ad0a77cef06  js return
0x2ad0a77cef15  code target (STUB)  (0x2ad0a77b6560)

hello world

Your output will vary, of course. The above is from the v8 trunk compiled for Linux x64.

当然,你的输出会有所不同。以上是为Linux x64编译的v8 trunk。

#2


6  

You need to build v8 with disassembler support.

您需要使用反汇编程序支持构建v8。

Download v8 source code.

下载v8源代码。

git clone https://chromium.googlesource.com/v8/v8.git

Build with disassembler support.

使用反汇编程序支持构建。

make dependencies
make ia32.release objectprint=on disassembler=on

Call d8 (v8 shell) using certain flags, depending on what you want.

根据您的需要,使用某些标志调用d8(v8 shell)。

out/ia32.release/d8 --code-comments --print-code <app.js>

For reference:

  • --code-comments: includes code comments.
  • --code-comments:包括代码注释。

  • --print-code: prints out code to stdout.
  • --print-code:将代码打印到stdout。

  • --print-code-stubs: prints code stubs.
  • --print-code-stubs:打印代码存根。

  • --print-opt-code: prints optimized code.
  • --print-opt-code:打印优化代码。

  • --trace-hydrogen: prints IR (intermediate representation) code to hydrogen.cfg. This file can be opened with Java's C1Visualizer.
  • --trace-hydrogen:将IR(中间表示)代码打印到hydrogen.cfg。可以使用Java的C1Visualizer打开此文件。

#3


2  

Try with NodeJS or Chrome:

尝试使用NodeJS或Chrome:

  1. -print-opt-code: Code generated by optimizing compiler.
  2. -print-opt-code:优化编译器生成的代码。

  3. -print-bytecode: Byte code generated by interpreter.
  4. -print-bytecode:解释器生成的字节码。

  5. -trace-opt and -trace-depot : which functions are (de)optimized.
  6. -trace-opt和-trace-depot:哪些功能被(de)优化。

Check this article by @Franziska Hinkelmann :

查看@Franziska Hinkelmann撰写的这篇文章:

https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775

Additionally you can also try

另外你也可以试试

D8: It will help you compile V8 and view the assembly code generated from JavaScript.

D8:它将帮助您编译V8并查看从JavaScript生成的汇编代码。

For usage and details:

用法和细节:

http://www.mattzeunert.com/2015/08/19/viewing-assembly-code-generated-by-v8.html

#4


1  

You're on the right track, I think.

我想你是在正确的轨道上。

It looks like you need to get from Script::Compile to Compiler::Compile, which will lead you to the code generators (codegen*.cc and .h).

看起来你需要从Script :: Compile到Compiler :: Compile,它将引导你进入代码生成器(codegen * .cc和.h)。

All of this to say that, looking at codegen-ia32.cc, if you define ENABLE_DISASSEMBLER when you build, your disassembly should get printed, I think.

所有这些都说,看看codegen-ia32.cc,如果你在构建时定义ENABLE_DISASSEMBLER,我认为你的反汇编应该打印出来。

Of course, all of this is just from a quick browse of an old copy of the source I have here, so YMMV, but I think this should work.

当然,所有这些只是通过快速浏览我在这里的源代码的旧副本,所以YMMV,但我认为这应该工作。

(Looking at your post again, I see you're looking for the machine language, not the assembler -- I'm not sure, but you might have to modify the logic if you want the assembled code output rather than its disassembly)

(再次查看你的帖子,我看到你正在寻找机器语言,而不是汇编程序 - 我不确定,但如果你想要汇编的代码输出而不是它的反汇编你可能需要修改逻辑)

#5


0  

Take a look at v8_root/build/features.gypi, and you will find disassembler related and many other compile time feature switches for V8.

看看v8_root / build / features.gypi,您会发现V8的反汇编程序和许多其他编译时功能开关。