Design: 優先度:WASMにGCを実装するためのJavaScript統合GCまたはプリミティブ

作成日 2016年07月26日  ·  25コメント  ·  ソース: WebAssembly/design

現在のWebAssemblyに関する私の主な関心事は、現在の仕様ではなく、設計がGC参照型の追加を想定していることです。 これは、WebAssemblyと既存のJavaScriptエンジンの不要な結合だと思います。

GC参照を追加する動機は理解できます。また、既存のJavaScriptエンジン内にランタイムを実装しているほとんどの人にとって、コストはそれほど悪くはないように思われます。 しかし、GC参照型が事実上の要件である場合、ブラウザーの外部でのWebAssemblyの使用が制限されることがわかると思います。

オプションの拡張機能として追加されたとしても、Emscriptenがそれを使用すれば、それなしのWebAssembly実装は無意味になります。 CランタイムがJavaScriptハーネスに結合されているため、WAVMでEmscriptenコンパイル済みバイナリを実行する際にすでに問題が発生しています。 そのインターフェイスがGC参照を使用し始めたら、スタンドアロンのWebAssemblyVMにガベージコレクターを追加する必要があります。

ガベージコレクターをWebAssemblyVMに追加したくないのは、ガベージコレクターを作成したくないからではなく、WebAssembly内にガベージコレクターを作成したいからです。 私はWebAssemblyにコンパイルするプログラミング言語を開発しています。多くの理由から、WebAssemblyの抽象化の制限内であっても、言語固有のガベージコレクターは言語に依存しないTypedObjectコレクターよりも効果的だと思います。

GC.mdは、JavaScriptオブジェクトモデルをWebAssemblyプログラムに公開することに関するものであり、ガベージコレクターの効率的な実装を可能にするプリミティブをWebAssemblyに公開することについては言及されていません。 これは、Emscripten(または他のツールチェーン)がGC参照を必要な機能にするリスクと同じくらい心配しています。 WebAssembly内にGCを実装したいという願望を人々が認識しており、反対していないことは知っていますが、それは明らかにリソースが集中している場所ではありません。

私の意見では、焦点は見当違いです。 Webは、既存のアプリケーションを高速化することからではなく、WebAssemblyのパフォーマンスによって実現される新しいアプリケーションから最も恩恵を受けます。 WebAssemblyを使用する新しいアプリケーションは、線形メモリ内の独自のDOMを操作し、それをブラウザーのDOMに複製するための分離されたコードを使用することを期待しています。

VMレベルのGCの最も強力な議論は、データがTypedObjectsに適切にマッピングされる言語の場合、VMレベルのGCはハードウェアとOSに直接アクセスすることでメリットが得られるということだと思います。 おそらくこれは価値のある最適化ですが、WebAssemblyアプリケーションが独自のGCを実行できるようにすることが主要な目標であると思います。

managed objects

最も参考になるコメント

確かに、GC機能とツールチェーンをオプションとして設計し、プレーンなC / C ++ / Rustプログラムがそれを必要としないように設計することは理にかなっています。 考えられる反例は、GC参照を使用するとWeb APIとのより効率的な統合が可能になる場合ですが、それはおそらくWebAPIが使用された場合のみです。

そうは言っても、GCされた言語をコンパイルすることを望む場合、線形メモリですべてを実行するよりも、ホスト環境のGCと統合することにはいくつかの利点があります。

  • wasmオブジェクトとホスト環境(DOMなど)オブジェクトの間を行き来するサイクルは、ホスト環境GCによって収集できますが、リニアメモリ内のGCによっては収集できません。 あなたは他の方法で収集可能なサイクルを根付かせた強いエッジで終わるでしょう
  • ホスト環境のGCは、requestAnimationFrameやvsyncなどと統合されているため、たとえば、次のフレームを開始するときに終了するように増分GCスライスを調整できます。
  • 互いに素なwasm線形メモリ間でGCアリーナを安全に再利用できるようにすることで、内部の断片化を減らします。 特に仮想アドレス空間が限られている32ビットで重要
  • devtoolsがホストGCオブジェクトをよりよく理解するため、ブラウザーdevtoolの統合が向上します
  • ブラウザにすでにあるものを再利用することにより、より小さな配布可能なランタイム

