Java VM は「スタック方式」で動作するスタックマシンですが、動的コンパイルされた部分はRISC、CISC、EPICなどのネイティブコードに変換され、「汎用レジスタ」を利用するコードへと変換されます。汎用レジスタを利用することにより、動的に生成したネイティブコードをより高度にスケジュールして、コードの並列化などの最適化を行うことができます
チューニングのためのJava VM講座(前編):Hotspot VMの基本構造を理解する (2/2) - @IT
JVMはレジスタを持たないスタックマシンであるため、計算時の作業領域としてスタックを利用している
JVMはスタックマシンでも、JITでレジスタを利用するようにコンパイルはしているので、実際にレジスタを利用しないわけではない
- JVMのスタックはレジスタ的なもの
- MIPSに限らずCPUが扱うのはレジスタとメモリでローカル変数という概念は存在しない
- JITでレジスタを利用するようにコンパイル
以下ツイート。
@shigemk2 ストアの書き込み先はメモリです。JVMではスタックがレジスタ的な扱いで、ローカル変数がメモリだと解釈してください。MIPSはスタックもローカル変数もメモリなのであって、ストアの対象はスタックではなくメモリです。
— 七誌 (@7shi) May 26, 2015
@shigemk2 MIPSやPowerPCでもローカル変数の書き込みにストアを用いています。そこを起点に考えてください。JVMのスタックはメモリ扱いされていないので、スタックを基準に考えないでください。スタックを基準に考えるから逆に思えているのです。
— 七誌 (@7shi) May 26, 2015
@shigemk2 MIPSにローカル変数があるというのは、勘違いして変なものを想像していると思われます。MIPSに限らずCPUが扱う対象はメモリとレジスタしかありません。ローカル変数はコンパイラが作る概念です。JVMはレイヤが違うので同列に考えない方が良いです。
— 七誌 (@7shi) May 27, 2015
@shigemk2 それが「レイヤが違う」ということです。CPUによってレジスタの数が8個とか32個とか全然違うので、CPU依存をなくすためレジスタをなくしました。しかし馬鹿正直にスタック操作を実行するわけではなく、JITでCPUに合わせてレジスタを使うように変換されます。
— 七誌 (@7shi) May 27, 2015
@shigemk2 逆アセンブルを読みなら以下のことから想像すれば、当りが付きそうなものですが。
1. Javaのモットーが"Write once, run anywhere"であること
2. JITしていること
3. スタックがレジスタ的なものという説明を受けたこと
— 七誌 (@7shi) May 27, 2015
@shigemk2 CPUは熱血本で見たようにそれぞれ違うわけですが、JVMはそれと同列のものではなく、高級言語寄りに抽象化された一段レイヤの高いもの、という基本認識を持ってください。レイヤが高いということは、実行時に機械語に降ろす必要があって、それがJITということです。
— 七誌 (@7shi) May 27, 2015
JVMはレジスタを使わないといってもそれはコンパイラ的な概念で、JVMのスタックがレジスタ的なもの。というか、JVMのスタックやローカル変数とはCPUのレジスタやメモリとは別のレイヤの話なので、安易に比較してはいけないという戒め。