Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I see the machine code generated by v8?

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.

like image 790
user36128 Avatar asked Nov 10 '08 09:11

user36128


People also ask

What is V8 code?

V8 JavaScript engine is an open source JavaScript and WebAssembly engine that compiles JavaScript to optimized machine code before execution.

What is byte code in JS?

The bytecode is a format that simplifies the execution of the JavaScript code by an interpreter, and then by the Just-In-Time compilers (JITs). The bytecode is much larger than the source code, so Firefox only generates the bytecode of executed functions.

Is JavaScript compiled to bytecode?

A program such as C++ or Java needs to be compiled before it is run. The source code is passed through a program called a compiler, which translates it into bytecode that the machine understands and can execute. In contrast, JavaScript has no compilation step.


2 Answers

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 = 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.

like image 150
sstock Avatar answered Oct 02 '22 12:10

sstock


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 dependencies make 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.
like image 42
Diego Pino Avatar answered Oct 02 '22 14:10

Diego Pino