そして、これらはGCをwasmに統合する作業を正当化すると思います。

全てのコメント25件

確かに、GC機能とツールチェーンをオプションとして設計し、プレーンなC / C ++ / Rustプログラムがそれを必要としないように設計することは理にかなっています。 考えられる反例は、GC参照を使用するとWeb APIとのより効率的な統合が可能になる場合ですが、それはおそらくWebAPIが使用された場合のみです。

そうは言っても、GCされた言語をコンパイルすることを望む場合、線形メモリですべてを実行するよりも、ホスト環境のGCと統合することにはいくつかの利点があります。

  • wasmオブジェクトとホスト環境(DOMなど)オブジェクトの間を行き来するサイクルは、ホスト環境GCによって収集できますが、リニアメモリ内のGCによっては収集できません。 あなたは他の方法で収集可能なサイクルを根付かせた強いエッジで終わるでしょう
  • ホスト環境のGCは、requestAnimationFrameやvsyncなどと統合されているため、たとえば、次のフレームを開始するときに終了するように増分GCスライスを調整できます。
  • 互いに素なwasm線形メモリ間でGCアリーナを安全に再利用できるようにすることで、内部の断片化を減らします。 特に仮想アドレス空間が限られている32ビットで重要
  • devtoolsがホストGCオブジェクトをよりよく理解するため、ブラウザーdevtoolの統合が向上します
  • ブラウザにすでにあるものを再利用することにより、より小さな配布可能なランタイム

そして、これらはGCをwasmに統合する作業を正当化すると思います。

たとえば、lispの実装では短所を2語で格納できますが、Webブラウザのオブジェクトモデルを使用しても、メモリ効率がほぼ同じになる可能性はほとんどありません。 また、オブジェクトモデルとガベージコレクターで行うことができるさまざまなトレードオフがあり、特定のホスト実装の制約がないことをサポートします。 たとえば、記号数学アプリケーションなどの一部のアプリケーションでは、定期的な一時停止が目立たない場合は、パフォーマンス効率の高いガベージコレクターを使用できます。 また、ガベージコレクターがwasmプロセス内に実装されている場合は、ランタイムガベージコレクターとは独立して実行でき、ランタイムをブロックしません。

はい、これらは人々が線形メモリを使用して独自のGCを実装したいと思う理由であり、GCサポートをwasmに追加してもそうすることを妨げてはなりません。

はい、今はwasmにガベージコレクターを実装することも可能ですが、ローカルおよび中間体でGC参照をスキャンする方法があればはるかに実用的です。 これは、ホスト定義のGCに必要な機能のサブセットである非常に便利な機能ですが、AFAICTは設計リポジトリのどこにも言及されていません。

ホスト定義のGCに関する私の懸念は、より一般的なGCビルディングブロックを技術的に妨げることではなく、次のことです。

  • 人気のあるツールチェーンで採用することで、簡単に必須のVM機能になる可能性があります
  • そして、それは「十分」と見なされる可能性があるため、wasm内で効率的なGC実装をサポートするための取り組みはブロックされます

devtoolsがホストGCオブジェクトをよりよく理解するため、ブラウザーdevtoolの統合が向上します

二次的な利点として、スタック上のローカルと中間体をスキャンする機能は、ブラウザーに依存しない、言語固有のデバッグツールに向けた大きな一歩となるでしょう。

ある程度のオプトイン/従量課金制のスタック検査は、一般的にwasmにとって有用な機能であり、まもなくそのようなものを追加する必要があることに同意します。

ツールチェーンについては良い点があると思いますが、これは、非固有のGCソースのGCへの強い依存を回避するという高レベルの目標として受け入れることができると思います。 通常のGCヒープが割り当てられない、GCのみのwasmワーカーを作成できるはずなので、これはWeb上でも良い考えだと思います。

ローカル変数と値スタックが動的スコープのどこからでもアクセスできる場合、SSA形式へのデコードに暗黙的に含まれるいくつかの仮定が無効になる可能性がありますか? おそらく、ここでのオプションについてもう少し考える必要があり、おそらくそれは言語設計にも影響を与えます。

1つのオプションは、wasmコードプロデューサーが、値スタックまたはローカル変数で、ガベージコレクションをトリガーする可能性のあるポイントで、線形メモリではなく、スカベンジする必要のあるポインターを単純に保持しないことです。 したがって、ローカル変数と値のスタックは、引き続き字句スコープに十分に制約される可能性があります。

ローカル変数と値のスタックが読み取りのみで、字句スコープ外に書き込むことができない場合に役立ちますか? 最初は、SSAデコーダーへの影響を回避するのに十分な制限があると思いましたか? これは、ローカル変数と値スタック内の値の保守的なスカベンジャーをサポートしますが、ローカル変数または値スタックからのポインターを使用してオブジェクトを移動する正確なガベージコレクターはサポートしません。

値のスタックを回避したがローカル変数を使用した無表現エンコーディングは、別の極端なものになり、ローカル変数さえ使用しなかったため、すべての演算子が線形メモリの読み取りと書き込みを行ったとしましょう。 動的スコープからローカル変数とスタックへのアクセスを許可するのと同様の問題がデコーダーにありますが、線形メモリへの変更が関数の終わりを超えて持続し、書き戻す必要があるため、おそらくさらに悪い問題があります。

それで、最初に考えられた唯一の実用的なオプションは、ローカル変数から、そして値スタックからスカベンジする必要があるポインタを保持することであるように思われますか?

動的コンテキストからのローカル変数と値スタックの読み取りのみを許可し、これらへの書き込みを許可しないことの影響についての意見に興味があり、SSAデコーダーに影響を与えますか?

動的コンテキスト内からローカル変数と値スタックの読み取りを許可しても問題ないとしましょう。 get_valueプロポーザル(スタックの静的参照)も問題ないようです。 その場合、モデルは、値スタックに動的スコープの読み取り専用値があり、ローカル変数には動的スコープで読み取ることができるが字句スコープでのみ書き込むことができる値があるというものになります。

これらの問題のいずれかが、議論されているwasm-GCバリアントに影響を与えますか? ローカル変数または値スタックのGCポインターを任意の動的コンテキストから書き込むことができる場合、これらの問題のいくつかもあり、イライラするSSAデコードが発生する可能性がありますか?

申し訳ありませんが、これをもう少し考えてみると、ローカル変数または値スタックへのアクセスをレキシカルスコープ外に許可することはまったく実用的ではないようです。パフォーマンスに関しては実用的ではありません。

これにより、プロデューサーはガベージコレクションを実装して、ガベージコレクションをトリガーし、そこでそれらを清掃できるポイントで線形メモリへのポインターを書き戻すようになります。

ローカル変数と値スタックが動的スコープのどこからでもアクセスできる場合、SSA形式へのデコードに暗黙的に含まれるいくつかの仮定が無効になる可能性がありますか? おそらく、ここでのオプションについてもう少し考える必要があり、おそらくそれは言語設計にも影響を与えます。

ローカル変数と中間値の存続期間には、実装の非決定論があることに気付いていると思います。 そうですか?

LLVM GCステートポイント組み込み関数のようなものを追加する必要があると思います。呼び出しによって変更される可能性のある値スタックの場所とローカル変数のセットを追加で取得する呼び出しです。 これにより、すべてを呼び出しでシリアル化する必要があると悲観的に想定することなく、呼び出しでローカル状態の変更をシリアル化できます。

このGC対応の呼び出しによって明示的にシリアル化されたローカル状態を超えて、スタック検査で他のライブローカルおよび中間値の形式で非決定性を観察できるようにすると便利な場合があります。

