ES-VM #1
(1)
- ES-Cでは、いきなりx86の機械語を生成するのではなく、仮想的なCPU(=VM)の機械語を生成して、そのVM用のコードから実CPUの機械語を生成するという仕組みを採用しようと思っています。
- これはx86だけを考えるのなら明らかに無駄です。x86だけ考えていればよいのであれば、こんな余計な中間レイヤはないほうが速いし、処理系は小さくできるのです。・・・しかしx86以外も考えるのであれば、この仕組みは理にかなっています。
- 今はx86やx64が主流ですが、今後もそうであるかは不明です。私は将来自作CPUを作るのかもしれません。そうなったら、自作のCPU上でES-Cを動かしたいです。もしこのVMレイヤがあれば、最小限の手間で自作CPUに移植できるでしょう。
- そういうVMレイヤがあったほうがよいのだとしても、自分でわざわざ独自仕様を考えたりせずに、それこそx86の仕様をそのまま使うか、もしくはそのサブセットでいいじゃないかという考え方もできます。この場合、x86であればVM用のコードはそのままかもしくは軽微な変換ですぐに実行できることになります。そして他のCPU上で動かす場合は、変換して動かすことになります。
- しかしこれはうまい方法ではないと思います。なぜならx86よりもレジスタを多く持つCPUはいくつかありますが、x86からこれに変換するとすべてのレジスタを活用しない機械語になってしまうからです。
- またx86は32bitもしくは64bitですが、遠い将来はもっと幅の広いCPUがでてくるかもしれません。そのときに32bitや64bitを前提にしている、ちまちまと計算するプログラムは、広いビット幅を十分には活用できません。
- ということで、VMレイヤの機械語の仕様は、ビット幅に上限がなく、またレジスタ数にも上限がないようなそういうものであるべきです。そしてそれぞれのCPUの実際の仕様に合わせて、必要に応じて多倍長演算したり、レジスタに乗りきらないものはメモリに置くなどして、機械語を生成することになります。
- x86やx64の仕様ではこれらを表現できないので、独自の機械語を考えようと思います。これがES-VMです。
(2)
- さてES-VMはコンパイラの移植性を高めるためだけの、単なる中間コードなのでしょうか。・・・そういう設計で作ることもできると思いますが、私は直感的にそれでは不十分だと感じています。
- ES-VMは、レイヤとして最下層であるべきです。つまり、実CPUの知識がなくても何も困らないようになっているべきです。
- たとえて言うなら、x86は世代によって内部構成が異なっていますが、それでも最適化の時以外はその内部構成に配慮する必要はありません。実にうまくできています。
- つまりデバッグの際にx86の機械語を見たり、x86のマシンのレジスタの値を見たりするというのはダメだということです。例外で止まったりブレークポイントで止まったりしたときは、ES-VMの命令のどこで止まったのか、その時のES-VMのレジスタはどうなっているのか、メモリはどうなのかなど、すべてES-VMの知識の範囲内で説明できなければいけないという意味です。
- 「とりあえずES-VMの機械語からx86に変換したよー、それじゃあとはよろしくねー」はダメだというわけです。
- 私は数年前からJITコンパイラを何度か作っていますが、その時に思ったのは、「なぜ21世紀にもなって、x86の機械語の知識がなければやりたいことができないのか」ということでした。プログラミング言語は何度も何度も大きな進化を遂げてきたはずなのに、そして普段はC++とかを使うだけで十分に高度なプログラムが書けるのに、JITコンパイラを作ろうと思ったとたんにすべてのメッキははがれて、機械語の知識が必要になってしまったのです。
gcc → アセンブラ → リンカ → 機械語
- こうなっているおかげで、アセンブラはWindowsの実行ファイル形式がどうなのかとかに煩わされることなく、x86のことだけを考えて作られている(そこはリンカがやってくれる)
- gccは、機械語のことを気にしないで、アセンブラを出力すればいい
- こういう積み重ねで、プログラミング言語は進化してきた
- それなのに、JITコンパイラを作ろうとすると、これらのツールは誰一人としてプログラマを助けてはくれなくて、プログラマは自力で機械語を生成しなければいけないのが現状。
- つまり、既存ツールは、「より下位の知識が全く不要な世界」を十分には構築できていなかった。
- だからもういかなる時もES-VMより下のレイヤの知識がなくてもいいようにする、それが目標です。
(3)
- 今更なのですが、結局私が第一世代OSASKで掲げたエミュレータOSという構想は、究極的には「移植作業のいらない世界」を作ることでした。そのためのエミュレータOSでした。
- 今は、Javaがあり、.NETがあり、Monoがあり、LLVMがあり、JavaScriptがあり、WebAsmがあります。しかしどれも大変に巨大です。私から見れば、絶対にもっと小さくできるはずだと確信するには十分すぎるほど巨大です。
- 私はES-VMによって、「移植作業のいらない世界」を作りたいのです。これは私の長年の夢なのです。
(4)
- [1]ES-VMのバイトコードとターゲット情報を渡すと、機械語を生成して返してくれる。そういう関数がある。
- これは純粋に単純なフィルタでしかないので、このプログラム自身も究極的にはES-VMのバイトコードで記述可能なはず。これができれば、爆発的な早さでクロスコンパイラを整備できる。
- ターゲットを現在動作中のものにして、返された関数をすぐに呼び出せばJITコンパイラになるし、ファイルとして出力すれば、普通のコンパイラやアセンブラになる。
- どのラベルがどのアドレスになったかなどの情報も提供する。変数やレジスタの割り当て状況なども報告する。型の対応関係も。
- 変換に際しては、安全モードと高速モードを提供。
- またステップ実行的なこともできるようにしたい(そういうモードがある)。
- [2](これは年内に作る予定はないけど)x86の機械語を渡すとES-VMのバイトコードを生成する機能もいつか作りたい。
- これができると、Windowsの実行ファイルが「はりぼてOS」で動くとか、ラズベリーパイで動くとか、そういうことができるようになる・・・はず。
- もちろんx86だけではなく、他のCPUやWindows以外のファイルにも対応する。
- まあ、5年後とか10年後だよな、たぶん。
- 文章にして書いてみると、かなりかつての「エミュレータOS」がやろうとしていたことに近いなーと思う。
- ES-VMは言語処理系のバックエンドとして考えていたけど、エミュレータOSのバックエンドとしても相当に魅力的な気がしてきた・・・。
こめんと欄
- 今こそ私は Inferno OS を勉強するべきなんじゃないかという気はする。 -- K 2020-06-25 (木) 17:24:15