nx_jpegmem_gate.nx
buildroot/runtime/nx_jpegmem_gate.nx
about
nx_jpegmem_gate.nx -- THE JPEG DECODE MEMORY GATE: repeated decodes are FLAT-RSS and overrun-free.
Subject: _offc/nx_jpegmem_probe.elf forked over a REAL banked donor texture (never a synthetic
stand-in -- the asset class that exposed the defect IS the donor corpus). The probe decodes the
same jpeg N times in one process, prints VmRSS after each round, and surfaces any ARENA-OVERRUN
diagnostic from the allocator canary.
WHY THIS GATE EXISTS (measured 2026-08-23, nx_jpegmem_probe): nx_jpeg_idct_8x8 and the zigzag
inverse-table builders each allocated 512 B PER 8x8 BLOCK; 512 > NXA_SMALL_MAX routes past the
bump arena to the page allocator, so every block cost a 4 KiB page nothing freed --
3,203,232 kB RSS growth PER 4096x4096 decode (it OOM-killed a build VM). Separately,
NX_JPEG_DEC_CTX_BYTES=112 under-sized the 15-field NxJpegDecCtx, so every decode wrote 8 B past
its context allocation (canary: ARENA-OVERRUN prev_alloc_size=112). After the root fixes the
probe measures ~50 kB/round, bounded by bump-arena chunk growth.
FAIL DIRECTION IS PROVEN BY MUTATION, not by a synthetic neg-control tooth: nx_gate_bite with
nx_jpeg_idct.nx as the mutated source and nx_jpegmem_probe as the rebuilt subject restores the
per-block allocation and the flat-rss tooth MUST go RED (bite receipt in the ship record).
NOT ROSTER-ADMITTED on purpose: a real decode takes seconds and the roster beat kills at
~1.8 s (the voxchunk precedent) -- run via the job lane / ship loop.
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_gate_verdict.nxnx_gatekit_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 26 | const JMG_ELF: *u8 = "_offc/nx_jpegmem_probe.elf" |
| 27 | const JMG_FIXTURE: *u8 = "knowledge/rigcorpus/fbx/textures/toon3d8/Ludovisions_Toon3D8_Eyes_D.jpg" |
| 28 | const JMG_ROUNDS_ARG: *u8 = "3" |
| 29 | const JMG_ROUNDS: i64 = 3 |
| 33 | const JMG_CAP: i64 = 65536 |
| 36 | const JMG_MS: i64 = 60000 |
| 38 | const JMG_SOI0: i64 = 255 |
| 39 | const JMG_SOI1: i64 = 216 |
functions
| 42 | func jmg_find(buf: *u8, n: i64, from: i64, t: *u8) -> i64 called by 1: main |
| 59 | func jmg_num(buf: *u8, n: i64, i: i64) -> i64 called by 1: main |
| 76 | func main(argc: i64, argv: *i64) -> i64 |