ローカル変数と値のスタックが読み取りのみで、字句スコープ外に書き込むことができない場合に役立ちますか? 最初は、SSAデコーダーへの影響を回避するのに十分な制限があると思いましたか? これは、ローカル変数と値スタック内の値の保守的なスカベンジャーをサポートしますが、ローカル変数または値スタックからのポインターを使用してオブジェクトを移動する正確なガベージコレクターはサポートしません。

IMOの目標は、正確でコンパクトなGCである必要があります。

呼び出し時に変更できる値スタックとローカル変数の場所の定義を許可することによって何が得られるかはすぐにはわかりません。 実際には、これらをメモリに書き戻して再ロードする必要があります。これは、すでにサポートされているリニアメモリに保存するだけで、プロデューサーが明示的に行うことができます。 必要がないのになぜ複雑さを加えるのか。

申し訳ありませんが、これをもう少し考えてみると、ローカル変数または値スタックへのアクセスをレキシカルスコープ外に許可することはまったく実用的ではないようです。パフォーマンスに関しては実用的ではありません。

ゼロコストの例外処理のためにコールスタックを巻き戻すために使用されるのと同じ情報で、各呼び出しの時点でレジスタの状態を再構築できます。 同じ情報を使用して、呼び出しの時点でレジスタにあったGC参照を検索して変更できます。これらは、呼び出し先によってスタックに保存されているか、GCがトリガーされたときにまだレジスタにあります。

ありがとう、メタ情報を使用してライブの場所と場所を記録することでうまくいくかもしれないと思いますが、ランタイムにとっては非常に複雑に聞こえます。 状態が字句スコープの外で変更される可能性がある場合は、SSAデコーダーにまだ問題がある可能性があります。

ありがとう、メタ情報を使用してライブの場所と場所を記録することでうまくいくかもしれないと思いますが、ランタイムにとっては非常に複雑に聞こえます。

実装するのは間違いなくトリッキーです。 ただし、ゼロコストの例外処理はすでにMVP後のロードマップにあり、単純さを優先するランタイムは、呼び出し間でシャドウスタックへのGC参照を常に流出させる可能性があります。

状態が字句スコープの外で変更される可能性がある場合は、SSAデコーダーにまだ問題がある可能性があります。

この突然変異の可能性をSSAで次のようにエンコードできます。

%gcRef0 = ... ; The initial value of gcRef.
%gcStatepoint = call ... gcstate=[%gcRef0...]
%gcRef1 = gcmutate %gcStatepoint 0 ; The new, possibly mutated value of gcRef after the GC statepoint
%result = gcresult %gcStatepoint   ; The result of the function called by the GC statepoint

@ lars-t-hansen VMはメモリをサンドボックス化するだけでよいため、VM自体のオブジェクトシステム(および可能なポインタタグ付け)を実装する言語は、常にタイプセーフである必要はなく、ポインタのIDを保護する必要もありません。 不透明なGCポインターはサンドボックスを保護するために常に安全である必要があり、VMで実行されているコードにポインター値を公開したくないと述べています。 また、メモリ管理は多くの場合、このサンドボックスを低コストで実装できます。ハードウェアは、将来、メモリ管理サンドボックスをより適切にサポートする機能を追加する可能性もあります。 したがって、サンドボックス内に独自のオブジェクトヒープを実装するコードは、パフォーマンスを向上させ、VMにほとんど負担をかけません。

たとえば、各要素がタグ付きの小さな整数(タグ付き整数など)であるリスト(consセルのリンクリスト)と、すべてのリスト要素を追加するコードについて考えてみます。 プロデューサーは、これらが小さな整数であり、合計が小さな整数をオーバーフローしないという宣言を利用して、x86上の単一の命令でこれらを単純にロードして追加する場合があります。 gcヒープに割り当てられたオブジェクトを対象とする言語がこのレベルのパフォーマンスにどのように近づくことができるかわかりません。

たとえば、ポインタタグを使用すると、consセルへのポインタにタグ付きタイプを設定して、consセルが2ワードのメモリのみを消費できるようにすることができます。 gcヒープに割り当てられたオブジェクトシステムがこのレベルのメモリ効率にどのように近づくことができるかわかりません。

