--- 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.