Mozilla Foundation(リンク)は、JavaScript性能の限界に挑んだトレースベースのJITコンパイラ、TraceMonkey(リンク)を開発した。Firefox 3.1(リンク)に搭載予定のTraceMonkeyはCに近い性能を発揮し、RIA開発を一気に新しいレベルに押し上げることが確実視されている。
Andreas Gal氏はTraceMonkeyのベンチマークについて以下のように述べている(リンク)。
TraceMonkeyはトレースベースのJITコンパイラで、JavaScript性能の枠を超えるものです。人気のあるAppleのSunSpiderベンチマークでは、Firefoxの前回リリース版と比較して、平均して4.6倍の高速化を実現しました。また、SunSpiderの全体的なランタイムは約1.83倍の向上を見せました(JITコンパイルの範囲外である通常のエクスプレッションエンジンなど、SunSpiderの一部の働きのため、全体的な高速化はあまり大きいとは言えません)。JavaScriptのコア言語機能に重点を置くSunSpiderのubenchスイートでは22倍の高速化を実現しています。どの測定基準を採用しても、今やFirefoxは世界最速のJavaScriptエンジンと言えます。
当該JITは、最適化前のCコード(gcc -O0)の性能におおよそ匹敵するコードを生成します。
同氏はトレーシングの仕組みについても説明している(リンク)。
従来のジャストインタイム方式のコンパイラ(SunのHotspot VMなど)は、スタティックコンパイラ(GCCなど)に非常によく似た設計、構造を持っています。これらはどのメソッドが頻繁に実行されるかを観察し、ある一定のしきい値に達したときにそのメソッドをネイティブマシンコードに変換します。このようなメソッドはしばしば性能に不可欠な要素(ループなど)を含む一方、多くの場合、低速なパスやループのないコードも含み、メソッドのランタイムにほとんど貢献することはありません。しかし、全体メソッドのコンパイラは、その一部が特にコンパイルする意義がないとしても、常にメソッド全体を分析し、変換する必要があります。
トレースベースのコンパイラは非常に異なった方式をとります。バイトコードの命令の解釈を仮想マシンで監視し、基礎をなすプログラム内においてループの指標となる、頻繁に行われる逆方向の分岐を調べ出します。そのようなループ開始点が見つかると、インタープリタがプログラムを実行し、途中で実行されるバイトコード命令のシーケンスを記録する流れに従って、インタープリタを追跡します。コンパイルはループヘッダで開始されるため、ループを経て繰り返しが完了すると、インタープリタは最終的にこのエントリポイントに戻ります。結果として得られる命令の直線的シーケンスが、トレースと呼ばれるものです。
トレースとは、ループを通した一回の繰り返しを意味し、複数のメソッドやプログラムモジュールにまたがることもあります。関数がループ内から呼び出されると、関数コールをたどり、呼び出されたメソッド内で実行される命令をインライン化します。関数コール自体は実際には記録されません。単にランタイムにて、その関数をアクティブにした条件と同じ条件が保たれていることを確かめます。
Mike Shaver氏はFirefoxのJavaScriptエンジンへの取り組み(リンク)についても語っている。
ここ数年、WebにおけるJavaScriptの性能は飛躍的な進化を遂げました。実際、あらゆるブラウザはエンジンを改善して実行速度を大幅に向上させました。たとえば、FirefoxはさまざまなJavaScriptベンチマークにおいて、Firefox 2の約3倍の高速化を実現しています。しかし当然、開発者やユーザーの性能への要求はとどまることを知らず、またMozillaとしてもそれを求めています。当社のアプリケーション自体、その大部分はJavaScriptで記述され、その傾向がますます進んでいるわけですから。Webアプリケーションの性能の向上に加えて、Firefox 3におけるJS性能に対する取り組みは、当社にとってアプリケーションの簡素化とレスポンスの向上をもたらしました。
Brendan Eich氏は、これらの開発が何を意味するのか(リンク)をブログで述べている。
詳細はさておき、特筆すべき点をいくつか紹介します。
- 現在、TraceMonkeyに対応するのはx86、x86-64、およびARMで、これはモバイルおよびデスクトップ向けのプラットフォームがすぐにでも実現可能であることを意味します。
- 性能が上がり続けるにつれ、人々はJSなど、ブラウザで実行するには「遅すぎ」であったコードを記述し、トランスポートするようになると思われます。これは、Webが、現時点では専用のプラグインを必要とする作業負荷に適応できるということを意味します。
- より多くのDOMや当社のその他のネイティブコードをトレースするため、攻撃に利用できるバグを決して含まない、信頼性のあるメモリセーフなコードベースが増えます。
- トレーシングはホットパスのみをたどり、トレースフリーのキャッシュを構築します。コールドコードをトレースしたりJITコンパイルしたりすることはなく、全体メソッドJITが招くメモリ肥大化を回避します。トレーシングはモバイルに適しています。
- ツールキット、シーングラフ、ゲームロジックなどのすべてをJSで記述するJS方式のレンダリングは、最高潮に達しつつある将来の波の1つです。
TraceMonkeyは、より多くのFirefoxコードがJSで記述されると予想される、来るべきMozilla 2時代へと私たちを進歩させてくれます。このプロセスが展開するにつれ、Firefoxはより高速に、より安全になるのです。
John Resig氏は、これらの重要な改善が、JavaScript言語およびRIAの将来にとって何を意味するかについても語っている(リンク)。
これが意味するもの、それはつまり、JavaScriptがかつては課題であった処理パワーのリソースにもはや縛られないということです。こうした改善によって、JavaScriptは従来的なあらゆるものを一気に別次元に引き上げ、Cのようなコンピュータ的に強力な言語と肩を並べるほどに至りました。
私は、より多くの大規模プロジェクトがJavaScriptで記述されていくことを全面的に期待しています。性能の向上を見込んだプロジェエクトも実際目にしつつあります。数が多い(画像操作など)またはオブジェクトが多い(リレーショナルオブジェクト構造など)アプリケーションもまた然りです。
私が特に胸を躍らせている分野の1つはCanvas関連です。大部分のCanvas大規模開発を阻む主な原因は、レンダリングではなく、言語におけるプロセッサの限界です(つまり、ベクトル、行列、または衝突検知に関連する、困難な数学演算の実行)。私はこの分野がFirefox 3.1のリリース以降に必ず爆発的に増加すると予想しており、実際、この取り組みが確固たるものになり始めている様子が伺えます。
このようなリリースを見ると、興奮が冷めやりません。JavaScriptはまさに、絶えずいずれの弱点も回避してすべての予想を吹き飛ばす、小さくてもやればできるという見本のような言語です。私はこれから何年先もずっと使用し続けるつもりです。
TraceMonkeyを試してみたい方は、Firefox 3.1 Nightly Buildが(リンク)ダウンロード可能である(about:configを開き、javascript.options.jit.content = trueに設定する)。これは未完成品でバグも存在するが、John Resig氏によると、このNightly BuildはほとんどのWebサイトを十分に取り扱えるほど優れているようだ。
Rich Internet Applicationについての詳しいニュースや記事については、http://www.infoq.com/jp/riaを参照されたい。