lispで書かれたmaximaのような象徴的な数学ソフトウェアがウェブ上で効率的に実行されることを望んでいます。それはフェアユースのケースのようです。

錆がwasmをターゲットにしている場合は、VMコンシューマーに頼って、タグ付きポインターなどをターゲットとするオブジェクトシステムを提供するのではなく、少なくともオブジェクトシステムをwasmに実装しようとする負担がプロデューサーにあるはずです。

絶え間なく変化する環境の中で適応性を強化するには、生のハードウェア機能のみを公開し、人々にGCを強制しないことが重要です。

チームにとって、Wasmの上にオープンソースGCを構築するという1つの特定の目的しかない独立したグループをスピンオフするのが最善だと思います。

..これにより、[ブラウザメーカーを含む]誰もが必要なときにGC機能を簡単に利用できるようになります。 同時に、 GCを回避する必要のある重いリアルタイムプログラムは、まさにそれ

私はアランケイからの

C ++が登場したとき、彼らはCプログラマーに対応しようとし、魚でも家禽でもないシステムを作りました。

ウェブを適切な人にしてください。 今回はそれを正しく行うか、私たちは再びアマチュアと呼ばれるでしょう。

@ Pacerier

安全上の制限によって最も影響を受けるのは一種のコードであるため、Wasmの_上に_競争力のあるパフォーマンスを備えたGCを実装することは非常に困難です。 また、正しく効率的にすることは信じられないほどの量の作業です。 同時に、これは事実上すべての高級言語が必要とするメカニズムであるため、ブラウザーですでに行われているハードワークを全員がやり直す必要がある場合、Webプラットフォームへのサービスは不十分です。

公平を期すために、プラットフォームにGCを使用すると、Web以外のwasmの実装は、他の方法では必要なかった可能性のあるGCの実装を余儀なくされる可能性があります。 すべてのブラウザベースのwasm実装は、確実にGCをJSと共有しますが、Web以外の実装には、ご存知のように、信じられないほどの量の追加作業が追加されます。

けっこうだ。 おそらく、GCを使用した将来のWasmの仕様では、実装が制限することを選択できるGCフリーのサブ言語を特定できる可能性があります。

一部の非Webプラットフォームでは、より簡単になります。 たとえば、.NETまたはJavaベースのWASM実装でも、ガベージコレクションをすぐに利用できます。

私はGCフリーのサブ言語の概念に同意します。これは、WASMライブラリがターゲットにできる「機能レベル」を提供し、Webブラウザなどの高度なプラットフォームに有用な機能を提供しながら幅広いプラットフォームをサポートします。 このアプローチは、他のさまざまな提案にも適用できます。

私は実装定義のGC拡張機能に反対していません。 「競争力のあるパフォーマンス」ではありませんが、おそらくWAVMでもサポートします。 私は、ルークが「非固有のGCソースのGCへの強い依存を回避する」という上記の高レベルの目標に満足しています。

私が心配しているのは、WASMプログラムが線形メモリを効率的にガベージコレクションできるようにする標準の拡張機能がないことと、ブラウザベンダーが何らかの理由で標準化を許可したとしても、そのような拡張機能をサポートしない可能性があることです。

言語がWASMの上に独自のガベージコレクターを実装すべきかどうかについて議論することは生産的ではないと思います。 WASMの第一の目標は、「幅広いプラットフォームで利用可能な共通のハードウェア機能を利用して、ネイティブ速度で実行するようにコンパイルできるコンパイルターゲット」を作成することです。したがって、WASMが試してみるべきことは当然だと思います。さまざまなプラットフォームのネイティブコードで利用できる一般的なハードウェア機能を公開します。スタックを検査して変更し、状態を登録します。

原則として誰もがそれに異議を唱えることはないと思いますが、誰もが物事に取り組むための限られた帯域幅を持っています。 これがどのように機能するかについてより具体的な提案をしたいと思いますが、努力する前に、ブラウザベンダーによって標準化および実装される可能性があることを知りたいと思います。優先度が低すぎるとしてパントされました。

