反汇编 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.

(Andy Wingo's blog)

堆栈检查也在函数开头插入。你明白了。

MakeQuadragenarianCodeYoungAgainOddMarking 可能与垃圾收集有关。 V8 有分代 GC,有年轻代和老年代的对象。而JIT代码是堆对象

Why are they needed? and where are they defined?

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