【发布时间】:2021-12-29 02:01:22
【问题描述】:
根据V8源码和turbofan资料,有一种去优化叫lazy deoptimization,描述如下(v8/src/common/globals.h):
惰性:代码已被标记为依赖于在其他地方检查的某些假设,并且可能会在下次执行代码时触发去优化。
但是,当使用 d8 观察 'v8/test/mjsunit/compiler/deopt-lazy-shape-mutation.js' 的执行时,我发现从函数 change_o 返回时发生了去优化立即。我猜这是因为f 对o 的映射依赖被执行change_o 破坏了,该change_o 操纵了o 的形状。
> d8/d8 --trace-deopt --allow-natives-syntax test/deopt-lazy-shape-mutation.js
[marking dependent code 0x3d7d00044001 (0x3d7d08293535 <SharedFunctionInfo f>) (opt id 0) for deoptimization, reason: code dependencies]
[bailout (kind: deopt-lazy, reason: (unknown)): begin. deoptimizing 0x3d7d08293779 <JSFunction f (sfi = 0x3d7d08293535)>, opt id 0, node id 20, bytecode offset 4, deopt exit 0, FP to SP delta 32, caller SP 0x7ffdaa56ff68, pc 0x3d7d00044111]
我的问题是:
-
究竟什么是惰性去优化? 在上面的例子中,可以理解为什么
f从change_o返回就被去优化的原因是change_o标志着f的一些假设已经被破坏了? -
惰性去优化是如何发生的? 在渴望去优化的情况下,我看到有名为
Deoptimize*的节点明确表示立即去优化条件,并使用call和条件跳转(例如jnz)组装成机器代码、ja等。但是,我无法弄清楚 惰性去优化 是如何进入执行流程的。是否有监督者监控call-ret操作,并在callee破坏caller的依赖关系时触发反优化?
【问题讨论】:
标签: javascript compilation v8 jit