fix(jit): size the string pool to one LBUF (#2066)

STR_LIMIT-STR_BASE was 12288 bytes while OUT_SLOT tracked LBUF_SIZE at
32768, so any expression whose pooled constants exceeded ~12KB fell back
with COMPILATION FAILED.  Measured cliff: rvbench(shuffle(repeat(a,N)),2)
at N=12272.

Expand the pool to 32KB and slide FARGS up to keep its 16KB capacity.
static_asserts pin the abutments.  Cached programs from the old layout
fail the fargs-range check on load and recompile.  Smoke pins N=15000
above the old cliff (rvbench_fn TC056).
This commit is contained in:
Stephen Dennis 2026-08-05 14:37:38 +00:00
parent d16d20761f
commit 6880a8e42c
3 changed files with 55 additions and 7 deletions

View file

@ -284,14 +284,30 @@ struct rv_compiler {
static constexpr size_t MEM_SIZE = 0x540000; // 4 MB map + 1 MB heap + 256 KB doubles scratch
static constexpr uint64_t CODE_BASE = 0x0000;
static constexpr uint64_t CODE_LIMIT = 0x1000;
// String pool sized to hold one full LBUF (32768) of constants (#2066).
// Previously STR_LIMIT was 0x4000 (12 KB) while OUT_SLOT tracked LBUF at
// 32 KB, so any expression whose pooled constants exceeded ~12 KB fell
// back to the AST evaluator with COMPILATION FAILED. FARGS moved up to
// keep the same 16 KB capacity without overlapping the string region.
// Cached programs from the old layout fail the fargs-range check on load
// and recompile cleanly.
static constexpr uint64_t STR_BASE = 0x1000;
static constexpr uint64_t STR_LIMIT = 0x4000;
static constexpr uint64_t FARGS_BASE = 0x4000;
static constexpr uint64_t FARGS_LIMIT= 0x8000;
static constexpr uint64_t STR_LIMIT = 0x9000; // STR_BASE + 0x8000 (= LBUF_SIZE)
static constexpr uint64_t FARGS_BASE = 0x9000;
static constexpr uint64_t FARGS_LIMIT= 0xD000; // FARGS_BASE + 0x4000
static constexpr uint64_t BLOB_BASE = 0x10000;
static constexpr uint64_t BLOB_LIMIT = 0x40000;
static_assert(CODE_LIMIT == STR_BASE,
"code region must abut the string pool");
static_assert(STR_LIMIT == FARGS_BASE,
"string pool must abut the fargs pool");
static_assert(FARGS_LIMIT <= BLOB_BASE,
"fargs pool must not overlap the blob region");
static_assert(STR_LIMIT - STR_BASE >= 32768,
"string pool must hold one LBUF of constants (#2066)");
// Output slots — sized to match LBUF_SIZE (32768).
// Stack-allocated: output buffers grow downward from STACK_TOP.
// The compiled code prologue decrements SP by the total output

View file

@ -4,8 +4,8 @@
# A JIT-compiled expression that evaluates another expression (u(), ulocal(),
# or any outer construct wrapping one) runs the inner compile on the shared
# heap, whose string pool lives at 0x40000..0x60000 rather than the one-shot
# compiler's 0x1000..0x4000. hir_codegen's FP slot allocator bounded itself
# against the static rv_compiler::STR_LIMIT (0x4000) instead of this compile's
# compiler's 0x1000..0x9000 (#2066). hir_codegen's FP slot allocator bounded
# itself against the static rv_compiler::STR_LIMIT instead of this compile's
# own str_pool_limit, so every FP slot address stayed 0 and all float
# temporaries aliased guest address 0 (#1159).
#

View file

@ -410,8 +410,40 @@
#
&tr.tc055 test_rvbench_fn=
@log smoke=BENCH055:
[rvbench(iter(a|1 b|2 c|3 d|4 e|5, before(##\,|)),10000)];
@trig me/tr.done
[rvbench(iter(a|1 b|2 c|3 d|4 e|5, before(##\,|)),10000)]
-
#
# Test Case #56 - string-pool capacity is one LBUF (#2066).
#
# The former cliff was exact and reproducible: rvbench(shuffle(repeat(a,N)),2)
# returned #-1 COMPILATION FAILED for N >= 12272 because STR_LIMIT-STR_BASE
# was 12288 bytes. The pool is now 32768 (= LBUF_SIZE). N=15000 sits above
# the old cliff and well under the new one; if the pool regresses, this
# fails with COMPILATION FAILED rather than a silent fallback to the AST.
#
&tr.tc056 test_rvbench_fn=
@if cand(
u(me/tr.has_jit),
not(strmatch(setr(0,rvbench(shuffle(repeat(a,15000)),2)),*COMPILATION FAILED*))
)=
{
@log smoke=TC056: str pool holds >12KB constants (#2066). Succeeded.;
@trig me/tr.done
},
{
@if u(me/tr.has_jit)=
{
@log smoke=TC056: str pool holds >12KB constants (#2066). Failed (%q0).;
@trig me/tr.done
},
{
@log smoke=TC056: str pool holds >12KB constants (#2066). Skipped (JIT not enabled).;
@trig me/tr.done
}
}
-
&tr.has_jit test_rvbench_fn=
[strmatch(jitstats(),*eval_attempts=*)]
-
&tr.done test_rvbench_fn=
@log smoke=End rvbench() benchmarks.;