2015-04-01 28 views
0

我在V8中反汇编了一个JavaScript函数。反汇编JavaScript jit代码调用未知函数

function A() { 
    a = 1; 
    b = 2; 
    c = a + b; 
} 

而且我得到了反汇编代码。在x86机器上(64位)

Instructions (size = 228) 
0x35ca73465740  0 488b4c2408  REX.W movq rcx,[rsp+0x8] 
0x35ca73465745  5 493b4da8  REX.W cmpq rcx,[r13-0x58] 
0x35ca73465749  9 750d   jnz 24 (0x35ca73465758) 
0x35ca7346574b 11 488b4e27  REX.W movq rcx,[rsi+0x27] 
0x35ca7346574f 15 488b492f  REX.W movq rcx,[rcx+0x2f] 
0x35ca73465753 19 48894c2408  REX.W movq [rsp+0x8],rcx 
0x35ca73465758 24 e88358fdff  call MakeQuadragenarianCodeYoungAgainOddMarking (0x35ca7343afe0) 
0x35ca7346575d 29 90    nop 
0x35ca7346575e 30 493ba5b0070000 REX.W cmpq rsp,[r13+0x7b0] 
0x35ca73465765 37 7305   jnc 44 (0x35ca7346576c) 
0x35ca73465767 39 e83456fdff  call StackCheck (0x35ca7343ada0) ;; debug: statement 19 
                 ;; code: BUILTIN 
0x35ca7346576c 44 4c89e0   REX.W movq rax,r12 
0x35ca7346576f 47 48b9111d111f770a0000 REX.W movq rcx,0xa771f111d11 ;; object: 0xa771f111d11 <String[1]: a> 
0x35ca73465779 57 488b5627  REX.W movq rdx,[rsi+0x27] 
0x35ca7346577d 61 e83e0ffdff  call 0x35ca734366c0  ;; debug: statement 26 
                 ;; debug: position 27 
                 ;; code: STORE_IC, PREMONOMORPHIC 
0x35ca73465782 66 4b8d0424  REX.W leaq rax,[r12+r12*1] 
0x35ca73465786 70 48b9311d111f770a0000 REX.W movq rcx,0xa771f111d31 ;; object: 0xa771f111d31 <String[1]: b> 
0x35ca73465790 80 488b5627  REX.W movq rdx,[rsi+0x27] 
0x35ca73465794 84 e8270ffdff  call 0x35ca734366c0  ;; debug: statement 33 
                 ;; debug: position 34 
                 ;; code: STORE_IC, PREMONOMORPHIC 
0x35ca73465799 89 48b9111d111f770a0000 REX.W movq rcx,0xa771f111d11 ;; object: 0xa771f111d11 <String[1]: a> 
0x35ca734657a3 99 488b5627  REX.W movq rdx,[rsi+0x27] 
0x35ca734657a7 103 e8940ffdff  call 0x35ca73436740  ;; debug: statement 40 
                 ;; debug: position 42 
                 ;; code: contextual, LOAD_IC, PREMONOMORPHIC 
0x35ca734657ac 108 50    push rax 
0x35ca734657ad 109 48b9311d111f770a0000 REX.W movq rcx,0xa771f111d31 ;; object: 0xa771f111d31 <String[1]: b> 
0x35ca734657b7 119 488b5627  REX.W movq rdx,[rsi+0x27] 
0x35ca734657bb 123 e8800ffdff  call 0x35ca73436740  ;; debug: position 44 
                 ;; code: contextual, LOAD_IC, PREMONOMORPHIC 
0x35ca734657c0 128 5a    pop rdx 
0x35ca734657c1 129 e89aeefaff  call 0x35ca73414660  ;; debug: position 43 
                 ;; code: BINARY_OP_IC, MONOMORPHIC, NORMAL (id = 31) 
0x35ca734657c6 134 90    nop 
0x35ca734657c7 135 48b9511d111f770a0000 REX.W movq rcx,0xa771f111d51 ;; object: 0xa771f111d51 <String[1]: c> 
0x35ca734657d1 145 488b5627  REX.W movq rdx,[rsi+0x27] 
0x35ca734657d5 149 e8e60efdff  call 0x35ca734366c0  ;; debug: position 41 
                 ;; code: STORE_IC, PREMONOMORPHIC 
0x35ca734657da 154 498b45a8  REX.W movq rax,[r13-0x58] 
0x35ca734657de 158 48bb214b4060ff110000 REX.W movq rbx,0x11ff60404b21 ;; object: 0x11ff60404b21 Cell for 6097 
0x35ca734657e8 168 83430bd1  addl [rbx+0xb],0xd1 
0x35ca734657ec 172 791f   jns 205 (0x35ca7346580d) 
0x35ca734657ee 174 50    push rax 
0x35ca734657ef 175 e86c54fdff  call InterruptCheck (0x35ca7343ac60) ;; code: BUILTIN 
0x35ca734657f4 180 58    pop rax 
0x35ca734657f5 181 48bb214b4060ff110000 REX.W movq rbx,0x11ff60404b21 ;; object: 0x11ff60404b21 Cell for 6097 
0x35ca734657ff 191 49ba0000000000180000 REX.W movq r10,0x180000000000 
0x35ca73465809 201 4c895307  REX.W movq [rbx+0x7],r10 
0x35ca7346580d 205 488be5   REX.W movq rsp,rbp  ;; debug: statement 47 
                 ;; js return 
                 ;; code_age_sequence 

“函数A”中没有明确的函数调用。但是在反汇编汇编代码中有两个函数(MakeQuadragenarianCodeYoungAgainOddMarking,StackCheck)和未知的“调用”指令(“调用0x35ca734366c0”)。他们是什么?他们为什么需要?他们在哪里定义?

+0

这是一个奇怪的问题,“函数A”中没有* JavaScript *函数调用,但x86-64汇编语言的语义与JavaScript语言的语义有很大不同 – Esailija 2015-04-01 06:51:28

+0

是的,您是对的!这就是我问这个问题的原因。 – Joffrey 2015-04-01 14:00:02

回答

1

生成的JIT代码不是完全独立的。它运行在VM(v8运行时)的上下文中。

StackCheck:

循环必须中断的,和V8通过在每个循环迭代的开始将堆栈 检查这样做。如果运行时想要 中断一个循环,它将重置进程的堆栈限制,并等待进程的下一个堆栈检查 。

(Andy Wingo's blog)

堆栈检查也插入功能开始。你明白了。

MakeQuadragenarianCodeYoungAgainOddMarking可能与垃圾收集有关。 V8具有世代GC,具有年轻和老一代的物体。 JIT代码是一个堆对象。

他们为什么需要?他们在哪里定义?

它们在V8源代码中定义。如果你想了解更多,我鼓励你为v8内部使用网络。有quite a few articles