shared objects: user space initialization safety
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- wasm
- 領域
- compilers
調査の方向性
ファイル、テスト、実装のエントリーポイントは指定されていません。まず Background セクションと Problem セクションから始め、release-fence と publish-instruction の提案を比較してください。完了の条件は、初期化の安全性メカニズムと、公開セマンティクスに関する一覧の3つの質問が提案内で解決されていることです。
索引モデルが issue の本文から書いたものです。
説明
Background
An important part of the memory model for shared GC objects will be that a thread can never observe uninitialized fields of an object allocated on another thread. For example, if I allocate a struct with (struct.new $s (i32.const 1)), no thread can ever read a 0 (or any other value) from that allocated struct unless the field is mutable and some other code writes that value into it.
In practice, this means implementations will have to do a release barrier at the end of shared object allocation. (A C++ release barrier technically does not have strong enough semantics, but it lowers to instructions that do have strong enough semantics on all architectures.)
Problem
Compilers for languages like Java will need to be able to provide similar initialization safety guarantees at the source language level. Java, for instance, guarantees that uninitialized final fields are never observed as long as the object being constructed is not leaked to other threads by its constructor.
Compilers could preserve this kind of initialization safety by constructing the WebAssembly object only at the end of the constructor and depending on WebAssembly's guarantees. Except that constructors (and the functions they call, including superclass constructors) generally need a real this object. So compilers could have a temporary this object used while calling constructors, then copy its fields to the "real" object at the end of the constructor. Except that this would be expensive and the temporary and real objects would be observably different, which would violate source language semantics.
So we need some other mechanism compilers can use to provide their own initialization safety.
Solutions
Release Fence
One option is to reuse the initialization safety formalism we will have in the memory model and reuse it in the semantics of WebAssembly release (and stronger) fences. Then producers can insert a release fence at the end of their constructors, just like WebAssembly engines will have to insert a release fence at the end of shared object allocation.
A downside of this approach is that there is nothing semantically tying the release fence to the particular object being published, so optimizers like Binaryen would not be able to remove the fence even in cases where they are able to optimize the constructor down to a single struct.new instruction. That means there would end up being two release fences at runtime; the engine's release fence at the end of struct.new followed by the user space release fence from the end of the optimized constructors. Beyond the extra runtime cost, the user space release fence would also unnecessarily prevent other possible instruction reorderings the optimizer might have wanted to do.
publish Instruction
A better approach would be to add a new instruction that provides the initialization safety publishing semantics for just a single object: publish.
instr := ... | publish
C |- publish : rt -> rt
publish pops an arbitrary reference value and ensures that any writes to the referenced value that happen-before the publish are visible to reads on any thread that are (happens-before or data-dependency or address-dependency)*-after the the publish. (At least approximately; we'll leave the precise formalism to @conrad-watt 😉) It pushes the same value back onto the stack, avoiding the need to use locals just to publish the value before doing something else with it.
Engines implement the publish with the same release fence they will use at the end of object allocation. Binaryen will be able to optimize out publish when there are no writes to the published object between its allocation and the publish because publish does not provide any guarantees already provided by the allocation in that case.
Open Questions
- What type does
publishaccept?- Right now the only mutable heap types are
structandarray, so the most precise type we could accept would be(ref (shared eq)). But we would definitely want to accept a nullable reference for consistency with every other instruction that takes references, and it's harmless and future-proof to have it take arbitrary references.
- Right now the only mutable heap types are
- What does
publishdo when passed a null value?- Most instructions that take references trap on a null value, but there are exceptions such as extern conversions and nullable casts. It seems harmless to allow
publishof nulls to do nothing without trapping.
- Most instructions that take references trap on a null value, but there are exceptions such as extern conversions and nullable casts. It seems harmless to allow
- Should
publishreturn its input?- This is unusual, but it is good for code size because otherwise the input would necessarily have to be
local.teed to be used for anything else. The alternative would be to have it return nothing. - There is a question of how this should work for polymorphic stacks. When validation of
publishpopsbot, it should just pushbotas well. There is precedence for this for e.g.select.
- This is unusual, but it is good for code size because otherwise the input would necessarily have to be
Edit log
- Updated
publishto push its operand back to the stack.
- 主要言語
- WebAssembly
- スター
- 98
- フォーク
- 7
- 平均マージ
- 1日 20時間
- マージ済み PR(30日)
- 1
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
WebAssembly/shared-everything-threads のほかの issue
-
難易度 5/5 1週間以上 初心者へのやさしさ 15/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
WebAssembly/shared-everything-threads#114 · コメント 7 件 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
WebAssembly/shared-everything-threads#105 · コメント 6 件 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
WebAssembly/shared-everything-threads#99 · コメント 5 件 ·
WebAssembly/shared-everything-threads の issue をすべて見る
似ている issue
-
bug derived types format I/O medium priority semantics
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
bytecodealliance/wasm-tools#2768 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
antlr/grammars-v4#5035 ·
メンテナーはふだん 5 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信