はじめに
WebAssembly(WASM)において標準化が最終段階にあるガーベージコレクション(GC)サポート(WasmGC)についてChromeのJavaScriptエンジンであるV8のブログに興味深い投稿がありました。
WasmGCの最大の特徴はもちろん、Dart、Java、Kotlin、Go、C#等のメモリ管理をGCに頼る言語(GC言語)においてWASMをターゲットとしたコンパイラ実装が容易になることです。
また、WASMにコンパイルしたGCエンジンをアプリに同梱するのと比較して、アプリのロード、実行時間、メモリ管理が効率的になります。
しかし、個人的に同ブログで最も興味深かったのは最適化に関する話題でした。
以降、WasmGCにおける最適化について話します。
ツールチェーン最適化(AOT最適化)
下図は同ブログからの引用です。
上図において、各ボックスはコンパイラツールチェーンにおけるツールです。
Source codeはソースコードから中間表現(IR)を生成するコンパイラのフロントエンドツールです。
Language optsは言語固有の最適化ツールです。
WasmMVPがC、C++、Rust、Swift等のメモリ管理を静的に指示する言語(非GC言語)を想定したWASMコード生成ツールです。
WasmGCがGC言語対応のWASMコード生成ツールです。
General optsは言語横断の一般的最適化ツールですが、注目すべきはその位置です。
非GC言語の実装の多くはLLVMを活用しており、WASM等のターゲットコードの生成前にLLVMのツールチェーンにより一般的最適化が行われます。
言語ごとに一般的最適化を実装しなくて良いところがLLVMのメリットでもあります。
対して、WasmGCワークフローではWASMコード生成後に一般的最適化が行われています。
WasmGCにおけるヒープオブジェクト(GCオブジェクト)はGCの都合上、原始的な型安全が確保されています。
この特徴を利用して、自動変数が指すGCオブジェクトのアロケーション、デアロケーションを省略する等の一般的最適化がWASMコードにおいて可能になるとのことです。
他にも関数ポインタとその呼び出し、コレクション要素の型他に関して最適化の余地があるそうですが、その詳細は同ブログからはわかりませんでした。
下図も同ブログからの引用です。
LLVMも一応GC言語をサポートしていますが、これまでGC言語の多くはLLVMを活用せず、AOT最適化の全てを言語固有の最適化ツールが行っていました。
WasmGCワークフローでは、一般的最適化をBinaryenに期待しており、Googleはそこに投資していくそうです。
VM最適化(JIT最適化)
一般的なGC言語では、スーパークラス型の変数を介したメソッド呼び出しにおいて、たとえそれがvirtual
と宣言されていなくとも、サブクラスでオーバーライドしたものがあればそれを呼び出します(ポリモーフィズム)。
そして、そのインライン化(ポリモーフィックインラインキャッシュ)は実行時(JIT)に行います。
また、ポリモーフィズムには実行時型(runtime type)が不可欠と言う点でGCと類似します。
V8におけるWASMのポリモーフィックインラインキャッシュは、WasmGC対応の一環で実装されたそうです。
ちなみに、非GC言語における関数のインライン化(インライン展開)はAOTに行います。
非GC言語におけるWasmGC
非GC言語においても、malloc等をGCオブジェクトにできる場合は、上記AOT最適化が可能となります。
その場合、メモリ管理が抽象化されるため、メモリのコンパクション(デフラグメント)も可能となります。
そう考えると、非GC言語の中では、メモリ安全なCarbonがもっともWasmGC恩恵を被る言語のひとつかもしれません。
flutter WebとFlutter(ネイティブ)におけるWasmGC
FlutterのAdvent Calendarでしたので、Dartに話を戻します。
ブラウザで「ネイティブ」に実行するというDartの10年来の悲願がWasmGCによってまもなく達成されようとしています。
そして、当然ながらFlutter WebもWASM対応になり、それが標準になることでしょう、SafariもWasmGCをサポートすればですが。
ところで、Webを除くFlutterのターゲットプラットフォームではDartはネイティブにAOTコンパイルされます。
AndroidにおいてもFlutterアプリはARTを用いないネイティブアプリとなります。
ここで、Wasmerを使えばWASM経由でもネイティブにAOTコンパルが可能となるはずです。
そうすれば、言語固有最適化としていたものの多くを一般的最適化としてBinaryenに集約することも可能かもしれません。
しかしこれは、JITコンパイルを避けるためにポリモーフィックインラインキャッシュをとりあえず諦めたということでもあります。
他方で、WasmGC対応のVMならJITコンパイルを避けつつ、ポリモーフィックインラインキャッシュは行えるはずです。
つまり、AndroidやiOSがWASIを標準的に実装するとすれば、WASMコンパイル済みFlutterアプリをデプロイするという将来もあるかもしれません。
その前に、WASM VMを同梱したWASMコンパイル済みFlutterアプリをデプロイするという将来も。