@sunfishcode私はいつも、WASMが管理するデータがWASMのSIMDのようになるというモデルを頭の中に持っていました。これは、新しい値、タイプ、およびオペコードを定義するかなり十分に含まれた拡張機能です。 テストスイートと仕様書を適切にモジュール化すれば、「コアWASM」とは何か、標準化された拡張機能とは何かを明確に描写できるはずです。

上記で成功した場合、WASMの一部の実装では、WASMのマネージドデータ拡張を実装しないことを選択するだけで十分です。

WASMの上にあるGCに関しては、これは実行エンジンの上のレイヤーであるため、明示的なサポートなしにWASMの上に構築できない理由はわかりません。 実際、まさにそれを行うプロジェクトはすでに進行中です。 標準化されたGC-on-top-of-WASMをコアWASMプロジェクトの目標とは見なしていませんが、ツールの規則と同じカテゴリで表示しています。

wasmエンジンがGC機能を実装しないことを選択し、GCを必要としない言語のセットに対して完全に機能するように、GCをオプションのコンポーネントとして維持することに同意しました。 これは、 GCPRの高レベルのアプローチの

WASMの上にあるGCに関しては、これは実行エンジンの上のレイヤーであるため、明示的なサポートなしにWASMの上に構築できない理由はわかりません。 実際、まさにそれを行うプロジェクトはすでに進行中です。 標準化されたGC-on-top-of-WASMをコアWASMプロジェクトの目標とは見なしていませんが、ツールの規則と同じカテゴリで表示しています。

WASMにリニアメモリガベージコレクタを実装することは可能ですが、あまり効率的ではありません。 WASMには、コールスタックまたはレジスタ内の参照を検索/変更する方法がないため、呼び出し間で線形メモリへのすべての参照をスピルする必要があります。

私が望んでいるのは、線形メモリガベージコレクタを標準化することではなく、スタック上のアドレスを検索、読み取り、書き込みするための安全でポータブルな方法を提供する低レベルの拡張機能を標準化することです。 いくつかの追加のオペランドを取り、呼び出し中に発生する可能性のある「スタックマップ」操作を介してそれらを再マップする拡張呼び出し演算子が必要になります。 また、現在のスレッドのスタック上の拡張呼び出し演算子によって「マップ」された参照を読み書きするための演算子も必要になります。 それだけでは、ネイティブGC実装の​​パフォーマンスに匹敵するほどではありませんが、ギャップをかなり埋めることができます。

@AndrewScheideckerええ、そのようなものを追加するのは合理的な機能であり、一般的にも役立つと思います。 最近、Windows SEHフィルターとiircを実装する方法について話していましたが、これも必要でした。

@ rossberg-クロム、再:

WasmでのGCの可用性は、それを使用しないコードには影響しません。

..それはオプションであり、削除する必要があることを意味します。 緩い結合。 ハードウェアでできることとできないことは、非常に明確に示されています。 したがって、相互作用する懸念がないため、階層化されたアプローチが優れています。

@ rossberg-クロム、再:

したがって、誰も何も強制されません。

..あなたはまだ要点を逃しています。 ポイントは次のとおりです。緩い結合。 相互作用の懸念がないため、階層化されたアプローチが優れています。

@ rossberg-クロム、再:

Wasmの上に競争力のあるパフォーマンスを備えたGCを実装することは非常に困難です。これは、安全性の制限によって最も影響を受ける種類のコードだからです。 また、正しく効率的にすることは信じられないほどの量の作業です。 同時に、これは事実上すべての高級言語が必要とするメカニズムであるため、ブラウザーですでに行われているハードワークを全員がやり直す必要がある場合、Webプラットフォームへのサービスは不十分です。

..それは「オープンソースの方法」で行われます。jqueryが1つのライブラリでありながら、何百万ものチームによって使用されているように。 大企業がそのオープンソースプロジェクトの完成に取り組んでいる専任チームを持っているのに、小さなコードショップが自分でjqueryを書く必要がある理由はありません。

