pr6.4
This commit is contained in:
parent
29736e9577
commit
5095fc1a76
@ -407,4 +407,70 @@ mod tests {
|
||||
assert!(!heap.is_valid(b));
|
||||
assert_eq!(heap.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gc_scans_closure_env_and_keeps_captured_heap_object() {
|
||||
let mut heap = Heap::new();
|
||||
|
||||
// Captured heap object.
|
||||
let obj = heap.allocate_object(ObjectKind::Bytes, &[4, 5, 6]);
|
||||
|
||||
// Closure capturing the heap object among other primitive values.
|
||||
let env = [Value::Boolean(true), Value::HeapRef(obj), Value::Int32(123)];
|
||||
let clo = heap.alloc_closure(1, &env);
|
||||
|
||||
// Mark from closure root: both closure and captured object must be marked.
|
||||
heap.mark_from_roots([clo]);
|
||||
|
||||
assert!(heap.header(clo).unwrap().is_marked());
|
||||
assert!(heap.header(obj).unwrap().is_marked());
|
||||
|
||||
// Sweep should keep both and clear their marks.
|
||||
heap.sweep();
|
||||
assert!(heap.is_valid(clo));
|
||||
assert!(heap.is_valid(obj));
|
||||
assert!(!heap.header(clo).unwrap().is_marked());
|
||||
assert!(!heap.header(obj).unwrap().is_marked());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gc_scans_nested_closures_and_keeps_inner_when_outer_is_rooted() {
|
||||
let mut heap = Heap::new();
|
||||
|
||||
// Inner closure (no env).
|
||||
let inner = heap.alloc_closure(2, &[]);
|
||||
|
||||
// Outer closure captures the inner closure as a Value::HeapRef.
|
||||
let outer = heap.alloc_closure(3, &[Value::HeapRef(inner)]);
|
||||
|
||||
// Root only the outer closure.
|
||||
heap.mark_from_roots([outer]);
|
||||
|
||||
// Both must be marked reachable.
|
||||
assert!(heap.header(outer).unwrap().is_marked());
|
||||
assert!(heap.header(inner).unwrap().is_marked());
|
||||
|
||||
// After sweep, both survive and have marks cleared.
|
||||
heap.sweep();
|
||||
assert!(heap.is_valid(outer));
|
||||
assert!(heap.is_valid(inner));
|
||||
assert!(!heap.header(outer).unwrap().is_marked());
|
||||
assert!(!heap.header(inner).unwrap().is_marked());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gc_collects_unreferenced_closure_and_captures() {
|
||||
let mut heap = Heap::new();
|
||||
|
||||
// Captured heap object and a closure capturing it.
|
||||
let captured = heap.allocate_object(ObjectKind::String, b"dead");
|
||||
let clo = heap.alloc_closure(9, &[Value::HeapRef(captured)]);
|
||||
|
||||
// No roots are provided; sweeping should reclaim both.
|
||||
heap.sweep();
|
||||
|
||||
assert!(!heap.is_valid(clo));
|
||||
assert!(!heap.is_valid(captured));
|
||||
assert_eq!(heap.len(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
413
files/TODOs.md
413
files/TODOs.md
@ -1,76 +1,3 @@
|
||||
# PR-6.4 — GC Traversal for Closures (Model B)
|
||||
|
||||
## Briefing
|
||||
|
||||
Closures introduce heap-to-heap references through their captured environments.
|
||||
|
||||
Under Model B, the closure object itself is passed at call time, but its environment remains stored in heap.
|
||||
|
||||
GC must traverse:
|
||||
|
||||
closure -> env -> inner HeapRefs
|
||||
|
||||
---
|
||||
|
||||
## Target
|
||||
|
||||
Extend GC mark phase to handle `ObjectKind::Closure`:
|
||||
|
||||
When marking a closure:
|
||||
|
||||
* Iterate over env values.
|
||||
* If a value contains HeapRef → mark referenced object.
|
||||
|
||||
No compaction. No relocation.
|
||||
|
||||
---
|
||||
|
||||
## Work Items
|
||||
|
||||
1. Extend mark traversal switch.
|
||||
2. Ensure safe iteration over env payload.
|
||||
3. Add regression tests.
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Checklist
|
||||
|
||||
* [ ] Closure env scanned.
|
||||
* [ ] Nested closures retained.
|
||||
* [ ] No regression in existing GC tests.
|
||||
|
||||
---
|
||||
|
||||
## Tests
|
||||
|
||||
1. Closure capturing another closure.
|
||||
2. Closure capturing heap object.
|
||||
3. Unreferenced closure collected.
|
||||
|
||||
---
|
||||
|
||||
## Junie Instructions
|
||||
|
||||
You MAY:
|
||||
|
||||
* Modify mark traversal.
|
||||
* Add tests.
|
||||
|
||||
You MUST NOT:
|
||||
|
||||
* Modify sweep policy.
|
||||
* Introduce compaction.
|
||||
|
||||
If unsure whether Value variants can embed HeapRef, STOP and ask.
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
GC correctly traverses closure environments under Model B semantics.
|
||||
|
||||
---
|
||||
|
||||
# PR-6.5 — Verifier Support for Closures (Model B)
|
||||
|
||||
## Briefing
|
||||
@ -147,4 +74,342 @@ If function metadata (arg_slots/ret_slots) is insufficient, STOP and request cla
|
||||
|
||||
## Definition of Done
|
||||
|
||||
Verifier fully supports closure creation and invocation under Model B semantics.
|
||||
Verifier fully supports closure creation and invocation under Model B semantics.
|
||||
|
||||
---
|
||||
|
||||
# PR-7 — Coroutines (Cooperative, Deterministic, No Mailbox)
|
||||
|
||||
Coroutines are the **only concurrency model** in the Prometeu VM.
|
||||
|
||||
This phase introduces:
|
||||
|
||||
* Cooperative scheduling
|
||||
* Deterministic execution order
|
||||
* SPAWN / YIELD / SLEEP
|
||||
* Switching only at safepoints (FRAME_SYNC)
|
||||
* Full GC integration
|
||||
|
||||
No mailbox. No message passing. No preemption.
|
||||
|
||||
Each PR below is self-contained and must compile independently.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.1 — Coroutine Heap Object
|
||||
|
||||
## Briefing
|
||||
|
||||
A coroutine is a suspended execution context with its own stack and call frames.
|
||||
|
||||
No mailbox is implemented in this phase.
|
||||
|
||||
## Target
|
||||
|
||||
Define `ObjectKind::Coroutine` with:
|
||||
|
||||
* `state: enum { Ready, Running, Sleeping, Finished, Faulted }`
|
||||
* `wake_tick: u64`
|
||||
* `stack: Vec<Value>`
|
||||
* `frames: Vec<CallFrame>`
|
||||
|
||||
Rules:
|
||||
|
||||
* Allocated in GC heap.
|
||||
* Addressed via `HeapRef`.
|
||||
* Stack and frames stored inside the coroutine object.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Coroutine heap object defined.
|
||||
* [ ] Stack/frames encapsulated.
|
||||
* [ ] No RC/HIP remnants.
|
||||
* [ ] Compiles and tests pass.
|
||||
|
||||
## Tests
|
||||
|
||||
* Allocate coroutine object.
|
||||
* Validate state transitions manually.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MAY extend heap object kinds.
|
||||
You MUST NOT implement scheduling yet.
|
||||
If stack representation is unclear, STOP and ask.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.2 — Deterministic Scheduler Core
|
||||
|
||||
## Briefing
|
||||
|
||||
Implement a cooperative deterministic scheduler.
|
||||
|
||||
## Target
|
||||
|
||||
Scheduler structure inside VM:
|
||||
|
||||
* `ready_queue: VecDeque<HeapRef>`
|
||||
* `sleeping: Vec<HeapRef>` (sorted or scanned by wake_tick)
|
||||
* `current: Option<HeapRef>`
|
||||
|
||||
Policy:
|
||||
|
||||
* FIFO for ready coroutines.
|
||||
* Sleeping coroutines move to ready when `wake_tick <= current_tick`.
|
||||
|
||||
No execution switching yet.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Scheduler struct exists.
|
||||
* [ ] Deterministic FIFO behavior.
|
||||
* [ ] No randomness.
|
||||
|
||||
## Tests
|
||||
|
||||
* Enqueue 3 coroutines and ensure dequeue order stable.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MAY add scheduler struct.
|
||||
You MUST NOT implement SPAWN/YIELD/SLEEP yet.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.3 — SPAWN Instruction
|
||||
|
||||
## Briefing
|
||||
|
||||
SPAWN creates a new coroutine and schedules it.
|
||||
|
||||
## Target
|
||||
|
||||
Introduce opcode:
|
||||
|
||||
`SPAWN fn_id, arg_count`
|
||||
|
||||
Semantics:
|
||||
|
||||
* Pop `arg_count` args.
|
||||
* Create new coroutine object.
|
||||
* Initialize its stack/frame with entry fn.
|
||||
* Push coroutine handle onto ready queue.
|
||||
|
||||
Current coroutine continues execution.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] SPAWN opcode exists.
|
||||
* [ ] Coroutine created.
|
||||
* [ ] Scheduled in ready queue.
|
||||
* [ ] No immediate context switch.
|
||||
|
||||
## Tests
|
||||
|
||||
* Spawn coroutine and verify it appears in ready queue.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MAY modify interpreter dispatch.
|
||||
You MUST NOT switch execution immediately.
|
||||
If entry frame layout unclear, STOP and ask.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.4 — YIELD Instruction
|
||||
|
||||
## Briefing
|
||||
|
||||
YIELD voluntarily gives up execution.
|
||||
|
||||
## Target
|
||||
|
||||
Opcode:
|
||||
|
||||
`YIELD`
|
||||
|
||||
Semantics:
|
||||
|
||||
* Current coroutine moves to end of ready queue.
|
||||
* Scheduler selects next coroutine at safepoint.
|
||||
|
||||
Switching must occur only at FRAME_SYNC.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] YIELD opcode implemented.
|
||||
* [ ] Current coroutine enqueued.
|
||||
* [ ] No mid-instruction switching.
|
||||
|
||||
## Tests
|
||||
|
||||
* Two coroutines yielding alternate deterministically.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MAY modify VM execution loop.
|
||||
You MUST NOT allow switching outside safepoints.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.5 — SLEEP Instruction
|
||||
|
||||
## Briefing
|
||||
|
||||
SLEEP suspends coroutine until a future tick.
|
||||
|
||||
## Target
|
||||
|
||||
Opcode:
|
||||
|
||||
`SLEEP duration_ticks`
|
||||
|
||||
Semantics:
|
||||
|
||||
* Remove coroutine from ready queue.
|
||||
* Set wake_tick.
|
||||
* Add to sleeping list.
|
||||
|
||||
At each FRAME_SYNC:
|
||||
|
||||
* Check sleeping coroutines.
|
||||
* Move ready ones to ready_queue.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] SLEEP implemented.
|
||||
* [ ] wake_tick respected.
|
||||
* [ ] Deterministic wake behavior.
|
||||
|
||||
## Tests
|
||||
|
||||
* Sleep and verify delayed execution.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MAY add tick tracking.
|
||||
You MUST NOT rely on real wall clock time.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.6 — Safepoint Integration
|
||||
|
||||
## Briefing
|
||||
|
||||
Execution switching must occur only at safepoints.
|
||||
|
||||
## Target
|
||||
|
||||
Switch coroutine only:
|
||||
|
||||
* After FRAME_SYNC
|
||||
* After instruction completes
|
||||
|
||||
Never mid-instruction.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Switch only at safepoints.
|
||||
* [ ] No reentrancy.
|
||||
|
||||
## Tests
|
||||
|
||||
* Stress test switching under heavy loops.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MUST enforce deterministic switching.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.7 — GC Integration
|
||||
|
||||
## Briefing
|
||||
|
||||
Suspended coroutines must be GC roots.
|
||||
|
||||
## Target
|
||||
|
||||
GC mark phase must traverse:
|
||||
|
||||
* All coroutine stacks
|
||||
* All coroutine frames
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] GC visits all suspended coroutines.
|
||||
* [ ] No leaked references.
|
||||
|
||||
## Tests
|
||||
|
||||
* Coroutine capturing heap object remains alive.
|
||||
* Finished coroutine collected.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MUST NOT change sweep policy.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.8 — Verifier Rules
|
||||
|
||||
## Briefing
|
||||
|
||||
Verifier must enforce coroutine safety.
|
||||
|
||||
## Target
|
||||
|
||||
Rules:
|
||||
|
||||
* YIELD forbidden inside invalid contexts (define minimal safe rule).
|
||||
* SPAWN argument validation.
|
||||
* SLEEP argument type validation.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Invalid YIELD rejected.
|
||||
* [ ] SPAWN arg mismatch rejected.
|
||||
|
||||
## Tests
|
||||
|
||||
* Invalid bytecode rejected.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
You MUST NOT weaken verifier.
|
||||
|
||||
---
|
||||
|
||||
# PR-7.9 — Determinism & Stress Tests
|
||||
|
||||
## Briefing
|
||||
|
||||
Validate deterministic behavior.
|
||||
|
||||
## Target
|
||||
|
||||
Tests must confirm:
|
||||
|
||||
* Same order across runs.
|
||||
* Sleep/wake order stable.
|
||||
* GC works with many coroutines.
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Deterministic order tests.
|
||||
* [ ] Stress test 100+ coroutines.
|
||||
|
||||
## Junie Rules
|
||||
|
||||
Tests must not depend on wall clock or randomness.
|
||||
|
||||
---
|
||||
|
||||
## Final Definition of Done
|
||||
|
||||
* Cooperative coroutines implemented.
|
||||
* Deterministic scheduling.
|
||||
* No mailbox.
|
||||
* GC and verifier fully integrated.
|
||||
* All tests pass.
|
||||
|
||||
@ -1,23 +1,4 @@
|
||||
vamos as PR7s todas em um unico canvas markdown ingles, devem ser auto contidas com briefing, alvo, checklist, test quando necessario e comandos do que a Junie pode ou nao fazer (Junie eh task operator nao arquiteta ou assume nada, questiona quando necessario).
|
||||
|
||||
7 — Coroutines (único modelo de concorrência, cooperativo)
|
||||
|
||||
7.1. Definir objeto Coroutine no heap: stack/frames próprios, status, wake time, mailbox/queue se existir.
|
||||
7.2. Definir scheduler determinístico: fila pronta, fila dormindo, política estável.
|
||||
7.3. Implementar SPAWN: criar coroutine + capturar entry + agendar.
|
||||
7.4. Implementar YIELD: ceder controle de forma cooperativa (somente em locais válidos).
|
||||
7.5. Implementar SLEEP: mover para fila dormindo até tick/time.
|
||||
7.6. Integrar execução/switch apenas em safepoints (FRAME_SYNC).
|
||||
7.7. Integrar GC roots: stacks suspensas e frames de todas as coroutines.
|
||||
7.8. Verifier: invariantes (ex.: proibir yield em contextos ilegais, validar spawn args/ret).
|
||||
7.9. Testes: determinismo (mesma ordem), sleep/wake, stress com GC + muitas coroutines.
|
||||
|
||||
8 — Tooling & test harness (para manter “JVM-grade”)
|
||||
|
||||
8.1. Disasm atualizado e confiável (roundtrip + snapshots).
|
||||
8.2. Harness de execução determinística para testes (seed fixo, time controlado).
|
||||
8.3. Suite de testes por camadas: bytecode (encode/decode), verifier, VM, GC, scheduler.
|
||||
8.4. “No legacy artifacts” check: busca por símbolos/nomes (retain/release/hip/gate/scope), módulos mortos removidos.
|
||||
vamos as PR9s todas em um unico canvas markdown ingles, devem ser auto contidas com briefing, alvo, checklist, test quando necessario e comandos do que a Junie pode ou nao fazer (Junie eh task operator nao arquiteta ou assume nada, questiona quando necessario).
|
||||
|
||||
9 — Hardening final e documentação do novo baseline
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user