Phase 10_6b scheduler complete; 10_4 GC hooks + counting/strict tracing; 10_c minimal JIT path (i64/bool consts, binop/compare/return, hostcall opt-in); docs & examples; add Phase 10.7 roadmap (JIT branch wiring + minimal ABI).
This commit is contained in:
@ -1,173 +1,19 @@
|
||||
# Phase 10.4: GC Switchable Runtime - 世界初の柔軟なメモリ管理
|
||||
# Phase 10.4 — GC Switchable Runtime (Scaffold)
|
||||
|
||||
Status: Planned
|
||||
Owner: core-runtime
|
||||
Target: After Cranelift JIT (Phase 10.0)
|
||||
Last Updated: 2025-08-26
|
||||
Dependencies: Phase 10.0 (Cranelift JIT), Phase 9.79b (Unified Box)
|
||||
Status: scaffolded (hooks only)
|
||||
|
||||
## 🎯 概要
|
||||
Goals
|
||||
- Decouple execution engines from a concrete GC.
|
||||
- Provide minimal `GcHooks` with `safepoint()` and `barrier(kind)` used by MIR `Safepoint`/`Barrier*`.
|
||||
- Make runtime supply a pluggable GC via `NyashRuntimeBuilder::with_gc_hooks`.
|
||||
|
||||
Nyashを**世界初のGC切り替え可能プログラミング言語**にする革新的機能。開発時はGCで快適に、本番ではGCなしで最高性能を実現。
|
||||
What’s done (in this repo)
|
||||
- Added `src/runtime/gc.rs` with `GcHooks` trait, `BarrierKind`, and `NullGc` (no-op).
|
||||
- `NyashRuntime` now holds `gc: Arc<dyn GcHooks>`; defaults to `NullGc`.
|
||||
- VM dispatch calls hooks on `Safepoint` and `Barrier(Read|Write|unified)`.
|
||||
|
||||
## 📊 技術的背景
|
||||
Next
|
||||
- Thread-local root set API design (`enter_scope/leave_scope`, root pinning) for precise collectors.
|
||||
- Card marking/write barrier integration for object field writes (`RefSet` sites).
|
||||
- Preemption policy at safepoints (cooperative scheduling integration).
|
||||
|
||||
### 現状のメモリ管理
|
||||
- Everything is Box哲学(すべてのデータがBoxオブジェクト)
|
||||
- 明示的メモリ管理(スコープベースfini)
|
||||
- Arc<Mutex>によるスレッドセーフ設計
|
||||
|
||||
### 提案する2つのモード
|
||||
1. **Explicit Mode(現在のデフォルト)**
|
||||
- スコープを抜けたら即座にfini()呼び出し
|
||||
- 予測可能な性能(リアルタイムアプリ向け)
|
||||
- メモリ使用量が最小
|
||||
|
||||
2. **Reference Counting Mode(新規)**
|
||||
- 参照カウントが0になったらfini()呼び出し
|
||||
- 循環参照はweak参照で解決
|
||||
- 開発効率重視(一般アプリ向け)
|
||||
|
||||
## 🏗️ アーキテクチャ設計
|
||||
|
||||
### MIR層:所有権イベントの抽象化
|
||||
```rust
|
||||
// GCモードに依存しない所有権表現
|
||||
enum MirOwnership {
|
||||
Move(temp_id), // 所有権移動
|
||||
Copy(temp_id), // 複製
|
||||
Drop(temp_id), // 破棄
|
||||
StorageLive(id), // 生存開始
|
||||
StorageDead(id), // 生存終了
|
||||
Escape(target), // エスケープ解析
|
||||
}
|
||||
```
|
||||
|
||||
### ランタイム層:モード別実装
|
||||
```rust
|
||||
// 統一APIでモード切り替え
|
||||
trait MemoryManager {
|
||||
fn retain_ref(&self, ptr: *const BoxHeader);
|
||||
fn release_ref(&self, ptr: *const BoxHeader);
|
||||
fn destroy(&self, ptr: *const BoxHeader);
|
||||
}
|
||||
|
||||
struct ExplicitManager; // 即座に破棄
|
||||
struct RefCountManager; // 参照カウント管理
|
||||
```
|
||||
|
||||
### JIT層:関数マルチバージョン化
|
||||
```
|
||||
関数テーブル:
|
||||
┌─────────────┬──────────────┬──────────────┐
|
||||
│ Function │ Explicit Ver │ RefCount Ver │
|
||||
├─────────────┼──────────────┼──────────────┤
|
||||
│ array_push │ 0x1000_0000 │ 0x2000_0000 │
|
||||
│ map_get │ 0x1000_1000 │ 0x2000_1000 │
|
||||
└─────────────┴──────────────┴──────────────┘
|
||||
|
||||
トランポリン → 現在のモードに応じてジャンプ
|
||||
```
|
||||
|
||||
## 📋 実装計画
|
||||
|
||||
### Phase 10.4.1: 基盤構築(2週間)
|
||||
- [ ] BoxHeaderに参照カウントフィールド追加
|
||||
- [ ] MemoryManagerトレイト定義
|
||||
- [ ] インタープリターでの基本実装
|
||||
|
||||
### Phase 10.4.2: MIR対応(1ヶ月)
|
||||
- [ ] 所有権イベント(Move/Copy/Drop等)の導入
|
||||
- [ ] retain_ref/release_ref命令の追加
|
||||
- [ ] エスケープ解析の基礎実装
|
||||
|
||||
### Phase 10.4.3: 最適化(3週間)
|
||||
- [ ] 近接ペア消去(retain直後のrelease削除)
|
||||
- [ ] ループ不変式の移動
|
||||
- [ ] φノードでの差分管理
|
||||
|
||||
### Phase 10.4.4: JIT統合(1ヶ月)
|
||||
- [ ] 関数マルチバージョン生成
|
||||
- [ ] トランポリン機構実装
|
||||
- [ ] fast path/slow path分離
|
||||
|
||||
### Phase 10.4.5: 実戦投入(2週間)
|
||||
- [ ] モード切り替えCLI実装
|
||||
- [ ] メモリリーク検出ツール
|
||||
- [ ] ベンチマーク・性能評価
|
||||
|
||||
## 🎯 使用例
|
||||
|
||||
### 開発フロー
|
||||
```bash
|
||||
# 1. 開発中:GCオンで快適に開発
|
||||
nyash --gc-mode=ref-counting --detect-leaks dev.nyash
|
||||
|
||||
# 2. テスト:メモリリークがないことを確認
|
||||
nyash --gc-mode=ref-counting --memory-report test.nyash
|
||||
# => No memory leaks detected!
|
||||
|
||||
# 3. 本番:GCオフで最高性能
|
||||
nyash --gc-mode=explicit --optimize prod.nyash
|
||||
```
|
||||
|
||||
### コード例
|
||||
```nyash
|
||||
// 同じコードが両モードで動作
|
||||
box DataProcessor {
|
||||
init { buffer, cache }
|
||||
|
||||
process(data) {
|
||||
me.buffer = data.transform() // GCありなら参照カウント管理
|
||||
me.cache.put(data.id, data) // GCなしなら即座に古い値を破棄
|
||||
return me.buffer
|
||||
}
|
||||
|
||||
fini() {
|
||||
print("Cleanup!") // タイミングはモード次第
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ⚠️ 技術的課題と解決策
|
||||
|
||||
### 1. Arc<Mutex>の重さ
|
||||
**課題**: 現在すべてのBoxがArc<Mutex>で重い
|
||||
**解決**: 必要な場所のみ同期、基本型は非同期に
|
||||
|
||||
### 2. 実行時オーバーヘッド
|
||||
**課題**: モードチェックのコスト
|
||||
**解決**: JITでの関数マルチバージョン化(間接ジャンプ1回のみ)
|
||||
|
||||
### 3. 循環参照
|
||||
**課題**: RefCountingモードでの循環参照
|
||||
**解決**: 既存のWeakBox活用+明示的切断
|
||||
|
||||
### 4. セマンティクスの違い
|
||||
**課題**: デストラクタ呼び出しタイミングの差
|
||||
**解決**: ドキュメント化+移行ガイド作成
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
1. **開発効率**: 30%向上(メモリ管理の負担軽減)
|
||||
2. **実行性能**: GCオフ時は現状維持、GCオン時は5-10%低下
|
||||
3. **メモリ効率**: モード次第で最適化可能
|
||||
4. **教育価値**: メモリ管理の学習に最適なツール
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
- [Phase 10.0: Cranelift JIT](phase_10_cranelift_jit_backend.md)
|
||||
- [Phase 9.79b: Unified Box Design](../phase-9/phase_9_79b_1_unified_registry_ids_and_builder_slotting.md)
|
||||
- [GC Switchable Language Idea](../../../ideas/other/2025-08-26-gc-switchable-language.md)
|
||||
|
||||
## ✅ 受け入れ基準
|
||||
- [ ] インタープリター/VM/JITすべてで両モード動作
|
||||
- [ ] モード切り替えが実行時に可能(再コンパイル不要)
|
||||
- [ ] 既存コードが無修正で動作(後方互換性)
|
||||
- [ ] パフォーマンス劣化が許容範囲(GCオン時10%以内)
|
||||
- [ ] メモリリーク検出ツールの提供
|
||||
|
||||
## 🚀 将来の拡張
|
||||
- Mark & Sweep GCモードの追加
|
||||
- 世代別GC
|
||||
- リージョンベースメモリ管理
|
||||
- プロファイルベース自動モード選択
|
||||
@ -0,0 +1,27 @@
|
||||
Phase 10.4d — Barrier Strict Mode (CI/Local)
|
||||
|
||||
Goal
|
||||
- Catch missing Write-Barrier quickly in development and CI.
|
||||
|
||||
How-To (Local)
|
||||
1) Build with default features:
|
||||
cargo build --release -j32
|
||||
2) Run with CountingGc + Strict Barrier + Trace:
|
||||
(in code) build runtime via NyashRuntimeBuilder::with_counting_gc()
|
||||
(env)
|
||||
set NYASH_GC_BARRIER_STRICT=1
|
||||
set NYASH_GC_TRACE=1
|
||||
nyash <program.nyash>
|
||||
|
||||
Expected
|
||||
- Barrier sites log to stderr.
|
||||
- On any mutating site without barrier increment, process panics with site name.
|
||||
|
||||
CI Suggestion
|
||||
- Add a job that runs selected examples/tests with CountingGc enabled and
|
||||
NYASH_GC_BARRIER_STRICT=1. Fail build on panic.
|
||||
|
||||
Notes
|
||||
- Strict mode requires CountingGc; otherwise the helper panics to avoid false negatives.
|
||||
- Use NYASH_GC_TRACE=2 for detailed roots breakdown at end-of-run when investigating.
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
# Phase 10.6 — Thread-Safe Revolution (Design Prep)
|
||||
|
||||
Status: preparation
|
||||
|
||||
Principles
|
||||
- Opt-in concurrency: default runtime remains single-threaded for simplicity.
|
||||
- All extension points intended for cross-thread use must be `Send + Sync`.
|
||||
|
||||
What’s prepared
|
||||
- `GcHooks: Send + Sync` to allow multi-threaded collectors later.
|
||||
- `NyashRuntime` holds `Arc<dyn GcHooks>` for safe sharing across threads.
|
||||
|
||||
Planned tasks
|
||||
- Audit `NyashBox` implementations for `Send + Sync` (introduce marker traits or wrappers).
|
||||
- Introduce scheduler abstraction for futures/actors (no global state).
|
||||
- Introduce interior mutability strategy `RwLock` on shared mutable state, with minimal contention.
|
||||
|
||||
Notes
|
||||
- Until the audit, VM enforces single-threaded access; sharing across threads is unsupported by default.
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
Phase 10.6a — Thread-Safety Audit (TXT)
|
||||
|
||||
Scope
|
||||
- Audit Send/Sync policy for core runtime + Box families.
|
||||
- Classify: Allowed (Send+Sync), Not-Send (single-threaded), Needs-Wrapper (guarded by RwLock/mpsc/etc.).
|
||||
- Output concrete action items for hardening.
|
||||
|
||||
Legend
|
||||
- ALLOW: Safe to share/send across threads as-is.
|
||||
- NO-SEND: Must remain thread-confined; do not share.
|
||||
- WRAP: Provide wrapper/adapter to safely share (interior mutability / channels / handles).
|
||||
|
||||
Runtime Components
|
||||
- NyashRuntime: WRAP — shared via Arc; subcomponents must be audited (registry/decls RwLock OK).
|
||||
- GcHooks: ALLOW — trait requires Send+Sync; CountingGc is Send+Sync by design.
|
||||
- TypeMeta/CacheVersions: WRAP — global tables; protect via atomic/versioning (already present) + RwLock where needed.
|
||||
- Scheduler (planned): WRAP — explicit abstraction (cooperative); no global mutable state.
|
||||
|
||||
VM Values / Execution
|
||||
- VMValue: ALLOW (data) / WRAP (BoxRef) — primitives OK; BoxRef must only be shared via immutable Box API.
|
||||
- ScopeTracker: NO-SEND — per-VM; not shared. Access confined to single thread.
|
||||
- JIT Manager: WRAP — read-mostly maps; guard with RwLock if shared, or keep per-VM.
|
||||
|
||||
Builtin Boxes (initial pass)
|
||||
- IntegerBox/BoolBox/StringBox: ALLOW (immutable data semantics).
|
||||
- FloatBox (math): ALLOW (stateless ops; string-ification only).
|
||||
- ArrayBox/MapBox: WRAP — interior mutability required (RwLock); Write-Barrier remains required.
|
||||
- Buffer/IO/Net/Time/Audio/etc.: WRAP — external handles; use Arc + internal locks; expose async/channel for ops.
|
||||
- FutureBox: WRAP — already uses RwLock pattern; verify methods are non-blocking and Send+Sync where applicable.
|
||||
- ChannelBox: WRAP — backed by mpsc/crossbeam; ensure senders/receivers are Send.
|
||||
|
||||
Plugin Boxes
|
||||
- PluginBoxV2: WRAP — FFI handle; calls marshalled via TLV; all access through thread-safe host layer.
|
||||
|
||||
Interpreter/Runner Layers
|
||||
- Parser/Tokenizer/AST: ALLOW (not shared at runtime).
|
||||
- Runner (VM backend): NO-SEND — execution confined to the owning thread.
|
||||
|
||||
Policies and Enforcement
|
||||
1) Marker traits (for docs only):
|
||||
- ThreadSafeBox (Doc): Box types that are Send+Sync-safe as value semantics.
|
||||
- HandleBox (Doc): wraps external/native handles; must be behind RwLock/Mutex and non-blocking APIs.
|
||||
2) Constructor guidance:
|
||||
- For WRAP boxes, store state under RwLock/Mutex; prefer RwLock (read-mostly).
|
||||
- Avoid blocking in methods; prefer async/task dispatch via scheduler abstraction.
|
||||
3) Sharing rules:
|
||||
- VMValue::BoxRef must not be mutated without Write-Barrier when GC is active.
|
||||
- Cross-thread sharing limited to BoxRef with immutable APIs or actor-like message passing.
|
||||
4) Testing:
|
||||
- Add feature-gated thread-smoke tests (spawn two threads, share ALLOW boxes, ensure no UB).
|
||||
- Add Mutex/RwLock poisoning handling policies (map to Nyash exceptions if needed).
|
||||
|
||||
Immediate Action Items
|
||||
- [A1] Document per-Box classification in code headers (short note + rationale).
|
||||
- [A2] Ensure ArrayBox/MapBox internals use RwLock and respect Write-Barrier (already partially in place; verify set/push paths).
|
||||
- [A3] PluginBoxV2 calls remain serialized through host; confirm Send on host dispatch closures.
|
||||
- [A4] Introduce lightweight scheduler trait (single-threaded impl first); route blocking ops via scheduler.
|
||||
- [A5] Add CI job to run with NYASH_GC_BARRIER_STRICT=1 and CountingGc for barrier regression.
|
||||
|
||||
Future (10_6b/10_6c tie-ins)
|
||||
- Scheduler + cooperative safepoint policy across threads.
|
||||
- Per-thread root regions; ensure root pin/unpin remains thread-local.
|
||||
- Card marking/write barrier strategy for shared objects modified across threads (design doc first).
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
Phase 10.6b — Scheduler Prep (Single-Thread Queue)
|
||||
|
||||
What’s added
|
||||
- `src/runtime/scheduler.rs` with `Scheduler` trait and `SingleThreadScheduler`.
|
||||
- Queue + delayed tasks (spawn/spawn_after) and `poll()` to run work.
|
||||
- VM calls `scheduler.poll()` at MIR `Safepoint` to integrate cooperative scheduling.
|
||||
- Poll budget via env `NYASH_SCHED_POLL_BUDGET` (default: 1)
|
||||
|
||||
How to use (dev)
|
||||
- Build runtime with default SingleThreadScheduler (already default via builder), or inject custom via:
|
||||
`NyashRuntimeBuilder::new().with_single_thread_scheduler().build()`
|
||||
- Schedule tasks from boxes/host code via `runtime.scheduler.spawn(...)`.
|
||||
- At safepoints, queued tasks run (1 per safepoint) and due delayed tasks are enqueued.
|
||||
|
||||
How to validate quickly
|
||||
- Run any Nyash program that contains loops or function entries (safepoints exist by default).
|
||||
- Optionally enable the demo hook: set `NYASH_SCHED_DEMO=1` and run the VM backend
|
||||
to observe scheduler tasks firing at safepoints.
|
||||
- Control throughput by `NYASH_SCHED_POLL_BUDGET` (e.g., 3 runs up to 3 tasks/safepoint).
|
||||
- GC trace pairs well: set `NYASH_GC_COUNTING=1 NYASH_GC_TRACE=1` to see safepoints.
|
||||
|
||||
Next (10.6c+)
|
||||
- Expose scheduling APIs to script level (Box API).
|
||||
- Optional multi-thread scheduler implementation behind feature flag.
|
||||
@ -0,0 +1,37 @@
|
||||
Phase 10.6c — Parallel GC Design (Notes)
|
||||
|
||||
Objectives
|
||||
- Keep GC hooks and MIR sites stable while enabling parallel/stop-the-world options.
|
||||
- Introduce per-thread root regions, card marking, and coordinated safepoints.
|
||||
|
||||
Design Sketch
|
||||
1) Per-thread roots
|
||||
- Root API remains the same but live under thread-local trackers.
|
||||
- VM/engines expose `enter_root_region/pin/leave_root_region` that operate on TLS.
|
||||
- Global snapshot for diagnostics merges per-thread views (debug only).
|
||||
|
||||
2) Safepoint coordination
|
||||
- Central GC controller requests a safepoint; worker threads acknowledge at next MIR `Safepoint`.
|
||||
- Timeout/poll policy configurable; in single-threaded mode this is no-op.
|
||||
|
||||
3) Card marking / write barriers
|
||||
- Extend `BarrierKind::Write` to accept optional object metadata (future API): object id/card index.
|
||||
- For now, keep symbolic barrier only; when parallel GC is enabled, maintain a global dirty set.
|
||||
|
||||
4) Scheduler interplay
|
||||
- GC controller can schedule minor/major cycles using the Scheduler abstraction.
|
||||
- In single-threaded mode, cycles are chunked via `poll()` to avoid long pauses.
|
||||
|
||||
API Diffs (future)
|
||||
- `GcHooks::barrier(kind)` → `barrier(kind, obj: Option<ObjectId>)` (compat shim keeps old signature).
|
||||
- `GcHooks::safepoint()` may return a hint (`Proceed`, `Yield`) for engines to cooperate.
|
||||
|
||||
Migration Plan
|
||||
- Keep current single-threaded path as default.
|
||||
- Add feature flag `gc-parallel` that swaps in an implementation honoring the extended API.
|
||||
- Incrementally add: dirty set, per-thread roots, coordinated safepoint prototype.
|
||||
|
||||
Testing Strategy
|
||||
- Deterministic unit tests using SingleThreadScheduler.
|
||||
- Stress tests with STRICT barrier and TRACE=2 to validate barrier coverage and root progression.
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
Phase 10.7 — JIT Branch Wiring + Minimal ABI Extensions
|
||||
|
||||
Overview
|
||||
- Purpose: Enable real control-flow in the JIT path by wiring MIR Branch/Jump/Return to Cranelift blocks, and extend the minimal ABI to support multi-arg i64 and basic bool/f64.
|
||||
- Outcome: If/loop constructs execute natively in JIT for straight-line + branched code paths, with safe VM fallback preserved. HostCall PoC remains opt-in.
|
||||
|
||||
Goals (Must)
|
||||
- Wire MIR basic blocks to Cranelift blocks; emit `brif` and `jump` for Branch/Jump.
|
||||
- Keep Compare result usable as a branch condition (b1); where necessary, convert i64 to b1 via `icmp_imm != 0`.
|
||||
- Preserve Return behavior (already in place) and allow branching to return in both sides (no PHI required for first pass).
|
||||
- Minimal ABI: multi-argument i64 stable, bool constants lowered to 0/1, f64 constants passed through (no arithmetic yet required).
|
||||
- Safety: On JIT panic or unsupported instruction at runtime, VM fallback with logs.
|
||||
|
||||
Stretch (Nice-to-have)
|
||||
- PHI at merge points via block parameters for simple patterns (two-predecessor if-else returning a value).
|
||||
- Bench: Add a small control-flow benchmark to CLI/`examples`.
|
||||
|
||||
Non-Goals (10.7)
|
||||
- Full PHI generalization across arbitrary CFG.
|
||||
- Type-specialized calling conventions beyond i64/f64/bool minimal path.
|
||||
- Deoptimization or on-stack replacement.
|
||||
|
||||
Deliverables
|
||||
- Code: CraneliftBuilder block management + branch/jump emission.
|
||||
- Lowering updates: Branch/Jump hook uses real block IDs; Compare emits b1-friendly shape.
|
||||
- Env flags: Reuse `NYASH_JIT_EXEC/THRESHOLD/STATS/DUMP`; guard hostcalls by `NYASH_JIT_HOSTCALL`.
|
||||
- Docs: Update execution-backends.md with “JIT control-flow coverage (10.7)”.
|
||||
- Examples: `examples/jit_branch_demo.nyash` (if/loop minimal).
|
||||
|
||||
Design Sketch
|
||||
1) Block Mapping
|
||||
- Build `bb_map: MirBB -> Cranelift Block` in `begin_function` based on MIR function blocks.
|
||||
- Switch to entry block, `seal_block(entry)`.
|
||||
|
||||
2) Conditions
|
||||
- Compare emits Cranelift `icmp` returning b1; avoid converting to i64 unless explicitly needed.
|
||||
- If the condition arrives as i64 (const/param), lower `icmp_imm != 0` to get b1 for `brif`.
|
||||
|
||||
3) Branch / Jump
|
||||
- `emit_branch(cond, then_bb, else_bb)` → `brif(cond_b1, then_block, []); jump(else_block, []); seal both`.
|
||||
- `emit_jump(target_bb)` → `jump(target_block, [])`.
|
||||
|
||||
4) Return
|
||||
- Keep current return emission; when branches end in return, no PHI needed.
|
||||
|
||||
5) PHI (limited)
|
||||
- For a simple diamond where both arms jump to a single merge, add one block param at merge.
|
||||
- Pass the value via `jump(merge, [val])`; read via `block-arg(merge, 0)`; return it.
|
||||
|
||||
6) ABI
|
||||
- Keep signature `(i64 x argc) -> i64?` baseline.
|
||||
- Support f64/bool consts materialization; booleans as 0/1 integers for now unless used as branch cond (then b1).
|
||||
|
||||
Implementation Plan (Tasks)
|
||||
- T1: Extend IRBuilder API (only behind `cranelift-jit`): create_block(), br_if(), jump(), seal_block(), block_param(), append_block_params_for_function_params().
|
||||
- T2: CraneliftBuilder: implement block map allocation in begin_function; store in builder state.
|
||||
- T3: LowerCore:
|
||||
- Track current MIR bb while iterating.
|
||||
- For Branch/Jump, call builder with mapped blocks and condition value hint.
|
||||
- Compare: emit b1 icmp; when Compare is used as value elsewhere, allow i64 extend as needed.
|
||||
- T4: Minimal PHI support for a single merge (optional; guarded by env `NYASH_JIT_PHI_MIN=1`).
|
||||
- T5: Add `examples/jit_branch_demo.nyash` with: `if (a < b) { return 1 } else { return 2 }` and a small loop with early `return`.
|
||||
- T6: Docs update: execution-backends.md “JIT coverage 10.7” + env flags.
|
||||
- T7: Bench (optional): integrate into `--benchmark` with JIT warmup when `NYASH_JIT_EXEC=1`.
|
||||
|
||||
Validation
|
||||
- Build matrix: with/without `cranelift-jit` feature.
|
||||
- Smoke tests: run `jit_branch_demo.nyash` with `NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1`.
|
||||
- Fallback verification: force a path with unsupported op to confirm VM fallback.
|
||||
- GC/scheduler: ensure safepoint path still works (unchanged).
|
||||
|
||||
Risk & Mitigation
|
||||
- Mismatch of block sealing/order → start with straight-line + simple diamond; add asserts; prefer FunctionBuilder patterns.
|
||||
- Condition type confusion (i64 vs b1) → centralize cond normalization helper.
|
||||
- PHI complexity → keep optional, limited to single value diamond.
|
||||
|
||||
Rollout
|
||||
- Phase gate by envs: `NYASH_JIT_EXEC` for enable, `NYASH_JIT_PHI_MIN` for PHI.
|
||||
- Keep `NYASH_JIT_HOSTCALL` opt-in.
|
||||
|
||||
Success Criteria
|
||||
- If/else returning constants runs fully via JIT (Cranelift) without VM fallback.
|
||||
- Simple counting loop with early exit returns correct result via JIT.
|
||||
- All tests pass with and without feature flag; VM fallback works on traps.
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
# Phase 10.8: 統一デバッグシステム - DeepInspectorBoxとグローバルデバッグ整理
|
||||
|
||||
作成日: 2025-08-27
|
||||
発見者: ニャー
|
||||
参照元: docs/ideas/other/2025-08-25-unified-box-design-deep-analysis.md
|
||||
|
||||
## 🚨 現在の問題
|
||||
|
||||
### 1. デバッグ環境変数の乱立
|
||||
現在20個以上の環境変数が散在:
|
||||
- `NYASH_VM_STATS=1`
|
||||
- `NYASH_VM_DEBUG_BOXCALL=1`
|
||||
- `NYASH_DEBUG_PLUGIN=1`
|
||||
- `NYASH_NET_LOG=1`
|
||||
- `NYASH_JIT_THRESHOLD=1`
|
||||
- ... など多数
|
||||
|
||||
### 2. 統一されていないデバッグ体験
|
||||
- VM、プラグイン、JIT、ネットワークなど各コンポーネントが独自のデバッグフラグ
|
||||
- 複数の環境変数を組み合わせる必要がある
|
||||
- 何をONにすればいいか分かりにくい
|
||||
|
||||
## 🌟 提案: 統一デバッグシステム
|
||||
|
||||
### 1. 環境変数の整理統合
|
||||
|
||||
```bash
|
||||
# Before (現在)
|
||||
NYASH_VM_STATS=1 NYASH_VM_DEBUG_BOXCALL=1 NYASH_NET_LOG=1 ./nyash
|
||||
|
||||
# After (提案)
|
||||
NYASH_DEBUG=vm,boxcall,net ./nyash
|
||||
```
|
||||
|
||||
### 2. デバッグレベル制御
|
||||
|
||||
```bash
|
||||
# シンプルなレベル制御
|
||||
NYASH_DEBUG_LEVEL=0 # OFF
|
||||
NYASH_DEBUG_LEVEL=1 # 基本情報のみ
|
||||
NYASH_DEBUG_LEVEL=2 # 詳細情報
|
||||
NYASH_DEBUG_LEVEL=3 # すべて
|
||||
|
||||
# カテゴリ別レベル
|
||||
NYASH_DEBUG=vm:2,net:1,jit:3
|
||||
```
|
||||
|
||||
### 3. プリセット(よく使う組み合わせ)
|
||||
|
||||
```bash
|
||||
# プリセット
|
||||
NYASH_DEBUG_PRESET=basic # 基本的なデバッグ情報
|
||||
NYASH_DEBUG_PRESET=perf # パフォーマンス分析用
|
||||
NYASH_DEBUG_PRESET=network # ネットワーク問題調査用
|
||||
NYASH_DEBUG_PRESET=memory # メモリリーク調査用
|
||||
NYASH_DEBUG_PRESET=all # すべて有効
|
||||
```
|
||||
|
||||
## 🔍 DeepInspectorBox - Everything is Debugの実現
|
||||
|
||||
### グローバルシングルトンデバッガー
|
||||
|
||||
```nyash
|
||||
// グローバルに1つだけ存在する統一デバッガー
|
||||
static box DeepInspectorBox {
|
||||
public { enabled }
|
||||
private {
|
||||
boxCreations, methodCalls, fieldAccess,
|
||||
memorySnapshots, referenceGraph, performanceMetrics
|
||||
}
|
||||
|
||||
// === 簡単な有効化 ===
|
||||
enable(categories) {
|
||||
// "vm,net,memory" のようなカテゴリ文字列を解析
|
||||
me.parseAndEnableCategories(categories)
|
||||
}
|
||||
|
||||
// === プリセット対応 ===
|
||||
usePreset(presetName) {
|
||||
match presetName {
|
||||
"basic" => me.enable("vm,error")
|
||||
"perf" => me.enable("vm,boxcall,stats")
|
||||
"network" => me.enable("net,plugin,tlv")
|
||||
"memory" => me.enable("alloc,gc,leak")
|
||||
"all" => me.enable("*")
|
||||
}
|
||||
}
|
||||
|
||||
// === 統合ログ出力 ===
|
||||
log(category, level, message) {
|
||||
if me.shouldLog(category, level) {
|
||||
local formatted = me.formatLog(category, level, message)
|
||||
me.output(formatted)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### MIRレベルでの統一実装
|
||||
|
||||
```rust
|
||||
// MIR生成時にデバッグフックを埋め込み
|
||||
impl MirBuilder {
|
||||
fn build_new_box(&mut self, type_id: TypeId) -> ValueId {
|
||||
let result = self.push(NewBox { type_id });
|
||||
|
||||
// デバッグモード時のみ
|
||||
if self.debug_enabled {
|
||||
self.push(DebugHook {
|
||||
event: DebugEvent::BoxCreated,
|
||||
type_id,
|
||||
value: result,
|
||||
});
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 実装計画
|
||||
|
||||
### Phase 10.8a: 環境変数統合(3日)
|
||||
- [ ] 統一パーサー実装(`NYASH_DEBUG`解析)
|
||||
- [ ] レベル制御システム
|
||||
- [ ] プリセット定義
|
||||
- [ ] 既存環境変数との互換性層
|
||||
|
||||
### Phase 10.8b: DeepInspectorBox基礎(1週間)
|
||||
- [ ] グローバルシングルトン実装
|
||||
- [ ] カテゴリ管理システム
|
||||
- [ ] 基本的なログ収集
|
||||
- [ ] 出力フォーマッター
|
||||
|
||||
### Phase 10.8c: MIR統合(1週間)
|
||||
- [ ] DebugHook命令追加
|
||||
- [ ] MirBuilderへのフック埋め込み
|
||||
- [ ] VMでのDebugHook実行
|
||||
- [ ] JITでのデバッグ情報保持
|
||||
|
||||
### Phase 10.8d: 高度な機能(2週間)
|
||||
- [ ] メモリリーク検出
|
||||
- [ ] 参照グラフ構築
|
||||
- [ ] P2P非同期フロー追跡
|
||||
- [ ] パフォーマンスプロファイリング
|
||||
|
||||
## 🎯 期待される効果
|
||||
|
||||
### 1. 使いやすさ向上
|
||||
- 1つの環境変数で制御
|
||||
- 分かりやすいプリセット
|
||||
- 統一されたログフォーマット
|
||||
|
||||
### 2. デバッグ効率向上
|
||||
- 必要な情報だけを表示
|
||||
- カテゴリ別フィルタリング
|
||||
- レベル別詳細度制御
|
||||
|
||||
### 3. 保守性向上
|
||||
- 新しいデバッグ機能の追加が容易
|
||||
- 統一されたインターフェース
|
||||
- MIRレベルでの一元管理
|
||||
|
||||
## ✅ 成功基準
|
||||
|
||||
1. **環境変数の数**: 20個以上 → 3個以下
|
||||
2. **デバッグ有効化**: 複雑なコマンド → `NYASH_DEBUG=basic`
|
||||
3. **統一体験**: すべてのコンポーネントで同じデバッグインターフェース
|
||||
|
||||
---
|
||||
|
||||
*Everything is Box, Everything is Debug - 統一されたデバッグ体験へ*
|
||||
@ -0,0 +1,85 @@
|
||||
# Phase 10.7: fromキーワード一貫性修正
|
||||
|
||||
作成日: 2025-08-27
|
||||
発見者: ニャー
|
||||
|
||||
## 🚨 現在の問題
|
||||
|
||||
### 言語仕様と実装の不一致
|
||||
- **言語仕様**: `from Parent.method()` (2025-08-11完全明示デリゲーション革命で決定)
|
||||
- **実装の一部**: まだ`super`という用語が残っている可能性
|
||||
|
||||
### 影響範囲
|
||||
主にRustの`use super::*`(モジュールインポート)なので言語仕様への影響は限定的だが、以下の確認が必要:
|
||||
1. エラーメッセージ内の文言
|
||||
2. ドキュメントやコメント内の記述
|
||||
3. 内部変数名・関数名での使用
|
||||
|
||||
## 🔧 修正内容
|
||||
|
||||
### 1. エラーメッセージの確認
|
||||
```rust
|
||||
// 例: エラーメッセージで"super"を使っていないか確認
|
||||
"Cannot find super class" → "Cannot find parent box for delegation"
|
||||
```
|
||||
|
||||
### 2. ドキュメント・コメントの統一
|
||||
```rust
|
||||
// Before
|
||||
// Call super method
|
||||
|
||||
// After
|
||||
// Call parent method via from delegation
|
||||
```
|
||||
|
||||
### 3. 内部実装での用語統一(必要に応じて)
|
||||
```rust
|
||||
// 変数名や内部メソッド名での統一
|
||||
super_call() → from_call()
|
||||
SuperMethodCall → FromMethodCall
|
||||
```
|
||||
|
||||
## 📊 優先度評価
|
||||
|
||||
- **重要度**: 中(言語仕様の一貫性)
|
||||
- **緊急度**: 低(機能的には問題ない)
|
||||
- **実装難度**: 低(主に文言修正)
|
||||
|
||||
## 🎯 実装計画
|
||||
|
||||
### Phase 10.7a: 調査フェーズ(1日)
|
||||
- [ ] エラーメッセージ内の"super"使用箇所を特定
|
||||
- [ ] ドキュメント内の不整合を洗い出し
|
||||
- [ ] テストケース内の文言確認
|
||||
|
||||
### Phase 10.7b: 修正フェーズ(1日)
|
||||
- [ ] エラーメッセージの文言修正
|
||||
- [ ] ドキュメント更新
|
||||
- [ ] 必要に応じて内部変数名の統一
|
||||
|
||||
### Phase 10.7c: 検証フェーズ(半日)
|
||||
- [ ] 修正後の動作確認
|
||||
- [ ] エラーメッセージの表示確認
|
||||
- [ ] ドキュメントの整合性チェック
|
||||
|
||||
## 📝 Nyashの哲学との整合性
|
||||
|
||||
### fromキーワードの意義
|
||||
- **明示性**: どの親のどのメソッドかを完全に明示
|
||||
- **統一性**: 宣言(`box Child from Parent`)と呼び出し(`from Parent.method()`)で同じキーワード
|
||||
- **初学者フレンドリー**: 「〜から」という直感的な表現
|
||||
|
||||
### superを使わない理由
|
||||
- 多重デリゲーション時に曖昧
|
||||
- 他言語の概念を引きずらない
|
||||
- Nyash独自の哲学を貫く
|
||||
|
||||
## ✅ 期待される効果
|
||||
|
||||
1. **一貫性**: 言語仕様と実装の完全な一致
|
||||
2. **学習性**: 初学者が混乱しない統一された用語
|
||||
3. **独自性**: Nyashらしい設計思想の徹底
|
||||
|
||||
---
|
||||
|
||||
*「from」こそがNyashの明示的デリゲーションの象徴*
|
||||
@ -96,6 +96,22 @@ AST → MIR → Optimizer → VM Dispatcher
|
||||
- 境界チェック/エラーはRust側に委譲、JITは薄い橋渡し
|
||||
- 受入: Array操作がVM経由より高速(目安1.5–2.0×)
|
||||
|
||||
Status(2025-08-27)
|
||||
- Param経路でのE2Eを実装(`NYASH_JIT_HOSTCALL=1`ゲート)
|
||||
- 実装済みシンボル(PoC, C-ABI in Rust):
|
||||
- `nyash.array.{len,push,get,set}` / `nyash.map.size`
|
||||
- 使い方(例):
|
||||
```bash
|
||||
cargo build --features cranelift-jit --release
|
||||
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
|
||||
./target/release/nyash --backend vm examples/jit_array_param_call.nyash
|
||||
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
|
||||
./target/release/nyash --backend vm examples/jit_map_param_call.nyash
|
||||
```
|
||||
Notes
|
||||
- 関数パラメータに渡した配列/MapのみHostCall経由でアクセス(thread-local引数参照)
|
||||
- ローカルnew値は10_eへ移管(ハンドル表PoC: u64→Arc<Box>)
|
||||
|
||||
### 10_e: BoxCall高速化 – Thunk/PICの直結
|
||||
- 目的: Phase 9.79bの `TypeMeta{slot->thunk}` と Poly-PIC をJITにインライン。
|
||||
- 具体:
|
||||
@ -150,3 +166,102 @@ AST → MIR → Optimizer → VM Dispatcher
|
||||
- ABI複雑化: まず整数/浮動/voidに限定し、BoxRefはホスト関数へブリッジ
|
||||
- 最適化過剰: 常にVMフォールバックを保持、ガード失敗で安全に戻す
|
||||
- デバッグ困難: CLIFダンプ/CFG表示/`NYASH_JIT_STATS`で観測
|
||||
|
||||
## 🐛 発見した問題点(2025-08-27 ベンチマーク実行時)
|
||||
|
||||
### 1. インタープリター性能問題
|
||||
- **問題**: 10万回のループで2分以上かかりタイムアウト
|
||||
- **原因**: `unwrap_instance`のデバッグログが大量出力(毎回の演算でInstanceBoxチェック)
|
||||
- **目標**: 10万回ループを数秒で完了
|
||||
- **対策**:
|
||||
- デバッグログの条件付き出力化
|
||||
- 基本演算の高速化(IntegerBoxの直接操作最適化)
|
||||
|
||||
### 2. VMの変数管理エラー
|
||||
- **問題**: `Invalid value: Value %47 not set` - simple_add_loop内の変数zが正しく管理されていない
|
||||
- **原因**: MIR生成時の変数スコープ管理の不具合
|
||||
- **対策**: MirBuilderの変数トラッキング改善
|
||||
|
||||
### 3. Box APIの成熟度
|
||||
- **問題**: TimeBoxにelapsed()/reset()メソッドがインタープリターから呼べない
|
||||
- **原因**: Boxメソッドの登録システム未完成
|
||||
- **対策**:
|
||||
- Boxメソッドの統一的登録システム実装
|
||||
- インタープリターとVMのメソッド解決統一
|
||||
|
||||
### 4. ベンチマーク基盤
|
||||
- **問題**: Nyashスクリプトでの正確な時間計測が困難
|
||||
- **根本原因**: TimeBoxのelapsed()/reset()メソッドがインタープリターから呼べない(Box API問題と同じ)
|
||||
- **対策**: Box APIの成熟度問題(問題3)が解決すれば自動的に解決
|
||||
|
||||
### 改善優先度
|
||||
1. **高**: インタープリター性能問題(基本機能の使い物にならない)
|
||||
2. **中**: VM変数管理(JIT最適化の前提)
|
||||
3. **中**: Box APIの成熟度(ベンチマーク基盤も同時解決)
|
||||
|
||||
## 🚀 Phase 10.9: Cranelift AOT Backend(追加計画)
|
||||
|
||||
Status: Future (JIT実装の上乗せで実現可能)
|
||||
|
||||
### 概要
|
||||
JIT実装(10_a~10_h)で構築したMIR→CLIF変換基盤をそのまま活用し、事前コンパイル(AOT)によるスタンドアロン実行ファイル生成を実現する。
|
||||
|
||||
### 利点
|
||||
- **コード再利用**: JITと同じLowerCore実装を使用(追加実装最小)
|
||||
- **非同期完全サポート**: WASMの制限なし、ネイティブ非同期可能
|
||||
- **最高性能**: ネイティブコード直接実行(起動時コンパイル不要)
|
||||
- **デバッグ容易**: gdb/lldb等のネイティブデバッガ使用可能
|
||||
|
||||
### 実装ステップ案
|
||||
```
|
||||
10.9a: ObjectModule統合
|
||||
├── cranelift-objectモジュール導入
|
||||
├── CLIF→オブジェクトファイル生成
|
||||
└── 既存のLowerCore再利用
|
||||
|
||||
10.9b: ランタイムライブラリ
|
||||
├── Nyash標準Box群の静的リンク版作成
|
||||
├── プラグインの静的埋め込み対応
|
||||
└── 最小ランタイム(GC hooks等)分離
|
||||
|
||||
10.9c: リンカー統合
|
||||
├── cc/ldによる実行ファイル生成
|
||||
├── プラットフォーム別設定
|
||||
└── デバッグシンボル生成
|
||||
|
||||
10.9d: クロスコンパイル
|
||||
├── 複数ターゲット(x86_64/aarch64/wasm32)
|
||||
├── ターゲット別最適化
|
||||
└── CI/CDでのマルチプラットフォームビルド
|
||||
```
|
||||
|
||||
### 使用イメージ
|
||||
```bash
|
||||
# ネイティブ実行ファイル生成
|
||||
./target/release/nyash --compile-native program.nyash -o program
|
||||
./program # スタンドアロン実行!
|
||||
|
||||
# クロスコンパイル
|
||||
./target/release/nyash --compile-native --target x86_64-pc-windows-msvc program.nyash -o program.exe
|
||||
./target/release/nyash --compile-native --target aarch64-apple-darwin program.nyash -o program.mac
|
||||
```
|
||||
|
||||
### 技術的詳細
|
||||
- **共通基盤**: `LowerCore`のemit処理はJIT/AOT両対応
|
||||
- **差分実装**: JITは`JITModule`、AOTは`ObjectModule`を使用
|
||||
- **リンク方式**: 静的リンク優先(配布容易性重視)
|
||||
- **サイズ最適化**: LTO/strip対応で実行ファイルサイズ削減
|
||||
|
||||
### WASM AOTとの比較
|
||||
| 特性 | Cranelift AOT | WASM AOT |
|
||||
|------|--------------|----------|
|
||||
| 非同期 | ✅ 完全対応 | ❌ 制限あり |
|
||||
| 実行速度 | 最速 | 速い |
|
||||
| ファイルサイズ | 大(MB級) | 小(KB級) |
|
||||
| ポータビリティ | プラットフォーム別 | 高い |
|
||||
| デバッグ | ネイティブツール | 限定的 |
|
||||
|
||||
### 想定スケジュール
|
||||
- Phase 10(JIT)安定化後に着手
|
||||
- 実装期間: 2-3週間(JIT基盤の再利用により短期実現可能)
|
||||
- 初期ターゲット: Linux x86_64、その後Windows/macOS対応
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
# Phase 10: Function Declaration MIR サポート課題
|
||||
|
||||
作成日: 2025-08-27
|
||||
発見者: Claude & ChatGPT5 & ニャー
|
||||
|
||||
## 🚨 現在の問題
|
||||
|
||||
### 症状
|
||||
```bash
|
||||
❌ MIR compilation error: Unsupported AST node type: FunctionDeclaration
|
||||
```
|
||||
|
||||
### 影響範囲
|
||||
- 通常の`function`定義がMIRでコンパイルできない
|
||||
- JITテストで関数を使った配列操作ができない
|
||||
- Static Boxメソッドは動作するが、通常関数が使えない
|
||||
|
||||
### 具体例
|
||||
```nyash
|
||||
// ❌ 動作しない - FunctionDeclarationがMIR未対応
|
||||
function len_of(arr) {
|
||||
return arr.length()
|
||||
}
|
||||
|
||||
// ✅ 動作する - Static Boxメソッド
|
||||
static box Utils {
|
||||
len_of(arr) {
|
||||
return arr.length()
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 動作する - 直接呼び出し
|
||||
local arr = new ArrayBox()
|
||||
local len = arr.length()
|
||||
```
|
||||
|
||||
## 🔧 解決案
|
||||
|
||||
### Option 1: MIRビルダーにFunctionDeclaration対応追加
|
||||
```rust
|
||||
// mir/builder.rs に追加
|
||||
AstNode::FunctionDeclaration { name, params, body, .. } => {
|
||||
// 関数をMirFunctionとして登録
|
||||
let mir_func = self.build_function(name, params, body)?;
|
||||
self.functions.insert(name.clone(), mir_func);
|
||||
}
|
||||
```
|
||||
|
||||
### Option 2: ASTレベルでStatic Boxに変換
|
||||
- FunctionDeclarationを内部的にStatic Boxメソッドに変換
|
||||
- 互換性を保ちつつ既存の仕組みを活用
|
||||
|
||||
### Option 3: 当面の回避策を公式化
|
||||
- ドキュメントで「VMモードではStatic Boxメソッドを推奨」と明記
|
||||
- 将来のサポートとして計画に含める
|
||||
|
||||
## 📊 優先度評価
|
||||
|
||||
- **重要度**: 中(基本的な言語機能だが回避策あり)
|
||||
- **緊急度**: 低(Static Boxで代替可能)
|
||||
- **実装難度**: 中(MIRビルダーの拡張が必要)
|
||||
|
||||
## 🎯 推奨アクション
|
||||
|
||||
1. **短期**: Static Boxメソッドを使った回避策をドキュメント化
|
||||
2. **中期**: Phase 10.1でFunctionDeclaration対応を実装
|
||||
3. **長期**: 関数定義の最適化(インライン化等)も検討
|
||||
|
||||
## 📝 関連イシュー
|
||||
- JIT配列操作テスト
|
||||
- MIRビルダー拡張
|
||||
- 言語仕様の完全性
|
||||
@ -0,0 +1,35 @@
|
||||
Phase 10 — GC/Thread Roadmap Order (txt)
|
||||
|
||||
Recommended order:
|
||||
10_4a → 10_4b → 10_6a → 10_4c → 10_4d → 10_6b → 10_6c
|
||||
|
||||
10_4a: GC hook scaffolding
|
||||
- Add GcHooks { safepoint(), barrier(kind) } and BarrierKind.
|
||||
- NyashRuntime holds Arc<dyn GcHooks>; builder supports with_gc_hooks.
|
||||
- VM calls hooks at MIR Safepoint/Barrier*.
|
||||
|
||||
10_4b: Roots + minimal barriers
|
||||
- ScopeTracker root API: enter_root_region/leave_root_region/pin_root.
|
||||
- Write-Barrier at RefSet/ArraySet/BoxCall(Array/Map: set/push).
|
||||
- Tracing flags: NYASH_GC_TRACE=1 for barrier/safepoint and roots.
|
||||
|
||||
10_6a: Thread-safety audit (prep)
|
||||
- Audit Builtin/User/Plugin boxes for Send/Sync policy.
|
||||
- Strategy for shared state (RwLock) and non-thread-safe wrappers.
|
||||
|
||||
10_4c: GC PoC (STW, single-thread)
|
||||
- Implement simple collector behind GcHooks (e.g., mark-sweep or RC hybrid).
|
||||
- Manage roots via ScopeTracker; traverse VMValue graph/object_fields.
|
||||
|
||||
10_4d: Barrier hardening + regression
|
||||
- Ensure coverage for all mutating write sites (Array/Map/Ref/Plugin paths).
|
||||
- Strict checks flag for development; add stress/regression tests.
|
||||
|
||||
10_6b: Thread runtime scaffolding
|
||||
- Scheduler abstraction (cooperative preemption), Future/Channel compliance.
|
||||
- Confirm GcHooks is Send+Sync and shareable.
|
||||
|
||||
10_6c: Parallel GC design notes
|
||||
- Per-thread root regions, card marking/write barriers, safepoint coordination.
|
||||
- Document design and API diffs for later implementation.
|
||||
|
||||
Reference in New Issue
Block a user