Each per-field cell getter wrapped its own Arena.ofConfined() (a native
alloc/free plus session bookkeeping) to hold a few output bytes. With ~6
downcalls per cell that is tens of thousands of confined arenas per frame on a
full screen, which profiling in jprototerm pinned as ~6-7ms/frame and the
dominant render cost.
Allocate the scalar out-segments (int, bool, color, style) plus a growable
graphemes buffer once per snapshot in a single Scratch, confined to the
single marshalling thread, and thread it through the cell getters. Also drop a
redundant List.copyOf of the per-row cell list (RenderRow's constructor already
makes the immutable copy) and reuse a shared empty-codepoints array.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>