16

サイド プロジェクトの背景として、さまざまな仮想マシンの設計について読んでいますが、もちろん JVM が最も報道されています。また、BEAM (Erlang)、GHC の RTS (VM のようなものですが、完全な VM ではありません)、および JavaScript の実装の一部についても調べました。Python にはバイトコード インタープリターもありますが、これは存在することは知っていますが、あまり読んだことがありません。

私が見つけられなかったのは、特定の言語に対して特定の仮想マシンの設計が選択された理由の適切な説明です。私は特に、並行言語や非常に動的な (Ruby、JavaScript、Lisp) 言語に適合する設計の選択に関心があります。


編集:具体性を求めるコメントへの回答として、ここに例を示します。JVM はレジスタ マシンではなくスタック マシンを使用しますが、これは Java が最初に導入されたときに非常に物議をかもしました。JVM を設計したエンジニアは、プラットフォームの移植性を意図してそうしていたことが判明し、仮想レジスタが多すぎたり少なすぎたりするインピーダンスの不一致を克服するよりも、スタック マシンをレジスタ マシンに変換する方が簡単で効率的でした。

もう 1 つの例を次に示します。Haskell の場合、注目すべき論文は、Implementing lazy functions languages on stock hardware: the Spineless Tagless G-machineです。これは、私が知っている他のタイプの VM とは大きく異なります。実際のところ、GHC (Haskell の主要な実装) は実際には動作しませんが、コンパイルの中間ステップとして使用されます。Peyton-Jones は、動作しなかった仮想マシンを 8 つも挙げています。一部の VM が成功し、他の VM が失敗する理由を理解したいと思います。

4

3 に答える 3

2

あなたの質問に別の方法でお答えします。VM とは何ですか? VM は、ソース言語よりも低レベルの言語の「インタープリター」の単なる仕様です。ここでは、「インタープリター」という単語のブラック ボックスの意味を使用しています。VM がどのように実装されるかは気にしません (バイトコード インターペレタ、JIT コンパイラなど)。そのように表現すると、設計の観点からは、VM は興味深いものではなく、低レベル言語です。

理想的な VM 言語は 2 つのことを行います。1 つは、ソース言語を簡単にコンパイルできるようにすることです。そして 2 つは、ターゲット プラットフォームでの解釈を容易にすることです (ここでも、インタープリターは非常に素朴に実装されるか、Hotspot や V8 のような非常に洗練された JIT である可能性があります)。

明らかに、これら 2 つの望ましい特性の間には緊張関係がありますが、多かれ少なかれ、考えられるすべての VM の設計空間を通る線上に 2 つの終点を形成します。(または、これは平らなユークリッド空間ではないため、線よりも複雑な形状かもしれませんが、アイデアは得られます)。その境界線をはるかに超えて VM 言語を構築すると、あまり役に立ちません。それが VM の設計を制約するものであり、VM をその理想的なラインのどこかに置くことです。

この線は、高レベルの VM が言語固有である傾向があるのに対し、低レベルの VM は言語にとらわれないが多くのサービスを提供しない理由でもあります。高レベルの VM は、その性質上ソース言語に近いため、他の異なるソース言語とはかけ離れています。低レベルの VM は、その性質上、ターゲット プラットフォームに近いため、多くの言語にとって理想的なラインのプラットフォームの端に近いですが、その低レベルの VM は、理想的なラインの「コンパイルが容易」な端からはかなり離れています。ほとんどのソース言語。

より広い意味で、概念的には、どのコンパイラも、ソース言語から中間形式への一連の変換と見なすことができ、それ自体が VM 用の言語と見なすことができます。中間言語用の VM は構築されないかもしれませんが、構築される可能性はあります。コンパイラは最終的に最終的なフォームを出力します。そして、その最終的な形自体が VM の言語になります。その VM を「JVM」、「V8」と呼ぶこともあれば、その VM を「x86」、「ARM」などと呼ぶこともあります。

それが役立つことを願っています。

于 2012-07-09T23:41:32.130 に答える
1

VM を派生させる手法の 1 つは、コンパイル チェーンをたどり、ソース言語をさらに低レベルの中間言語に変換することです。フラットな表現 (つまり、一連の「命令」にシリアル化できる言語) に適した十分に低レベルの言語を見つけたら、これはほとんど VM です。そして、VM インタープリターまたは JIT コンパイラーは、シリアル化のために選択したポイントから変換チェーンを継続します。

一部のシリアル化手法は非常に一般的です。たとえば、式ツリーの疑似スタック表現を使用します (「実際の」スタック マシンではない .NET CLR など)。それ以外の場合は、LLVM のようにシリアライゼーションに SSA 形式を使用するか、(Dalvik のように) 無制限の数のレジスタを持つ単純な 3 アドレス VM を使用することができます。シリアル化は単なるシリアル化であり、通常のコンパイル方法を続行するために後でシリアル化解除されるため、どちらの方法を取るかは実際には問題ではありません。

VM コードをコンパイルするのではなく、すぐに解釈するつもりなら、話は少し異なります。現在、どの種類の VM が解釈に適しているかについて、コンセンサスはありません。スタック (またはあえて言えば Forth) ベースの VM とレジスタ ベースの両方が効率的であることが証明されました。

于 2012-07-01T09:02:35.067 に答える
0

この本は役に立つと思いました。ご質問の多くの点について説明しています。(私は決して Amazon と提携していませんし、Amazon を宣伝しているわけでもありません。リンクするのが最も簡単な場所でした)。

http://www.amazon.com/dp/1852339691/

于 2012-06-29T18:43:23.760 に答える