How can I see the machine code generated by v8?
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.
First, compile v8 with disassembler support:
scons [your v8 build options here] disassembler=on sample=shell
Now you can invoke the shell with the "--print_code" option:
./shell --print_code hello.js
Which should give you something like this:
--- Raw source ---print("hello world");--- Code ---kind = FUNCTIONInstructions (size = 134)0x2ad0a77ceea0 0 55 push rbp0x2ad0a77ceea1 1 488bec REX.W movq rbp,rsp0x2ad0a77ceea4 4 56 push rsi0x2ad0a77ceea5 5 57 push rdi0x2ad0a77ceea6 6 49ba59c13da9d02a0000 REX.W movq r10,0x2ad0a93dc159 ;; object: 0xa93dc159 <undefined>0x2ad0a77ceeb0 16 4952 REX.W push r100x2ad0a77ceeb2 18 49ba688b700000000000 REX.W movq r10,0x708b680x2ad0a77ceebc 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,0xlx0x2ad0a77ceecd 45 49ba094b3ea9d02a0000 REX.W movq r10,0x2ad0a93e4b09 ;; object: 0xa93e4b09 <String[5]: print>0x2ad0a77ceed7 55 4c8955e0 REX.W movq [rbp-0x20],r100x2ad0a77ceedb 59 488945d8 REX.W movq [rbp-0x28],rax0x2ad0a77ceedf 63 49ba014d3ea9d02a0000 REX.W movq r10,0x2ad0a93e4d01 ;; object: 0xa93e4d01 <String[11]: hello world>0x2ad0a77ceee9 73 4c8955d0 REX.W movq [rbp-0x30],r100x2ad0a77ceeed 77 49baa06c7ba7d02a0000 REX.W movq r10,0x2ad0a77b6ca0 ;; debug: statement 0 ;; code: contextual, CALL_IC, UNINITIALIZED, argc = 10x2ad0a77ceef7 87 49ffd2 REX.W call r100x2ad0a77ceefa 90 488b75f8 REX.W movq rsi,[rbp-0x8]0x2ad0a77ceefe 94 4883c408 REX.W addq rsp,0xlx0x2ad0a77cef02 98 488945e8 REX.W movq [rbp-0x18],rax0x2ad0a77cef06 102 488be5 REX.W movq rsp,rbp ;; js return0x2ad0a77cef09 105 5d pop rbp0x2ad0a77cef0a 106 c20800 ret 0x80x2ad0a77cef0d 109 cc int30x2ad0a77cef0e 110 cc int30x2ad0a77cef0f 111 cc int30x2ad0a77cef10 112 cc int30x2ad0a77cef11 113 cc int30x2ad0a77cef12 114 cc int30x2ad0a77cef13 115 49ba60657ba7d02a0000 REX.W movq r10,0x2ad0a77b6560 ;; code: STUB, StackCheck, minor: 00x2ad0a77cef1d 125 49ffd2 REX.W call r100x2ad0a77cef20 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 return0x2ad0a77cef15 code target (STUB) (0x2ad0a77b6560)hello world
Your output will vary, of course. The above is from the v8 trunk compiled for Linux x64.
You need to build v8 with disassembler support.
Download v8 source code.
git clone https://chromium.googlesource.com/v8/v8.git
Build with disassembler support.
make dependenciesmake ia32.release objectprint=on disassembler=on
Call d8 (v8 shell) using certain flags, depending on what you want.
out/ia32.release/d8 --code-comments --print-code <app.js>
For reference:
- --code-comments: includes code comments.
- --print-code: prints out code to stdout.
- --print-code-stubs: prints code stubs.
- --print-opt-code: prints optimized code.
- --trace-hydrogen: prints IR (intermediate representation) code to hydrogen.cfg. This file can be opened with Java's C1Visualizer.
Try with NodeJS or Chrome:
-print-opt-code
: Code generated by optimizing compiler.-print-bytecode
: Byte code generated by interpreter.-trace-opt
and-trace-depot
: which functions are (de)optimized.
Check this article by @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.
For usage and details:
http://www.mattzeunert.com/2015/08/19/viewing-assembly-code-generated-by-v8.html