Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

JITコンパイルでのOSRとは

JITコンパイルのログなどを見ると、OSR(on-stack replacement)という単語が出てきます。このブログでも以前JITWatchを触ったときに少し書きました。

OSRはOn-Stack replacementのことで、ループ内の最適化のことを指します。

jyukutyo.hatenablog.com

で、今改めて考えると、わかったようなわかっていないような感じです。理解を深めます。

HotSpot用語集にはこう書かれていました。

on-stack replacement Also known as 'OSR'. The process of converting an interpreted (or less optimized) stack frame into a compiled (or more optimized) stack frame. This happens when the interpreter discovers that a method is looping, requests the compiler to generate a special nmethod with an entry point somewhere in the loop (specifically, at a backward branch), and transfers control to that nmethod. A rough inverse to deoptimization.

HotSpot Glossary of Terms

'OSR'としても知られる。インタープリトされた(もしくは少し最適化されただけの)スタックフレームをコンパイルされた(より最適化された)スタックフレームに変換する処理である。これはインタープリタがメソッドがループしていることを発見し、コンパイラにループ内のどこかにあるエントリポイント(とくに後方分岐)で特別なnmethodの生成を要求し、制御をnmethodに移したときに起こる。大雑把に逆は脱最適化である。

ループ処理をインタプリトしている途中で、コンパイルしたマシンコードに処理を移すということです。

こちらのBrian Goetz氏の記事にもこうありました。

www.ibm.com

ループの最中にインタープリターからコンパイルしたコードに切り替われるように(あるいは、別々にコンパイルされたもの同士を交換できるように)on-stack replacement (OSR) と呼ばれる手法を使っています。

ループ内の処理が完了する度に、ブランチカウンタをインクリメントし値を検査します。閾値に達するとループはコンパイル対象になります。このコンパイルがOSRです。

ループがコンパイルされるだけでは不十分で、JVMがループの実行中にコンパイルしたループのコードを実行するよう切り替える必要があります。ループ実行中はスタックでの処理なので、JVMはスタック上のコードを置き換えるわけです。つまりスタック上の置換、On-Stack replacement。その後ループはより速いコンパイルコードを実行します。

商用Java処理系の研究開発のスライドにも記載がありました。