~bigbes/tarantool-protobuf: b93adbf0

codec: emit per-descriptor encode body for monomorphic dispatch (21d)

The runtime-mode encode loop in codec.encode_message iterated
desc.fields and called `writer(data, out)` per field. Each iteration
saw a different closure, making the call site megamorphic from the
JIT's view: trace topology fragmented into 25 stops for Person_encode
vs full mode's 8 (~3x).

compile_encode_body emits a generated function at pb.finalize_message
time with one literal call site per field, all closing over a single
`_u` table upvalue indexed by constant int. TGETI on a stable array
with a literal key specializes on trace just like direct upvalue
access — and dodges LuaJIT's 60-upvalue function limit, which
TestAllTypesProto2 (~140 fields) would otherwise hit.

Trace topology (bench/jit_trace.lua):
  runtime/Person_encode             25 -> 10  (full 8)
  runtime/Person_encode multi-byte  18 ->  7  (full 6)
  runtime/Address_encode             6 ->  5  (full 2)
  runtime/Cardinality required       6 ->  2  (full 2)

Encode throughput (hello.Person, bench/bench.lua):
  10B    10.9 -> 15.5 MB/s  (+42%)
  100B  101.1 -> 144.4 MB/s (+43%)
  1KB   170.5 -> 183.5 MB/s (+8%)
  10KB  355.5 -> 362.3 MB/s (+2%)
  100KB 373.5 -> 407.6 MB/s (+9%)

Decode untouched. Full mode unaffected (its inline _encode doesn't
go through codec.encode_message). 752+1043 tests pass; examples
unchanged.

The issue's secondary goal — runtime within 5% of full on encode at
all sizes — is not met. Residual gap is per-closure call overhead;
closing it would need writer bodies inlined into the generated body
(not just call sites), which is a larger codegen-at-runtime change.

Closes tarantool-protobuf-21d.
Files tarantool-protobuf-h8x (decode_group bimodal trace flake
surfaced during validation; pre-existing on master).

Eugene Blikh <bigbes@gmail.com> — 2026-05-24 10:01:19 UTC

Commit b93adbf01508f9efe23729089e19285dc5c9abd8view raw patch

Parent(s): 0fb62135

4 changed file(s)

FileStatus+
.beads/issues.jsonl M +3 -2
bench/COMPARISON.md M +5 -2
runtime/pb/codec.lua M +87 -12
runtime/pb/init.lua M +6