用v8查看javascript生成的字节码
通过 V8 引擎的 --print-bytecode 标志输出 JavaScript 字节码,详解 LdaGlobal、StaGlobal、CallRuntime 等字节码指令的含义与执行流程。
用v8查看javascript生成的字节码
- 示意代码
var hello = "hello"
function display(hello) {
console.log(hello)
return 1
}
display(hello)
- 输出生成的字节码(--print-bytecode)
[generated bytecode for function: (0x01b008292bf1 <SharedFunctionInfo>)]
Bytecode length: 30
Parameter count 1
Register count 3
Frame size 24
OSR nesting level: 0
Bytecode Age: 0
000001B008292CBA @ 0 : 13 00 LdaConstant [0]
000001B008292CBC @ 2 : c2 Star1
000001B008292CBD @ 3 : 19 fe f8 Mov <closure>, r2
000001B008292CC0 @ 6 : 64 4f 01 f9 02 CallRuntime [DeclareGlobals], r1-r2
000001B008292CC5 @ 11 : 13 01 LdaConstant [1]
000001B008292CC7 @ 13 : 23 01 00 StaGlobal [1], [0]
000001B008292CCA @ 16 : 21 02 02 LdaGlobal [2], [2]
000001B008292CCD @ 19 : c2 Star1
000001B008292CCE @ 20 : 21 01 04 LdaGlobal [1], [4]
000001B008292CD1 @ 23 : c1 Star2
000001B008292CD2 @ 24 : 61 f9 f8 06 CallUndefinedReceiver1 r1, r2, [6]
000001B008292CD6 @ 28 : c3 Star0
000001B008292CD7 @ 29 : a8 Return
Constant pool (size = 3)
000001B008292C85: [FixedArray] in OldSpace
- map: 0x01b008002205 <Map>
- length: 3
0: 0x01b008292c39 <FixedArray[3]>
1: 0x01b008292bb9 <String[5]: #hello>
2: 0x01b008292bcd <String[7]: #display>
Handler Table (size = 0)
Source Position Table (size = 0)
[generated bytecode for function: display (0x01b008292c4d <SharedFunctionInfo display>)]
Bytecode length: 17
Parameter count 2
Register count 2
Frame size 16
OSR nesting level: 0
Bytecode Age: 0
000001B008292E06 @ 0 : 21 00 00 LdaGlobal [0], [0]
000001B008292E09 @ 3 : c2 Star1
000001B008292E0A @ 4 : 2d f9 01 02 LdaNamedProperty r1, [1], [2]
000001B008292E0E @ 8 : c3 Star0
000001B008292E0F @ 9 : 5d fa f9 03 04 CallProperty1 r0, r1, a0, [4]
000001B008292E14 @ 14 : 0d 01 LdaSmi [1]
000001B008292E16 @ 16 : a8 Return
Constant pool (size = 2)
000001B008292DD5: [FixedArray] in OldSpace
- map: 0x01b008002205 <Map>
- length: 2
0: 0x01b00820a401 <String[7]: #console>
1: 0x01b00820a475 <String[3]: #log>
Handler Table (size = 0)
Source Position Table (size = 0)
hello
Constant pool 表示常量池
LdaGlobal <name_index>
- 变量声明
000001B008292CBA @ 0 : 13 00 LdaConstant [0]
000001B008292CBC @ 2 : c2 Star1
000001B008292CBD @ 3 : 19 fe f8 Mov <closure>, r2
000001B008292CC0 @ 6 : 64 4f 01 f9 02 CallRuntime [DeclareGlobals], r1-r2
这一部分表示全局变量声明
调用函数DeclareGlobals,将寄存器r1,r2作为参数传入
- 函数调用准备
000001B008292CC7 @ 13 : 23 01 00 StaGlobal [1], [0] // 累加器中的值写入hello变量
000001B008292CCA @ 16 : 21 02 02 LdaGlobal [2], [2] // 函数display写入累加器
000001B008292CCD @ 19 : c2 Star1 // display写入到寄存器r1
000001B008292CCE @ 20 : 21 01 04 LdaGlobal [1], [4] // 变量hello 写入寄存器
000001B008292CD1 @ 23 : c1 Star2 //变量hello写入寄存器r2
- 函数查找
000001B008292CD2 @ 24 : 61 f9 f8 06 CallUndefinedReceiver1 r1, r2, [6] //调用函数display
- 属性查找
000001B008292E06 @ 0 : 21 00 00 LdaGlobal [0], [0] // 加载console到累机器中
000001B008292E09 @ 3 : c2 Star1 // console写入到r1寄存器
000001B008292E0A @ 4 : 2d f9 01 02 LdaNamedProperty r1, [1], [2] // console对象下面log属性查找
- 函数调用
000001B008292E0E @ 8 : c3 Star0 //查找对的对象值加载到寄存器r0
000001B008292E0F @ 9 : 5d fa f9 03 04 CallProperty1 r0, r1, a0, [4] // 调用函数其中a0为掺入的参数
000001B008292E14 @ 14 : 0d 01 LdaSmi [1] // 小整数1加载到累加器
- 函数信息
Parameter count 2 //参数个数(实际上只有一个入参)
Register count 2 // 寄存器个数