プロセスVM
Virtual Machine
その命令セットで書かれたプログラムを読み込み、実際のコンピュータ上のCPUが解釈可能なネイティブコードに変換し実行する
何が嬉しくてVMを使うか
移植性が高い
VMを複数プラットフォームで実装することは、コンパイラを作ることよりも容易
自力で機械語に変換するのが大変ってことか
多分違う。抽象度の低い高級言語の解析よりは、単純で抽象度の高いIRを解析して機械語などに変換するほうが簡単ってこと
それぞれのCPUに合わせてコード生成をする処理を書き直さなくて済む
ターゲットとなる言語に合わせて設計できるので、用意する命令セットがその言語の実現に必要なものだけに限定できる
あまり明示的な説明がないが、VMはスタックマシンやレジスタマシンなど機械語と似た構造をしていることが前提にあるのか
機械語がスタックマシンやレジスタマシンであることも前提か。
というか、ASTのようにツリー構造なのではなく
バイトコードのように命令の並びが一本道になっているもの
n個のアーキテクチャとm個の言語がある時に、その組み合わせ全てを実現するためにはn*m個の実装が必要だが、VMを挟むことでn+m個に減らせる
最適化がしやすい
高級言語よりはシンプルなIRの方が最適化を施しやすい
別のプラットフォームを対象としたコンパイラが必要な場合VMを置き換えるだけで済む
つまり、フロントエンドを触らなくて済む
複数の言語のコンパイラによって、同じVMのバックエンドを利用できる
コードの共有、複数言語での相互利用が可能になる
例えば科学計算を得意とする言語A、UIを扱うことが得意な言語Bがあるときに、一方で書かれたルーチンをもう一方の言語から呼び出すことができる
モジュール性
VMの実装を改善すれば、それよりも上のレイヤのコンパイラは全てその恩恵を受けられる
既存技術の再利用
あるVM実装を備えるコンピュータやデジタル機器は、これまでそのVMのために開発されてきた豊富なソフトウェアを利用できる
もう少しわかりやすい具体例が欲しい

既存技術への機能追加
下位レイヤーではなかった機能をVMで追加する
セキュリティのためのチェック機構とか
速度改善
前提: 指定したアドレスにあるデータをメモリバス経由で取り込む時間は、CPUの実行速度に比べて低速
だから、CPUの中のメモリキャッシュを使いたい(速い)
しかし、このメモリキャッシュの容量は少ない
メモリキャッシュを上手く使えるのは、メモリアクセスの局所性があるとき
しかし、構造木インタプリタはキャッシュアクセスという観点からは最悪
構文木を構成する1つのノードは別々の構造体
これらのアドレスは近いとは限らない、連続もしていない
だから、メモリキャッシュを上手く使えない
VMのデメリット
ハードウェアで直接実行するものに比べると数倍から数百倍、パーフォマンスペナルティになる
VMはCPUをエミュレートして実行しているから。
JITコンパイルなどを使って対策してる
VMの例
コンパイラが中間言語で書かれたコードを生成
CLR(Common Language Runtime)というVM上で実行される
VM言語の具体例
pコード
バイトコードによるコマンドを生成
JVM上で実行される
VMの実装手法
インタプリタによる方法
専用に設計されたハードウェアによる方法
VMプログラムを対象プラットフォームの機械語に変換するによる方法
命令フォーマット
動機としてはインタプリタループを効率化したい
インタプリタループはswitch文で命令で分岐して処理をするもの
GCCの拡張機能を用いる
switch文の代わりにgoto文を用いる
>ある種のCPUは、アドレスが特定の数の倍数になっていないアドレスへのダイレクトアクセスはエラーになります。その場合はアラインメント(アドレスが特定の数の倍数に揃っている状態)されているアドレスからデータを取り出し、ずれた文を切り出すようなことをする必要があります。エラーにならなくても倍数のアドレスとそうでないアドレスとで(内部的に上記の切り出しを行うなどの理由で)アクセス速度がかなり異なるCPUは珍しくありません。 『言語のしくみ』 p.35
VMコードをどう使うか
VMコードを、対象のプラットフォーム用の機械語へ変換
エミュレータ上でVMコードを実行
こっちのほうが実装が容易だが、速度は落ちる
配布時の工程
開発者はプログラムをIRに変換し、配布する
利用者はVM上でそのIRを実行する
こうすることで
開発者は利用者の機種やOSごとにプログラムを用意しなくて済む
利用者は環境問わずそのプログラムを利用できる
VM変換器
VM translator
VMコード→アセンブリコードへ変換
VM言語に含まれるコマンド
算術
メモリアクセス
プログラムフロー
サブルーチン呼び出し
実用的なアイディア
コードの上位互換性を満たすために、新しいプラットフォーム上で前世代のコンピュータをエミュレートする
参考

p.142-
高水準言語の for
や while
を、VMの goto
などを用いて書き換えないといけない
良さそう
参考
OSも一種の仮想化
CPUを抽象化している
起源