@ rossberg-クロム、再:

同時に、それは事実上すべての高級言語が必要とするメカニズムです。

..とんでもない。 Cはどうですか?

..確かに、ゲーム開発者や他の時間に敏感なアプリの開発者は、たまたまCを使用する贅沢を持っていないので、対処せざるを得なかったGCを常に嫌うことになります。

@ AndrewScheidecker 、re:

私が心配しているのは、WASMプログラムが線形メモリを効率的にガベージコレクションできるようにするための標準的な拡張機能がないことです。

..すべてのハードウェア機能がプログラマーに公開されている限り、すべてを実行できるため、それは不可能です。 実際、そうでない場合は、単に、公開されたレイヤーが高レベルであり、ハードウェアに近い小さなサブセットがターゲットに適したレイヤーであることを意味します。

この標準は、少なくとも20年または30年の間、Web内に定着することを期待していると思いますか? 次に、生のハードウェアレイヤーをターゲットにして、それに固執します。 ハードウェア層の上にある他のすべては、「他のチーム」によって処理される必要があります。 1つのチーム1つの懸念。

結局のところ、それは簡単な質問に要約されます。今世紀にガベージコレクションの命令があるハードウェアはありますか? 響き渡る「ノープ」。 1つが作成されたとき、そしてそのとき

オプションの拡張機能として追加されたとしても、Emscriptenがそれを使用すれば、それなしのWebAssembly実装は無意味になります。 CランタイムがJavaScriptハーネスに結合されているため、WAVMでEmscriptenコンパイル済みバイナリを実行する際にすでに問題が発生しています。 そのインターフェイスがGC参照を使用し始めたら、スタンドアロンのWebAssemblyVMにガベージコレクターを追加する必要があります。

^このx1000

これはまさに、 Embrace、Extend、およびExtinguishの仕組みです。 GCの提案がMicrosoftに倣って意図的にパターン化されていると言っているのではなく、無意識のうちにそのパターンに従うことから生じる不可避の影響を指摘しているだけです。

  1. 現在、すべてのWASMを_どこでも_ホストできます
  2. WASMプログラム用のGCオプションを追加します(「しかし、それは拡張機能のみです!」)
  3. GCのないランタイムは、GCを実装するか、すべてのWASMをホストできないかの選択に直面します。
  4. 最終結果:WASMはどこでもホストできなくなりました

WASMが場所で実行可能でなくなることを本当に望んでいますか?

私は実用的な側面を理解しています。WASMの現在の最大の市場はウェブです。 つまり、_Web_Assemblyと呼ばれています。

しかし、それはインターネットブラウザに限定されたものではないことを誰もが覚えておいてください。 今のところ、セキュリティを損なうことなく、信頼できない任意のWASMバイナリをRustプログラムに埋め込むことができます。 そして、誰でもLLVMでそのWASMを作成できます。 それはすごいね。 それをもっと難しくしたくありません。 そして、20年後にウェブがどのようになるか誰が知っていますか。 そして、Dockerの共同創設者がWASM + WASIについて言ったことを忘れないでください:

標準化されたシステムインターフェイスは欠落していたリンクでした

彼は「言語の拡張はミッシングリンクだった」とは言いませんでした。

WASMプログラムに高品質のGCを持たせたい場合は、GCをカプセル化して、WASMプログラムにそれらを実行させましょう( @PacerierのjQueryの例のように)。

また、ホストGCとの緊密な統合が必要な場合は、通常のインターフェイスを作成します。


そうは言っても、GCされた言語をコンパイルすることを望む場合、線形メモリですべてを実行するよりも、ホスト環境のGCと統合することにはいくつかの利点があります。

  • wasmオブジェクトとホスト環境(DOMなど)オブジェクトの間を行き来するサイクルは、ホスト環境GCによって収集できますが、リニアメモリ内のGCによっては収集できません。 あなたは他の方法で収集可能なサイクルを根付かせた強いエッジで終わるでしょう

