【发布时间】:2022-01-25 00:15:44
【问题描述】:
AFAIK,V8 中大致有两种代码对象。一种是由 Ignition 解释的 javascript 字节码,另一种是由 Turbofan 编译和优化的机器码。根据execution/frames.h,V8 为每种代码对象构造了不同的堆栈帧。这意味着 V8 在执行之前应该知道callee 的类型。
当未优化的代码(JS 字节码)调用优化的代码时,我猜 Ignition 可以正确处理这种情况,为优化的代码构建一个新的堆栈帧。但是,当优化后的代码(机器码)调用未优化的代码时,我很好奇 V8 是如何确定 callee 是否未优化的。如果机器代码直接在处理器上运行,没有什么可以帮助 V8 确定callee 的种类。
另外,在我的理解中,V8 应该检测某些代码依赖是否受到损害,以标记或取消优化无效的代码对象。如果 V8 不监控机器代码的执行,这似乎也不可行。
所以我的问题是:
-
V8 是否监控(优化的)机器代码的执行?如果是这样,它是如何发生的?
-
如果
1为false,那么V8如何检查代码依赖失效或检测callee是否编译?
【问题讨论】:
-
“监控”是什么意思?
-
"没有什么可以帮助 V8 在执行调用指令之前确定被调用者的类型。" - 为什么需要它?设置新的堆栈帧是被调用函数(或者可能是
call本身)的工作,它不需要在执行call指令之前发生。 -
@user2864740 据我所知,Turbofan 在编译期间会将依赖项安装到代码对象中。(请参阅 DependencyGroup@code.h)。如果依赖项之一被破坏(无效),则代码被取消优化或将被取消优化。
-
@Bergi 我的意思是字面上的执行监控。如果 V8 不监控机器代码的执行,那么 V8 是如何在执行时检测到某些代码依赖的失效呢?比如我们看test/mjsunit/compiler/deopt-lazy-shape-mutation.js,假设
change_o被优化了,那么v8怎么知道f返回时应该去优化。 -
@SeungwanKwon 您可能对these slides 感兴趣,它详细介绍了该示例;)(虽然它已经过时,但它仍然对实时修补的概念提供了一些概述)
标签: javascript compiler-construction v8 jit execution