V8引擎执行JS(函数)过程
- JS代码执行阶段
- 代码执行过程
JS代码执行阶段
-
Parse阶段:Parse模块会将JavaScript代码转换成AST(抽象语法树),这是因为解释器并不直接认识JavaScript代码
-
Lgnition阶段:Lgnition是一个解释器,会将AST转换成ByteCode(字节码)
2.1、同时会手机TurboFan优化所需要的信息(比如函数参数的类型信息,有了类型才能进行真实的运算)
2.2、如果函数只调用一次,Ignition会执行解释执行ByteCode -
TurboFan阶段:TurboFan是一个编译器,可以将字节码编译为CPU可以直接执行的机器码
3.1、如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能
3.2、但是,机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码 -
执行阶段: 字节码转变为计算机能看懂的二进制文件进行执行。(转变字节码有跨平台的作用)
代码执行过程
-
在Parse阶段会生成一个全局对象GO(Global Object),这个对象中放着公共类,变量,函数等等
—GO对象包含着window对象,GO对象又指向window对象 -
JS引擎内部有个执行上下文栈(Execution Context Stack,简称ECS),用于执行代码的调用栈
-
全局的代码块为了执行会构建一个全局执行上下文(Global Execution Context(GEC))
首先全局执行上下文会被放入到ECS调用栈中,在执行前全局上下文中的VO(变量对象)就指向GO(全局对象),然后开始执行代码。
当执行到函数时,会创建一个函数执行上下文(Function Execution Context(FEC)),函数执行上下文会入ECS调用栈,这个函数执行上下文跟全局执行上下文相似,也有VO,不同的是这里的VO指向着AO(Activation Object)对象。
AO中也放着函数的参数、变量等等,当函数执行完毕时,函数执行上下文会出栈、销毁,此时AO对象也会被回收。
当函数再次执行时,会重复上面的步骤
创建函数执行上下文—>入栈—>执行—>出栈—>销毁