HSimulate這條Hydrogen里的instruction到底是什麼意思?
V8 Crankshaft編譯架構的Hydrogen IR中的其他指令都很容易理解,唯獨這個 HSimulate 怎麼都看不懂。而且與Crankshaft相對應的HotSpot C1中也沒有找到這條指令。求指導。
這是跟V8從Crankshaft開始支持的deoptimization功能相關的HIR指令,用於記錄信息以便將Crankshaft優化編譯的代碼的狀態映射到非優化的FullCodeGen的狀態。
Sasha大大(Vyacheslav Egorov)如是說:Optimizing for V8 - Hydrogen
Simulate is a pseudo-instruction that marks a deoptimization point. If some check fails then execution will continue from a place in non-optimized code that corresponds to the closest dominating simulate; simulate id will be used to find this place. This is called deoptimization. Information that each simulate is carrying around describes changes to the state of unoptimized code happened since the previous simulate (which locals were assign, what was pushed on the expression stack). This is used to build description of non-optimized frame that will be used for frame rewriting during deoptimization. Hope this explains it.
另外一個演示稿大致介紹了V8中的deoptimization:
High performance JavaScript with V8
第40頁開始
而這篇文章更直接的講解了HSimulate在deoptimization實現中的作用:
Deoptimize me not, v8
HotSpot C1 / Maxine C1X編譯器中沒有直接與HSimulate對應的指令,但deoptimization還是實現了的。
在C1 / C1X中,任何一個可能帶有safepoint的HIR指令都是潛在的deoptimization位置。它們會攜帶 ValueStack / FrameState對象來描述解釋器棧幀的slot與HIR指令之間的關係,以便在需要deoptimize的時候從C1 / C1X的編譯方法的棧幀重新構造出對應的解釋器棧幀。
V8的HSimulate與C1 / C1X中帶有ValueStack / FrameState的HIR指令的最大區別,就是V8里多條可能deoptimize的HIR指令可以共享同一個HSimulate,而C1 / C1X的則是在deoptimize可能發生的HIR指令上直接攜帶映射信息。
V8的HSimulate做法可以讓代碼更加精簡,被deoptimization信息所捕獲的HIR會更少,減少了deoptimization對編譯器優化帶來的干擾。
同樣的思路在別的地方也有應用,例如說Graal編譯器的Guard IR指令。請參考論文:An Intermediate Representation for Speculative Optimizations in a Dynamic Compiler
推薦閱讀: