[PERF] VM Allocation and Copy Pressure
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good

This commit is contained in:
bQUARKz 2026-04-20 09:09:24 +01:00
parent 8937963819
commit cd6bf6b313
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 71 additions and 531 deletions

View File

@ -1,4 +1,4 @@
{"type":"meta","next_id":{"DSC":29,"AGD":29,"DEC":19,"PLN":36,"LSN":35,"CLSN":1}}
{"type":"meta","next_id":{"DSC":29,"AGD":29,"DEC":19,"PLN":36,"LSN":36,"CLSN":1}}
{"type":"discussion","id":"DSC-0023","status":"done","ticket":"perf-full-migration-to-atomic-telemetry","title":"Agenda - [PERF] Full Migration to Atomic Telemetry","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["perf","runtime","telemetry"],"agendas":[{"id":"AGD-0021","file":"workflow/agendas/AGD-0021-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"decisions":[{"id":"DEC-0008","file":"workflow/decisions/DEC-0008-full-migration-to-atomic-telemetry.md","status":"accepted","created_at":"2026-04-10","updated_at":"2026-04-10"}],"plans":[{"id":"PLN-0007","file":"workflow/plans/PLN-0007-full-migration-to-atomic-telemetry.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}],"lessons":[{"id":"LSN-0028","file":"lessons/DSC-0023-perf-full-migration-to-atomic-telemetry/LSN-0028-converging-to-single-atomic-telemetry-source.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
{"type":"discussion","id":"DSC-0020","status":"done","ticket":"jenkins-gitea-integration","title":"Jenkins Gitea Integration and Relocation","created_at":"2026-04-07","updated_at":"2026-04-07","tags":["ci","jenkins","gitea"],"agendas":[{"id":"AGD-0018","file":"workflow/agendas/AGD-0018-jenkins-gitea-integration-and-relocation.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"decisions":[{"id":"DEC-0003","file":"workflow/decisions/DEC-0003-jenkins-gitea-strategy.md","status":"accepted","created_at":"2026-04-07","updated_at":"2026-04-07"}],"plans":[{"id":"PLN-0003","file":"workflow/plans/PLN-0003-jenkins-gitea-execution.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}],"lessons":[{"id":"LSN-0021","file":"lessons/DSC-0020-jenkins-gitea-integration/LSN-0021-jenkins-gitea-integration.md","status":"done","created_at":"2026-04-07","updated_at":"2026-04-07"}]}
{"type":"discussion","id":"DSC-0021","status":"done","ticket":"asset-entry-codec-enum-with-metadata","title":"Asset Entry Codec Enum Contract","created_at":"2026-04-09","updated_at":"2026-04-09","tags":["asset","runtime","codec","metadata"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"lessons/DSC-0021-asset-entry-codec-enum-contract/LSN-0024-string-on-the-wire-enum-in-runtime.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
@ -21,7 +21,7 @@
{"type":"discussion","id":"DSC-0026","status":"done","ticket":"render-all-scene-cache-and-camera-integration","title":"Integrate render_all with Scene Cache and Camera","created_at":"2026-04-14","updated_at":"2026-04-18","tags":["gfx","runtime","render","camera","scene"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0031","file":"lessons/DSC-0026-render-all-scene-cache-and-camera-integration/LSN-0031-frame-composition-belongs-above-the-render-backend.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]}
{"type":"discussion","id":"DSC-0027","status":"done","ticket":"frame-composer-public-syscall-surface","title":"Agenda - FrameComposer Public Syscall Surface","created_at":"2026-04-17","updated_at":"2026-04-18","tags":["gfx","runtime","syscall","abi","frame-composer","scene","camera","sprites"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0032","file":"lessons/DSC-0027-frame-composer-public-syscall-surface/LSN-0032-public-abi-must-follow-the-canonical-service-boundary.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]}
{"type":"discussion","id":"DSC-0028","status":"done","ticket":"deferred-overlay-and-primitive-composition","title":"Deferred Overlay and Primitive Composition over FrameComposer","created_at":"2026-04-18","updated_at":"2026-04-18","tags":["gfx","runtime","render","frame-composer","overlay","primitives","hud"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0033","file":"lessons/DSC-0028-deferred-overlay-and-primitive-composition/LSN-0033-debug-primitives-should-be-a-final-overlay-not-part-of-game-composition.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]}
{"type":"discussion","id":"DSC-0014","status":"in_progress","ticket":"perf-vm-allocation-and-copy-pressure","title":"Agenda - [PERF] VM Allocation and Copy Pressure","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[{"id":"AGD-0013","file":"workflow/agendas/AGD-0013-perf-vm-allocation-and-copy-pressure.md","status":"accepted","created_at":"2026-03-27","updated_at":"2026-04-20","_override_reason":"User explicitly requested emitting a decision from the resolved agenda in this turn."}],"decisions":[{"id":"DEC-0018","file":"workflow/decisions/DEC-0018-vm-allocation-and-copy-pressure-baseline.md","status":"in_progress","created_at":"2026-04-20","updated_at":"2026-04-20","ref_agenda":"AGD-0013","_override_reason":"User explicitly requested emitting and then accepting the decision, followed by plan generation."}],"plans":[{"id":"PLN-0033","file":"PLN-0033-vm-hot-path-ownership-and-string-copy-pressure.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0018"]},{"id":"PLN-0034","file":"PLN-0034-internal-allocation-evidence-and-hot-path-measurement.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0018"]},{"id":"PLN-0035","file":"PLN-0035-runtime-spec-wording-for-materialization-vs-copy-pressure.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0018"]}],"lessons":[]}
{"type":"discussion","id":"DSC-0014","status":"done","ticket":"perf-vm-allocation-and-copy-pressure","title":"Agenda - [PERF] VM Allocation and Copy Pressure","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0035","file":"lessons/DSC-0014-perf-vm-allocation-and-copy-pressure/LSN-0035-first-materialization-is-not-the-same-as-hot-path-copy-pressure.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20"}]}
{"type":"discussion","id":"DSC-0015","status":"open","ticket":"perf-cartridge-boot-and-program-ownership","title":"Agenda - [PERF] Cartridge Boot and Program Ownership","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0014","file":"workflow/agendas/AGD-0014-perf-cartridge-boot-and-program-ownership.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0016","status":"done","ticket":"tilemap-empty-cell-vs-tile-id-zero","title":"Tilemap Empty Cell vs Tile ID Zero","created_at":"2026-03-27","updated_at":"2026-04-09","tags":[],"agendas":[{"id":"AGD-0015","file":"workflow/agendas/AGD-0015-tilemap-empty-cell-vs-tile-id-zero.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-09"}],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0022","file":"lessons/DSC-0016-tilemap-empty-cell-semantics/LSN-0022-tilemap-empty-cell-convergence.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
{"type":"discussion","id":"DSC-0017","status":"done","ticket":"asset-entry-metadata-normalization-contract","title":"Asset Entry Metadata Normalization Contract","created_at":"2026-03-27","updated_at":"2026-04-09","tags":[],"agendas":[{"id":"AGD-0016","file":"workflow/agendas/AGD-0016-asset-entry-metadata-normalization-contract.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-09"}],"decisions":[{"id":"DEC-0004","file":"workflow/decisions/DEC-0004-asset-entry-metadata-normalization-contract.md","status":"accepted","created_at":"2026-04-09","updated_at":"2026-04-09"}],"plans":[],"lessons":[{"id":"LSN-0023","file":"lessons/DSC-0017-asset-metadata-normalization/LSN-0023-typed-asset-metadata-helpers.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}

View File

@ -0,0 +1,69 @@
---
id: LSN-0035
ticket: perf-vm-allocation-and-copy-pressure
title: First Materialization Is Not the Same as Hot-Path Copy Pressure
created: 2026-04-20
tags: [runtime, vm, performance, strings, allocation, telemetry]
---
## Context
`DSC-0014` started from a broad performance complaint around VM allocation and string-heavy execution. The tempting response would have been to chase "zero alloc everywhere" or to reopen public VM semantics around globals and strings.
The completed work converged on a narrower and more durable rule: the real optimization boundary is not "all allocation is bad", but "first materialization cost must be separated from repeated hot-path copy pressure".
That distinction shaped three concrete outcomes:
- immutable string payloads are now shared instead of recopied in common paths such as constant-pool use and `GET_GLOBAL`;
- internal telemetry records heap-allocation and string-materialization evidence without turning those counters into certification policy;
- the published specs now explain that zero-allocation happy paths are engineering targets, not guest-visible compatibility promises.
## Key Decisions
### Allocation Baseline for Strings and Globals (`DEC-0018`)
**What:**
PROMETEU keeps strings in the public VM language surface, but the runtime treats string payload as potentially expensive. Hardcoded strings may materialize once during build/load, runtime-created strings may materialize when a new value is semantically created, and `GET_GLOBAL` keeps its public behavior while avoiding unnecessary repeated payload copying internally.
**Why:**
The original hotspot was not the existence of strings. It was the fact that already-materialized payloads were being cloned repeatedly on hot paths. Fixing that internally is cheaper and safer than redefining the guest ABI.
**Trade-offs:**
String concatenation still creates a new string when the language semantics require it. The runtime gives up the illusion of "free strings", but preserves the correct public model while removing redundant copies that were never semantically required.
## Patterns and Algorithms
- Separate semantic allocation from accidental copying:
A new value may require materialization. Re-reading or forwarding an existing value usually should not.
- Share immutable payloads aggressively:
If a payload is immutable and already materialized, shared ownership is often the cheapest way to preserve public semantics while removing internal copy pressure.
- Keep public semantics stable, move optimization inward:
`GET_GLOBAL` did not need new meaning. The fix belonged in representation and ownership, not in the opcode contract.
- Keep engineering evidence internal unless explicitly promoted:
The runtime now records internal allocation evidence, but that evidence is not automatically a certification rule or ABI promise.
- Make internal counters robust under parallel tests:
Process-global counters can produce false failures in concurrent test runs. Internal evidence for runtime behavior should be scoped so unrelated work cannot contaminate the result.
## Pitfalls
- Do not treat every allocation as equivalent.
A first materialization that creates a semantically new value is not the same problem as cloning an old value on every hot-path access.
- Do not promote engineering goals to public contracts by accident.
"Zero alloc on the happy path" is useful for implementation discipline, but dangerous if readers start assuming it is a certification guarantee.
- Do not optimize strings by changing surface semantics prematurely.
The pressure here was internal. Reopening the guest ABI first would have increased scope and risk without solving the actual hotspot cleanly.
- Do not use shared global counters for per-test behavioral evidence.
The failed coverage run showed that instrumentation design matters as much as the metric itself.
## Takeaways
- The right performance question is often "where is the repeated cost?" rather than "where is any cost at all?"
- Immutable payload sharing is a strong default when public semantics must remain stable and hot-path copies are the real issue.
- Internal telemetry should help engineering decisions without silently becoming a product contract.

View File

@ -1,123 +0,0 @@
---
id: AGD-0013
ticket: perf-vm-allocation-and-copy-pressure
title: Agenda - [PERF] VM Allocation and Copy Pressure
status: accepted
created: 2026-03-27
resolved: 2026-04-20
decision: DEC-0018
tags: []
---
# Agenda - [PERF] VM Allocation and Copy Pressure
## Problema
O core da VM ainda aloca e clona demais em alguns caminhos relevantes, especialmente quando strings entram no fluxo.
Hoje `ADD` com string usa `format!`/`to_string()`, `GET_GLOBAL` clona valores e varios caminhos de erro montam strings dinamicas.
## Dor
- churn de heap reduz o teto de throughput da VM.
- carts que abusam de string e estado global pagam custo cedo demais.
- hardware barato sente alocacao repetitiva de forma desproporcional.
## Hotspots Atuais
- [virtual_machine.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-vm/src/virtual_machine.rs#L635)
- [virtual_machine.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-vm/src/virtual_machine.rs#L870)
- [tick.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs#L111)
## Alvo da Discussao
Definir o nivel de disciplina de alocacao/copia exigido do core da VM no baseline do console.
## O Que Precisa Ser Definido
1. Prioridade dos casos.
Fechar quais caminhos sao realmente hot:
- opcodes de string;
- acesso a globals;
- faults;
- logs.
2. Estrategia de ownership.
Decidir onde vale introduzir:
- borrow temporario;
- small-string strategy;
- copy-on-write;
- intern/cache de strings.
3. Meta de alocacao.
Definir se o projeto quer:
- zero alloc no frame loop feliz;
- alloc rara e explicita;
- apenas reducao oportunista.
4. Instrumentacao.
Decidir como medir alocacao sem transformar a VM em microbenchmark artificial.
## Open Questions de Arquitetura
1. Strings sao citizen de primeira classe no fantasy console ou recurso conveniente mas caro?
2. Vale endurecer a linguagem/ABI para reduzir alocacao implicitamente?
3. Caminhos de fault precisam ser maximizados para desempenho ou apenas os caminhos felizes?
## Sugestoes para Fechar as Open Questions
1. Strings devem ser tratadas como recurso suportado, mas caro por definicao no baseline.
A VM hoje modela `Value::String(String)` como valor inline clonavel e o opcode `ADD` concatena via `format!`, entao o custo de copia ja faz parte do comportamento real do runtime. A sugestao nao e prometer "string cheap" na semantica base, e sim preservar string como capacidade legitima da linguagem enquanto o baseline otimiza os caminhos quentes que nao dependem de formatacao dinamica. Strings hardcoded podem ser materializadas uma vez na constant pool durante build/load; strings dinamicas podem ser materializadas em storage dinamico durante runtime. Em ambos os casos, a primeira materializacao e aceitavel. O que esta fora da meta e recopiar payload de string repetidamente no caminho quente depois dessa primeira materializacao.
2. Vale endurecer o contrato operacional, mas nao a expressividade publica da linguagem neste primeiro passo.
A recomendacao e evitar uma mudanca ampla de ABI agora. Em vez disso:
- o caminho feliz do frame loop deve evitar alocacao implicita quando opera sobre numeros, handles e valores ja materializados;
- strings dinamicas devem continuar permitidas, mas tratadas como custo explicito de runtime;
- globals devem privilegiar handles e valores baratos no caminho quente, sem introduzir nova semantica publica para `GET_GLOBAL`;
- qualquer estrategia mais invasiva, como intern global, copy-on-write ou heap-string canonica, deve nascer como decisao posterior se a telemetria provar necessidade.
3. Fault paths nao precisam ser maximizados como se fossem caminho quente.
A recomendacao e exigir que traps e faults permanencam corretos, deterministas e legiveis para tooling host-owned, mas sem contaminar o caminho feliz com formatacao defensiva ou montagem rica de strings em toda instrucao. O investimento principal deve ir para opcode dispatch, acesso a globals e operacoes repetidas por frame; faults podem aceitar custo maior desde que esse custo seja pago so na excecao.
## Sugestao / Recomendacao
Fechar esta agenda com a seguinte linha:
- baseline alvo: "happy path com alloc rara e explicita", nao "zero alloc absoluto";
- prioridade imediata: reduzir copia/alocacao em `GET_GLOBAL` e nas operacoes de string mais frequentes do loop;
- strings constantes: custo de materializacao pago uma vez no carregamento/constant pool e depois preferencialmente referenciadas;
- strings dinamicas: custo inicial de criacao aceito em runtime, mas sem clones implicitos repetidos apos a primeira materializacao;
- `GET_GLOBAL`: nenhuma nova semantica publica; a reducao de copia deve vir de representacao interna e ownership dos tipos caros;
- ownership baseline: manter valores triviais por copia e mover payloads caros para representacoes por handle quando houver prova de pressao suficiente para justificar a complexidade;
- faults/logs: preservar clareza e determinismo, aceitando custo fora do caminho feliz;
- meta interna de engenharia: perseguir `zero alloc` no caminho feliz numerico e nos acessos quentes ja materializados, sem publicar isso como metrica de certificacao;
- instrumentacao canonica: medir `heap_used_bytes`, frequencia de GC e contagem de logs/faults no fim do frame, mantendo contadores de alocacao como metrica interna de engenharia, sem transformar o dispatch em microbenchmark intrusivo.
## Perguntas em Aberto
- Nenhuma no nivel arquitetural atual. A agenda pode ser encerrada quando esta direcao for promovida para decisao normativa.
## Dependencias
- `docs/specs/runtime/02a-vm-values-and-calling-convention.md`
- `docs/specs/runtime/03-memory-stack-heap-and-allocation.md`
- `docs/specs/runtime/10-debug-inspection-and-profiling.md`
## Criterio de Saida Desta Agenda
Pode virar PR quando houver decisao escrita sobre:
- caminho quente prioritario para desengordurar;
- meta minima de alocacao/copia da VM;
- estrategia de ownership para strings/values;
- instrumentacao canonica para medir regressao.
## Resolucao Proposta
- Strings continuam parte legitima da linguagem, mas sao tratadas como recurso potencialmente caro no baseline.
- Strings hardcoded podem pagar custo de materializacao uma vez no carregamento/constant pool.
- Strings dinamicas podem pagar custo inicial de criacao em runtime.
- A arquitetura deve evitar recopia de payload apos a primeira materializacao sempre que o caminho quente puder operar por referencia, handle ou ownership interno mais barato.
- `GET_GLOBAL` nao ganha nova semantica publica; qualquer reducao de copia deve vir de mudancas internas de representacao e processo.
- `Zero alloc no caminho feliz` e meta interna de engenharia do runtime, nao criterio publicado de certificacao.
- Faults e logs permanecem corretos e legiveis, mas nao dirigem a otimizacao principal.

View File

@ -1,112 +0,0 @@
---
id: DEC-0018
ticket: perf-vm-allocation-and-copy-pressure
title: Decision - [PERF] VM Allocation and Copy Pressure Baseline
status: in_progress
created: 2026-04-20
accepted: 2026-04-20
agenda: AGD-0013
plans: [PLN-0033, PLN-0034, PLN-0035]
tags: [perf, runtime, vm, memory, strings, allocation]
---
# Status
Accepted on 2026-04-20 and now in progress through linked implementation plans.
# Contexto
O core da VM ainda apresenta churn de alocacao e copia em caminhos relevantes, em especial:
- concatenacao de string em `ADD`;
- clone de valores em `GET_GLOBAL`;
- montagem de strings dinamicas em faults e logs.
O estado atual do runtime permite strings como parte legitima da linguagem, mas a representacao pratica ainda empurra payload caro para copias repetidas em alguns caminhos. A discussao da agenda fechou que o problema arquitetural nao e eliminar toda alocacao, e sim impedir recopia desnecessaria depois da primeira materializacao dos dados.
# Decisao
1. Strings SHALL remain part of the supported VM language surface.
2. The runtime MUST treat string payload as potentially expensive in the baseline performance model.
3. Hardcoded strings MAY pay one materialization cost during build/load into the constant pool, and runtime hot paths SHOULD preferentially reference that already-materialized representation.
4. Dynamically produced strings MAY pay an initial runtime materialization cost in dynamic storage, but the runtime MUST NOT introduce repeated implicit payload copies on hot paths unless the operation semantically requires a new string value.
5. `GET_GLOBAL` SHALL NOT gain new public semantics. Any reduction in copy pressure MUST come from internal representation, ownership strategy, or storage process, not from a guest-visible ABI change.
6. The baseline engineering target for the VM happy path SHALL be zero allocation on numeric and already-materialized hot paths.
7. That zero-allocation target SHALL remain an internal engineering objective and MUST NOT be published as a certification contract or guest-facing compatibility guarantee.
8. Fault and log paths MUST remain correct, deterministic, and readable, but they SHALL NOT drive the primary optimization strategy for the VM hot path.
# Rationale
Esta decisao fecha tres tensoes da agenda:
- preserva string como capacidade real da linguagem, sem prometer que string e "cheap" por definicao;
- evita reabrir a ABI publica apenas para aliviar pressao de copia em um ponto interno da VM;
- separa meta de engenharia de contrato normativo externo.
O custo inevitavel e a primeira materializacao:
- string hardcoded entra na constant pool em build/load;
- string dinamica nasce em runtime.
O custo evitavel e a recopia posterior do payload em caminhos quentes que ja deveriam operar sobre valor materializado, handle ou ownership mais barato.
Essa linha tambem mantem a arquitetura coerente com as specs atuais:
- valores triviais continuam baratos por copia;
- objetos com identidade e lifetime relevante continuam candidatos naturais a representacao por handle;
- tooling host-owned continua podendo observar heap e pressao de memoria sem que a VM precise transformar cada opcode em um ponto de instrumentacao intrusivo.
# Invariantes / Contrato
- The VM MUST preserve the public meaning of string values as guest-visible values.
- The VM MUST NOT change the public behavior of `GET_GLOBAL` as part of this decision.
- The runtime MUST distinguish first materialization from repeated implicit copy when evaluating optimization work.
- Constant-pool-backed strings SHOULD be treated as already materialized data for runtime access purposes.
- Runtime-created strings MAY allocate once at creation time.
- Hot-path operations over numeric values, handles, and already-materialized values SHOULD converge toward zero allocation.
- Any future move to heap-backed canonical strings, interning, copy-on-write, or similar global representation changes MUST be proposed in a separate decision if it changes operational constraints or implementation complexity materially.
- Fault generation and logs MAY allocate outside the happy path, provided they remain deterministic and do not leak into hot-loop design as a hidden steady-state cost.
# Impactos
- Spec
- No immediate guest-visible ABI change is required.
- Existing memory/value/debug specs remain directionally compatible.
- A follow-up plan may update wording in runtime specs to distinguish first materialization from repeated copy pressure more explicitly.
- Runtime
- Optimization work MUST target internal ownership and representation first.
- `GET_GLOBAL` copy pressure MUST be addressed without semantic drift.
- String-heavy `ADD` and similar paths become explicit hot-path optimization candidates.
- Host
- Certification and tooling remain host-owned.
- Allocation counters may exist as engineering telemetry, but they are not promoted to public certification criteria by this decision.
- Firmware / Tooling
- No cartridge author contract changes are introduced.
- Compiler/loader/tooling MAY continue to materialize hardcoded strings into constant-pool storage.
# Referencias
- `AGD-0013`
- `docs/specs/runtime/02a-vm-values-and-calling-convention.md`
- `docs/specs/runtime/03-memory-stack-heap-and-allocation.md`
- `docs/specs/runtime/10-debug-inspection-and-profiling.md`
- `crates/console/prometeu-vm/src/virtual_machine.rs`
- `crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs`
# Propagacao Necessaria
- Create a plan that separates:
- hot-path ownership work in the VM core;
- telemetry/internal measurement work;
- any optional spec wording cleanup.
- Audit `GET_GLOBAL` and string-producing opcode paths under this contract.
- Define implementation evidence for "zero alloc on happy path" as internal profiling evidence rather than certification output.
- Do not reopen public ABI or language semantics during plan execution unless new evidence shows the current contract is insufficient.
# Revision Log
- 2026-04-20: Initial draft from AGD-0013.
- 2026-04-20: Accepted and linked to PLN-0033, PLN-0034, and PLN-0035.

View File

@ -1,108 +0,0 @@
---
id: PLN-0033
ticket: perf-vm-allocation-and-copy-pressure
title: Plan - VM Hot Path Ownership and String Copy Pressure
status: done
created: 2026-04-20
completed: 2026-04-20
tags: [perf, runtime, vm, memory, strings]
---
## Briefing
Implement the runtime-core portion of `DEC-0018` by reducing repeated string payload copies and hot-path allocation pressure without changing guest-visible semantics.
## Decisions de Origem
- `DEC-0018` - VM Allocation and Copy Pressure Baseline
## Alvo
Change the VM core so that hot paths over numeric values and already-materialized values converge toward zero allocation, while preserving the public semantics of string values and `GET_GLOBAL`.
## Escopo
### Included
- VM value representation and ownership audit for hot paths.
- `GET_GLOBAL` copy-pressure reduction without semantic drift.
- String-producing opcode hot-path changes, especially `ADD`.
- Unit and focused integration coverage for unchanged semantics.
### Excluded
- Public ABI changes.
- Certification or host-facing telemetry policy changes.
- Broad speculative string interning or copy-on-write rollout unless directly required by a concrete implementation step.
## Fora de Escopo
- Cartridge language changes.
- Host debugger protocol changes.
- General fault/log path rewrites beyond keeping them isolated from hot-path work.
## Plano de Execucao
### Step 1 - Audit current hot-path ownership
**What:** Identify the exact VM operations that still clone or allocate on already-materialized hot paths.
**How:** Review `Value`, `GET_GLOBAL`, `ADD`, related stack helpers, and any nearby string coercion paths; classify each site as unavoidable first materialization versus avoidable repeated copy.
**File(s):** `crates/console/prometeu-bytecode/src/value.rs`, `crates/console/prometeu-vm/src/virtual_machine.rs`
### Step 2 - Rework internal representation/ownership for expensive payloads
**What:** Introduce the smallest internal representation change needed to avoid repeated payload copies for expensive values.
**How:** Prefer internal ownership changes that preserve guest-visible semantics. If strings or other expensive payloads need to move behind handles or equivalent internal storage, keep the public value meaning unchanged and constrain the change to runtime-core internals.
**File(s):** `crates/console/prometeu-bytecode/src/value.rs`, `crates/console/prometeu-vm/src/heap.rs`, `crates/console/prometeu-vm/src/object.rs`, `crates/console/prometeu-vm/src/virtual_machine.rs`
### Step 3 - Fix `GET_GLOBAL` without semantic change
**What:** Remove avoidable repeated copy pressure from `GET_GLOBAL`.
**How:** Keep the observable contract identical while changing retrieval/storage internals so already-materialized expensive payloads are not recopied on each hot-path access.
**File(s):** `crates/console/prometeu-vm/src/virtual_machine.rs`
### Step 4 - Optimize string-producing opcode paths
**What:** Reduce repeated allocation/copy pressure in string-producing operations, starting with `ADD`.
**How:** Separate true new-string creation from repeated cloning of existing payloads. Ensure any operation that semantically creates a new string still does so correctly, while avoiding extra transient allocations around existing materialized values.
**File(s):** `crates/console/prometeu-vm/src/virtual_machine.rs`, related helper modules if introduced
### Step 5 - Preserve semantic coverage
**What:** Prove semantics did not change while ownership internals did.
**How:** Add/update tests for constants, dynamic strings, globals, arithmetic/string `ADD`, and edge cases where strings cross stack/global boundaries.
**File(s):** `crates/console/prometeu-vm/src/virtual_machine.rs`, VM test modules
## Criterios de Aceite
- `GET_GLOBAL` keeps its public semantics unchanged.
- Hot-path access to already-materialized expensive values no longer performs avoidable repeated payload copies.
- Numeric hot paths remain allocation-free.
- String operations that truly create a new string remain correct and deterministic.
- VM tests cover constant-pool strings, runtime-created strings, and globals under the new ownership model.
## Tests / Validacao
### Unit Tests
- Value/ownership tests for expensive payload movement or referencing.
- VM opcode tests for `GET_GLOBAL`, `SET_GLOBAL`, and string `ADD`.
### Integration Tests
- Small bytecode programs that read globals repeatedly and mix numeric/string paths.
### Manual Verification
- Review allocation-sensitive hotspots in the final implementation to confirm repeated copies were removed rather than merely relocated.
## Riscos
- Internal representation changes may ripple into GC/root traversal.
- A partial fix may hide copies in helper methods rather than eliminate them.
- Over-optimizing strings could accidentally change guest-visible behavior if semantic boundaries are not defended by tests.
## Dependencies
- `DEC-0018`
- Existing VM heap/object/root traversal contracts

View File

@ -1,98 +0,0 @@
---
id: PLN-0034
ticket: perf-vm-allocation-and-copy-pressure
title: Plan - Internal Allocation Evidence and Hot Path Measurement
status: done
created: 2026-04-20
completed: 2026-04-20
tags: [perf, runtime, telemetry, allocation, engineering]
---
## Briefing
Add internal engineering evidence for `DEC-0018` so the team can verify progress toward zero allocation on the happy path without turning that metric into a certification contract.
## Decisions de Origem
- `DEC-0018` - VM Allocation and Copy Pressure Baseline
## Alvo
Produce low-intrusion internal measurement for allocation and copy pressure that can guide implementation and regression detection during engineering work.
## Escopo
### Included
- Internal-only allocation counters or equivalent evidence mechanisms.
- Measurement points around VM execution slices and/or frame boundaries.
- Regression-oriented tests or harnesses that assert expected internal evidence in happy-path scenarios.
### Excluded
- New public certification outputs.
- Guest-visible profiling ABI changes.
- Heavy per-opcode instrumentation that distorts the hot path.
## Fora de Escopo
- Rewriting the full telemetry model.
- Publishing allocation counts to cartridge authors as normative behavior.
## Plano de Execucao
### Step 1 - Define internal evidence model
**What:** Choose the minimal evidence surface that proves whether happy-path execution allocates.
**How:** Prefer counters or snapshots that can distinguish first materialization from steady-state hot-path execution. Tie the evidence to engineering diagnostics only.
**File(s):** `crates/console/prometeu-hal/src/telemetry.rs`, `crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs`, internal runtime/telemetry helpers as needed
### Step 2 - Implement low-intrusion collection
**What:** Add instrumentation with bounded overhead.
**How:** Record allocation evidence at frame or execution-slice boundaries rather than on every operation when possible. Keep the instrumentation isolated from guest-visible contracts.
**File(s):** `crates/console/prometeu-vm/src/heap.rs`, `crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs`, related telemetry modules
### Step 3 - Define regression scenarios
**What:** Create deterministic scenarios that express the engineering target.
**How:** Add tests or bench-like checks for numeric happy paths, already-materialized constant strings, and runtime-created string paths after first materialization.
**File(s):** runtime/VM test modules; dedicated internal telemetry tests if appropriate
### Step 4 - Document how evidence is used
**What:** Clarify that this evidence is an engineering metric, not certification policy.
**How:** Update inline docs or internal notes near the measurement code so future work does not accidentally publish the metric as a hard contract.
**File(s):** relevant telemetry/runtime modules
## Criterios de Aceite
- Engineers can observe whether selected happy-path scenarios allocate.
- The measurement surface distinguishes internal engineering evidence from public certification output.
- Instrumentation overhead stays bounded and does not require intrusive per-opcode tracing.
- Regression checks exist for at least one numeric path and one already-materialized string path.
## Tests / Validacao
### Unit Tests
- Counter/reset/snapshot correctness for internal allocation evidence.
### Integration Tests
- Runtime scenarios that verify zero-allocation expectations on steady-state happy paths.
### Manual Verification
- Inspect final measurement plumbing to confirm it is not exposed as public certification policy.
## Riscos
- Instrumentation may accidentally become hot-path overhead.
- Counters may undercount or overcount if first materialization is not separated from steady-state execution.
- Internal metrics may be misread later as external compatibility guarantees unless explicitly documented.
## Dependencies
- `DEC-0018`
- Existing runtime telemetry boundary

View File

@ -1,88 +0,0 @@
---
id: PLN-0035
ticket: perf-vm-allocation-and-copy-pressure
title: Plan - Runtime Spec Wording for Materialization vs Copy Pressure
status: done
created: 2026-04-20
completed: 2026-04-20
tags: [spec, runtime, memory, strings, perf]
---
## Briefing
Apply the minimal spec wording cleanup implied by `DEC-0018` so published runtime docs distinguish first materialization cost from repeated hot-path copy pressure without changing the public ABI.
## Decisions de Origem
- `DEC-0018` - VM Allocation and Copy Pressure Baseline
## Alvo
Update canonical runtime specs so the published memory/value/debug model reflects the accepted architectural framing behind the implementation work.
## Escopo
### Included
- Wording updates in runtime specs for values, memory/allocation, and debug/profiling boundaries.
- Clarifications that zero-allocation on the happy path is an engineering target, not certification policy.
### Excluded
- Any new guest-visible ABI rules.
- Broad documentation rewrite unrelated to `DEC-0018`.
## Fora de Escopo
- Lessons material.
- Cartridge author migration guides.
## Plano de Execucao
### Step 1 - Identify exact normative gaps
**What:** Locate wording that currently conflates all allocation cost with hot-path copy pressure or leaves the first-materialization distinction implicit.
**How:** Review the accepted decision against the current value, memory, and debug chapters and capture only the gaps required to keep docs aligned with implementation intent.
**File(s):** `docs/specs/runtime/02a-vm-values-and-calling-convention.md`, `docs/specs/runtime/03-memory-stack-heap-and-allocation.md`, `docs/specs/runtime/10-debug-inspection-and-profiling.md`
### Step 2 - Update normative text
**What:** Clarify constant-pool materialization, runtime materialization, and repeated-copy pressure boundaries.
**How:** Add concise normative wording that preserves the existing ABI while making clear that internal engineering may target zero allocation on happy paths without publishing that as certification policy.
**File(s):** `docs/specs/runtime/02a-vm-values-and-calling-convention.md`, `docs/specs/runtime/03-memory-stack-heap-and-allocation.md`, `docs/specs/runtime/10-debug-inspection-and-profiling.md`
### Step 3 - Cross-check consistency
**What:** Ensure the updated docs stay aligned with the accepted decision and with any implementation evidence introduced under linked plans.
**How:** Review terminology across the edited chapters and confirm no text implies a guest-visible ABI or certification promise that the decision explicitly rejected.
**File(s):** same as above
## Criterios de Aceite
- Runtime specs distinguish first materialization from repeated copy pressure.
- Specs do not imply a public ABI change for `GET_GLOBAL` or strings.
- Specs do not promote zero-allocation happy-path behavior to certification policy.
- Edited docs remain consistent across values, memory, and profiling chapters.
## Tests / Validacao
### Unit Tests
- Not applicable.
### Integration Tests
- Not applicable.
### Manual Verification
- Read the edited chapters side by side with `DEC-0018` and confirm that every new normative statement maps directly to the accepted decision.
## Riscos
- Specs may drift ahead of implementation details if wording is too specific.
- Overstating performance goals in normative docs may accidentally create an external compatibility promise.
## Dependencies
- `DEC-0018`