A note to our readers: You asked so we have developed a set of features that allow you to reduce the noise: you can get email and web notifications for topics you are interested in. Learn more about our new features.
オラクルはGraalVMの1.0リリースを発表した。これは多言語対応の仮想マシンとプラットフォームである。最初のリリースにはJavaとJVM言語の実行機能 (バイトコードを通じて)とJavaScriptとNode.JSの完全なサポート、RubyとPython、R、LLVMバイトコードのベータでのサポートがある。
プラットフォーム全体は多数のコンポーネントから成る。
- Graal - Javaで書かれたJITコンパイラ
- SubstrateVM - 実行コンテナを考慮せずに済む軽量ラッパ
- Truffle - 言語インタプリタ構築用のツールキットとAPI
全体としての目的は別の実行コンテナ内に組み込める多言語実行環境を提供することである。OpenJDKコンテナや別の可能性、たとえばオラクルやMySQLデータベースの中といったものだ。
InfoQはOracle LabsのResearch DirectorであるThomas Wuerthinger氏に声をかけ、GraalVMについて詳細にインタビューした。
InfoQ「GraalVMの歴史を解説してもらえませんか?これはどこからやって来たのでしょう?」
Wuerthinger氏「コンパイラが言語のセマンティックスについてあらかじめ知る必要がないようにすることが目的でした。オラクル内のグループがJavaScriptやR、Rubyといったとても多様な言語に初めから明確に興味があったことが理由です。
いくつかの調査で改善できると感じた重要な領域が2つありました。
- 当時のソフトウェア業界でのVMアーキテクトの一般的な考えは、最適なパフォーマンスを得るには言語のVMは言語のセマンティックスを考慮して特別に設計する必要があるというものでした。
- Javaアーキテクトは多言語の使用をサポートする作業をJava 7から始めていました。JVM仕様に`invokedynamic`を追加してJavaバイトコードを変更しました。JavaバイトコードがあまりにJavaのセマンティックスを組み込みすぎているので、長期的な取り組みの方が効率的で、さらに100%互換の実装にできるかもしれないとGraalVMチームは感じていました。
また、パフォーマンスの優位性がある完全な多言語用エンジンを実証するという目標もありました。他の言語を研究するため大学とコラボレーションを始めました。
パデューのグループはRの実装をし、カリフォルニア大学アーバインのグループは2012年から2014年にPythonの実装をしました。インターン生は論文のテーマプロジェクトとしてRubyを研究しました。これには多くの変わった、興味深い性質がありました。私たちの多言語用コンパイラが十分に一般的なものであるか、よい試験紙となったと考えています。後にこれらの言語プロジェクトをOracle Labsに持ち込みました。これらの言語を業界品質の実装とするためです。
GraalVM 1.0のリリースで、パフォーマンスの優位性がある多言語VMが可能であることと、それを実現するもっともよい方法というのはJavaやMicrosoft CLRのような言語固有のバイトコードを通じてではないということの両方を実証したと感じています。」
InfoQ「GraalVMを構成する重要な技術は何でしょうか?それらは開発者にとってどのように役立つのでしょうか?」
Wuerthinger氏「GraalVMにある重要な技術的アイデアは"部分評価"と呼ばれるものです。これはインタプリタをコンパイラに自動的に変換する技術です。これにより新しい言語をすぐに構築できます。言語開発者はASTインタプリタを構築することだけにフォーカスできます。コードジェネレータやガベージコレクタのような他の低レベルのランタイム機能を気にかける必要がありません。
GraalVMに組み込んだ重要な技術は論理/物理のデータ分離です。これによりあらゆるメモリデータレイアウトをローカル言語のオブジェクトのように見せられます。ほとんどのVMにはオブジェクトに対し固有のレイアウト ("boxes"とよく呼ばれているオブジェクトヘッダを持って)があります。言語にあるオブジェクトのセマンティックスを持つように、データは同じレイアウトを持たなければなりません。
これが意味することは、ほとんどのVMでは"オブジェクト"となるにはメモリを割り当て、データをコピーしなければならないということです。
Graalでは、言語間の相互運用がコストゼロでできます。JavaScriptオブジェクトを、JavaScriptオブジェクトだけでなくRオブジェクトや他のどんなものでもそのように振る舞わせることができるからです。しかも追加のオブジェクト生成やデータコピーの必要なしにです。
これによりたとえば高レベルなオブジェクトの形式の独自のバイナリフォーマットから、こうした高レベルオブジェクトを実際に割り当てることさえせずにプログラムへデータを露出させることもできます。
別の重要な技術はLLVMインタプリタです。一般的なLLVMコンパイラの出力であるLLVMバイトコード向けのGraalVMインタプリタがあります。これはネイティブバイナリを対象とした言語 (C++やFORTRAN、Rustなど) とうまく機能します。
言語実装における重要な問題の1つは、通常それらにはネイティブコードで実装されたライブラリがあるということです (たいていはC/C++)。それらは言語の内部をいくらか露出させるAPIを使います。なので言語エコシステムと互換性があるようにしたいなら、そのネイティブライブラリをサポートしなければなりません。
JRubyやNashornでの実装の問題の1つはネイティブな部分を持つモジュールには有効でないということです。これは互換性の問題なのです。
最後にして別の、あとで追加されたGraalVMの技術的要素はSubstrateVMと呼ばれるものです。ここでのアイデアはVMを組み込み可能に、そして必要に応じて組み合わせられるというものです。Java Hotspotのような従来の言語VMはすべてを制御しようとします。どのスレッドをスケジュールし、メモリ割り当てがそれらのスレッドにどのように分配されるのか、OSへのアクセスは、などです。
基本的なシステムでこうしたサービスのいくつかを提供できるような技術レイヤを求めました。SubstrateVMで動的なJITコンパイラ (ガベージコレクタのような) をサポートするために必要なものという観点から欠けていたピースを作り上げることができました。たとえばデータベースを実行しているとき、データベースはメモリ管理、スレッド割り当てなどを制御しようとします。
SubstrateVMは"非常に薄い"VMで、データベースのようなものの上に乗せることができます。そのためGraalコンパイラをそこで実行するとき、Javaのメカニズムではなくデータベースが最大ヒープサイズを指定できます。JVMクラスローダなどではなくデータベースがコード成果物を管理できます。
SubstrateVMを運用する有力な方法の1つはJavaコード (Graalのような) を閉じた世界という仮定 (使用するクラスはすべてコンパイル時にわかっているはずである) を使ってネイティブバイナリに直接事前コンパイルすることです。そのためデータベースにGraalコンパイラをデプロイするとき、GraalとGraalVMの言語の一部を選びネイティブの共有ライブラリにコンパイルします。それらは実行時にコンパイルする必要がありません。」
InfoQ「Truffleとは何ですか?なぜそれが必要なのですか?」
Wuerthinger氏「TruffleはAPIです。新しいGraalVMの言語を構築するとき、APIに対してGraalVMのインタプリタを書かなければなりません。インタプリタが動作する方法としては、最初にソースコードを抽象構文木またはASTと呼ばれるものにパースします。たとえばc = a + b
のようなコードを書いたとき、そのASTにはノードが2つあります。1つ目は子ノードa
とb
を持つ加算のオペレータです。2つ目はcと加算のオペレータノードを子ノードに持つ代入です。
ASTのようなインタプリタの内部ではTruffleのインタフェースを継承する必要があります。そうすれば、Graalコンパイラは言語インタプリタの活動を観察し言語のセマンティックスを学習します。言語のコンパイラを生成できるようにするためです。」
InfoQ「GraalVMのもっとも知られているコンポーネントの1つはGraalコンパイラ、これはJavaベースのJITコンパイラで単に"Graal"としても知られています。Graalが過去のものとしようとしているC2 (OpenJDKにある既存のC++のJIT) にある難しさについて話してもらえませんか?GraalがOpenJDKのメインラインでデフォルトとしてC2 / 階層型コンパイルに取って代わると考えていますか?」
Wuerthinger氏「GraalコンパイラはJava 10で実験的コンパイラとなりオラクルは今後のリリースでデフォルトとなると楽観的に考えています。
Graalのようなコンパイラにある大きなアドバンテージは最初に自身をコンパイルする (Javaで書かれているので) ことで、これによりC2がしているようなC++のASTで直接動作させるよりも高レベルな方法でGraalを書くことができます。よってGraalはたとえばより積極的なインライン化やオブジェクトのエスケープ解析をより簡単にできます。オブジェクトの割り当てをプログラムから自動的に削除できます。一般的にプログラムがより抽象化されればされるほど、Graalコンパイラがより役立ち、Java8もしくはScalaでのStreamやラムダのサポートといったことでパフォーマンスの恩恵を最大限得られます。」
InfoQ「オラクルは多言語VMとしてGraalVMを大きくマーケティングしています。1.0リリースの内容はJava 10の一部として出荷されたものとどのように異なるのでしょうか?たとえばJRuby開発者はどちらのリリースを選ぶべきでしょうか?GraalVMはOpenJDKとは別のプロジェクト、それともその一部として見ればよいでしょうか?Graalの今後のリリースはJavaのリリースサイクルと結びつくのでしょうか、それとも別々となるのでしょうか?」
Wuerthinger氏「GraalVMとJavaはともに巨大なオープンソースの存在で別のリリースサイクルを持つ100%別のプロジェクトです。両方が互いの技術の一端を握っています。Java 10はGraalVMからコンパイラを自分のものとしており (実験的オプションとして)、GraalVMはサポートする言語の1つとしてJava 8の大部分を受け入れています。GraalVMは単にJavaだけではなく多くの言語を受け入れており、Node.jsやJRuby、GNU R実装などからの技術を使っています。
組織を横断する技術的な生産者/消費者関係のほとんどにあるように、消費者は他からの新技術が安定するのを待ってから使います。 同様に、Javaプラットフォームグループは新技術の使用に関して既存の展開物を壊さないと確信があるまで保守的でなければなりません。下位、上位互換に多くの懸念があるので、いくらか時間差があるでしょう。」
InfoQ「IBMのOpenJ9ランタイムはGraalVMと異なるアプローチを取っています。あなたから見たOpenJ9 / OMRとの主な違いを説明してもらえますか?またGraalVMを類のないものにしていることについても話してもらえませんか?」
Wuerthinger氏「OpenJ9は既存の単一の言語ランタイム (Ruby MRIのような) にいくらか制限されたジャスト・イン・タイムコンパイル機能を追加することでそれをスピードアップしようとしています。彼らのアプローチの長所は互換性を保ちつつ既存のランタイムに合わせるのがより簡単であるということです。しかし主なデメリットは利点がかなり制限されているということです。
第一に、彼らのRubyプロトタイプのパフォーマンスの優位性はGraalVM上で実行するRubyが達成した指標と比較すると非常に小さいものです。その理由はOMRが既存のインタプリタのデータ構造を保ったままなのに対し、GraalVMがよりプロファイリングし推測した最適化をして動作するからです。
第二に、あちらはコードジェネレータを書くことを要求しますし、部分評価を通じてインタプリタからコンパイルしたコードを自動的に導出できません。
第三に、ビルトインで物理/論理データを分離していません。
これはもっとも重要な第四の点を導きます。彼らのアプローチでは効率的な言語の相互運用ができないということです。
OMRはまだあまり最適化されていないRuby MRIのような既存の単一言語ランタイムに対し周辺部の改善を提供します。GraalVMは大幅な改善と多言語を扱うという要件がある言語を書くにあたり、まったく新しい方法を使います。どんな言語の組み合わせでもオーバーヘッドなく相互運用して実行できます。
InfoQ「Graalにより広くコミュニティを巻き込むというのはどうですか?Twitterはアーリーアダプタとして記録されており本番環境でGraalを実行しています。他に誰がすでに使っていますか?オラクルではない開発者と作業をした経験はどうだったでしょうか?今後のGraal開発はどのような感じでしょうか?総じてOpenJDKに似たモデルを採用するのでしょうか?」
Wuerthinger氏「OpenJDKはGraalVMとかなり異なるミッションを持っています。
OpenJDKは開発者と大きな接点があります。ずっと新しい言語機能とライブラリを作成しているからです。OpenJDKの変更の多くに対応するには、コードを変更しなければなりません。ミッションはどの変更に価値があるのかコミュニティの合意を得ることです。OpenJDKのコミュニティはとても大きく、たくさんの選択肢があり、プロセスはコミュニティの合意を得るのに役立ちます。
GraalVMはすでに存在する言語やライブラリにあるコードをより効率的に、より多くの場所で、より相互に運用し、言語のセマンティクスを (大部分) 変更することなく実行させるものです。そこにある開発者との重要な接点は、他のランタイムにある異質な言語機能を呼び出せる相互運用APIのみです。できる限り水位線の下に留まろうとしています。
GraalVMがサポートする各言語のコミュニティはどのように発展すべきかについて各々の結論に達しています。
OpenJDKと同様に、GraalVMはレッドハットやインテル、AMDといった大手ベンダから大きな貢献を多く受け取っています。レッドハットは以前からイニシアティブを取り、私たちからほとんど情報を提供することなくGraalVMのARMバックエンドを構築しています。これは私たちにとってとても役立つものになりました。オラクルがARMベンダに投資していたことは知っているかもしれませんが、そのため今私たちはこのエコシステムにより注目しています。
こうしたベンダはGraalVMは投資に値するものであると他者から十分に理解を得ていると考えており、彼らの関心は自分たちの使い方のことが第一ではありません。ご指摘のように、TwitterはGraalVMへコントリビュートしてきました。彼ら自身が使っているからです。Twitterがしたように公開してはいないが、GraalVMを使用している主要な技術ベンダは他にもいくつかあります。オラクル内部にもユーザがいます。」
InfoQ「オラクルはたいてい今後のロードマップについてあまり語りません。GraalVMの開発が今後の18ヶ月で向かう場所について示してもらえませんか?」
Wuerthinger氏「そうですね、GraalVMチームはOracle Labsにあります。そのため多少逆の問題があります。多くの研究プロジェクトを持っており、それらは公開されています。学会での論文を超えたところへ行くかもしれないし行かないかもしれません。Oracle Labsには多くの大学生の協力者がおりGraalVMを使ってアイデアを試しています。
JavaScriptだけでなくあらゆる言語をブラウザで扱えるように、GraalVMをChromiumにリンクすることを考えた学生が1人います。しかしこれがオラクルの製品としてリリースされることはまずないというのは明らかでしょう。他の変わったアイデアを見るためGraalVMをベースにした論文を探すというのは確かにできます。コミュニティの関心に基づき、他のいくつかの言語をどうなるかわからない研究プロジェクトとして調査しました。
ロードマップについて言えることはより多くのプラットフォームをサポートするよう取り組んでいるということです。初回リリースでは"リリースのストレス"を最小限にすべくLinux/X86とMac/X86だけでした。Windowsのサポートに積極的に取り組んでおり、ARMプラットフォームのサポートにも (レッドハットとともに) 取り組んでいます。また現時点では"実験的"としている言語、たとえばRやRuby、Pythonに必要な安定化と網羅性への作業もかなりあります。
統合という観点では、MySQLとOracle RDBMSとGraalVMを深く統合している方法がいくつかあります。今後の18ヶ月で目にするでしょう。しかしこの18ヶ月でGraalVMがどのようになるかはすべてコミュニティからのフィードバックとコントリビュートに大きく依存するでしょう。
Rate this Article
- Editor Review
- Chief Editor Action