これはそのようなサイクルの具体例になると思います。ホストとWASMプログラムが連携して、循環リンクリストを作成します。 一方のノードはホストに存在し、もう一方のノードはWASMプログラムに存在し、各ノードはもう一方のノードを指し示します。 どちらの側も、相手の参照を破壊せずにノードをGCすることはできません。

しかし、私にとって、これは参照の実装に問題があることを示しています。

GCされた言語での参照は、参照がどこに移動しても、GCによって追跡可能であると想定されています。 C#GCはCランドに到達できず、いじくり回すことができないため、C#オブジェクトにC関数への参照を与えることはできません。 その参照からメモリアドレスを抽出してその番号を渡すことができますが、最初にC#のGCにそのオブジェクトを固定するように指示しない限り、メモリアドレスが後で意味を持つことを保証するものではありません。 これを行うと、C関数は一貫した方法でその数を使用して意味のあることを実行できます。 双方が幸せです。

C#にGCがあるという事実は、それが呼び出す他のすべてのプログラムにもGCが必要であることを意味しますか? いいえ。代わりに、ピン留め/ルート化のための明示的なコントロールがC#にあり、一貫した方法でプログラムをオーケストレーションできます。

Rustでの参照には、Rustの外部で維持できないことが多いという保証があります。 メモリアドレスを抽出し、その番号を壁に投げ込むと、所有権、存続期間、および可変性がすべて破壊される可能性があります。

Rustが所有権システムを持っているという事実は、すべての外国の機能が所有権システムを持っている必要があることを意味しますか? いいえ。代わりに、APIデザイナーはフレームワークを構築する際に非常に注意を払い、外部関数のRustラッパーは多くのことを考慮します。

参照をホストのGCで追跡する必要がある場合は、代わりにWASMの既存の構成を使用してその概念をカプセル化してみませんか?

ホストが参照カウントポインタをWASMプログラムと共有したい場合は、共有メモリに参照カウントポインタを作成し、双方がそれを1つとして扱うようにします。

ホストがWASMプログラムの足元でメモリをシャッフルしたい場合は、その意図と概念を伝達するインターフェイスを(通常の方法で)作成します。

また、C#バックエンドの参照グラフをFlutter UIフロントエンドの参照グラフとより協調的にする方法を考えることは、通常、実り多い演習ではないことは興味深いことです。 人々が許容する(必要でさえある)プロセス境界があり、その境界を越えるためのフレームワークとパターンがあります。

  • ホスト環境のGCは、requestAnimationFrameやvsyncなどと統合されているため、たとえば、次のフレームを開始するときに終了するように増分GCスライスを調整できます。

これは、WASMでホストされているGCの場合、関数呼び出しや共有状態などの通常の方法で解決できると思います。

言うまでもなく、これは、ホストGCがWASMプログラマーが望んでいることを正確に実行するという(大きな)仮定を立てています。

  • 互いに素なwasm線形メモリ間でGCアリーナを安全に再利用できるようにすることで、内部の断片化を減らします。 特に仮想アドレス空間が限られている32ビットで重要

これは、他のアセンブリ言語の範囲外であるのと同様に、範囲外だと思います。 ホストにプログラムのメモリ使用パターンを認識させたい場合は、そのようなことをホストに通信するWASMで構成されるレイヤーが必要です。 メモリ使用量マップなどを生成するエクスポートされた関数を使用してWASMプログラムを構築します。

  • devtoolsがホストGCオブジェクトをよりよく理解するため、ブラウザーdevtoolの統合が向上します

これはあまり強力な議論ではないと思います。 ツーリングは必然的に言語に遅れをとっており、またツーリングは静的ではありません。 ですから、私は今のツールに合うように言語デザインを変更するのが好きではありません。 Devtoolsは何でも理解するようにさせることができます。

  • ブラウザにすでにあるものを再利用することにより、より小さな配布可能なランタイム

ブラウザのファイルキャッシュとモジュールのリンクでこの問題は解決すると思います。 繰り返しますが、jQueryについて考えてみてください。

このページは役に立ちましたか?
0 / 5 - 0 評価