反汇编 javascript 调用未知函数的 jit 代码
disassembled javascript jit code calling unknown function
我在 V8 中反汇编了一个这样的 javascript 函数。
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
"function A" 中没有明确的函数调用。但是反汇编的汇编代码中有两个函数(MakeQuadragenarianCodeYoungAgainOddMarking,StackCheck)和未知的"call"指令("call 0x35ca734366c0")。这些是什么?为什么需要它们?它们在哪里定义?
生成的 JIT 代码不是完全独立的。它在 VM(v8 运行时)的上下文中运行。
堆栈检查:
Loops need to be interruptable, and V8 does so by placing a stack
check at the beginning of each loop iteration. If the runtime wants to
interrupt a loop, it resets the stack limit of the process, and waits
for the process's next stack check.
堆栈检查也在函数开头插入。你明白了。
MakeQuadragenarianCodeYoungAgainOddMarking 可能与垃圾收集有关。 V8 有分代 GC,有年轻代和老年代的对象。而JIT代码是堆对象
Why are they needed? and where are they defined?
它们在 V8 源代码中定义。如果您想了解更多,我鼓励您为 v8 内部结构服务网络。有quite a few articles。
我在 V8 中反汇编了一个这样的 javascript 函数。
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
"function A" 中没有明确的函数调用。但是反汇编的汇编代码中有两个函数(MakeQuadragenarianCodeYoungAgainOddMarking,StackCheck)和未知的"call"指令("call 0x35ca734366c0")。这些是什么?为什么需要它们?它们在哪里定义?
生成的 JIT 代码不是完全独立的。它在 VM(v8 运行时)的上下文中运行。
堆栈检查:
Loops need to be interruptable, and V8 does so by placing a stack check at the beginning of each loop iteration. If the runtime wants to interrupt a loop, it resets the stack limit of the process, and waits for the process's next stack check.
堆栈检查也在函数开头插入。你明白了。
MakeQuadragenarianCodeYoungAgainOddMarking 可能与垃圾收集有关。 V8 有分代 GC,有年轻代和老年代的对象。而JIT代码是堆对象
Why are they needed? and where are they defined?
它们在 V8 源代码中定义。如果您想了解更多,我鼓励您为 v8 内部结构服务网络。有quite a few articles。