Skip to content

Commit 7a2ece9

Browse files
committed
test(jit): separate SMR retry from iterator invalidation
1 parent 7cfa11d commit 7a2ece9

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

notes/b1.2.0-active-sweep-cnew-close-2026-07-14.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,18 @@ helpers have external linkage in split builds but become static in `ljamalg.o`.
5454
proof and the existing TNEW/MARK cooperation fixtures.
5555
- `m3_gc2_no_legacy_runtime`: passed in ordinary and amalgam builds, including
5656
retired-symbol gates and both IDLE and active-SWEEP shutdown.
57-
- Direct `LJ_GC2_TEST_HELPERS` CNEW/SWEEP build and run: passed.
57+
- `m6_jit_alloc_account`: passed, including the IDLE metadata-reclaim entry
58+
race and the helper CNEW/SWEEP and MARK cooperation fixtures.
5859
- The post-HEAD ASAN target previously passed both fixtures directly; the
5960
registered optimized variants above provide the final normal-build evidence.
6061

61-
The `m6_jit_alloc_account` aggregate did not reach the CNEW fixture because
62-
its earlier `t-jit-idle-reclaim-entry` stage timed out reproducibly. The new
63-
CNEW helper binary passed directly under the exact same helper build. The
64-
earlier timeout is being tracked separately and is not counted as validation
65-
for this change.
62+
The first aggregate attempt exposed a stale assumption in
63+
`t-jit-idle-reclaim-entry`: it froze the exclusive IDLE SMR writer and then
64+
forced failed-ISNEXT JLOOP despecialization, whose trace-body admission
65+
correctly retries until that bounded writer leaves. The fixture now tests
66+
closed-gate immutable-sidecar
67+
ITERN dispatch while the writer is paused, releases the writer, and only then
68+
tests lease-dependent exact `JLOOP -> ITERC` despecialization. The separate
69+
startins-sidecar fixture retains the exact live-trace invalidation proof. This
70+
preserves both proofs without
71+
constructing a circular test-only dependency; the full aggregate then passed.

tests/t-jit-idle-reclaim-entry.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,6 @@ int main(void)
209209
ret_patch = patch_first_op(L, "__idle_shadow_ret", BC_RET0);
210210
assert(proto_has_op(global_proto(L, "__idle_shadow_itern"), BC_ISNEXT));
211211
itern_patch = patch_first_op(L, "__idle_shadow_itern", BC_ITERN);
212-
lua_getglobal(L, "idle_next_wrapper");
213-
lua_setglobal(L, "next");
214212
if (!lj_gc2_test_idle_reclaim_enter(g)) {
215213
fprintf(stderr,
216214
"idle reclaim preflight failed: state=%u phase=%u worker=%u assist=%u "
@@ -274,8 +272,9 @@ int main(void)
274272
assert(lua_tointeger(L, -2) == 5);
275273
assert(lua_tointeger(L, -1) == 165);
276274
lua_pop(L, 2);
275+
assert(gc2_jit_sweep_displaced_acq(g) != 0);
277276
assert(bc_op((BCIns)la_load32_acq((const uint32_t *)itern_patch.pc)) ==
278-
BC_ITERC);
277+
BC_JLOOP);
279278

280279
gc2_jit_sweep_displaced_rel(g, 0);
281280
lj_trace_test_force_startins_retry(1);
@@ -294,6 +293,23 @@ int main(void)
294293
assert(la_load32_acq(&ctx.done) != 0);
295294
assert(gc2_smr_reclaiming_acq(g) == 0);
296295
assert(gc2_jit_phase_gate_acq(g) != 0);
296+
297+
/* A failed ISNEXT must take a trace-body lease before deciding whether the
298+
** observed JLOOP still names the exact live ITERN generation and before
299+
** publishing JLOOP -> ITERC. Do that lease-dependent despecialization only
300+
** after the deliberately paused exclusive SMR writer has left. During the
301+
** pause the real builtin above still exercises closed-gate JLOOP recovery
302+
** through the immutable sidecar without waiting for body admission. */
303+
lua_getglobal(L, "idle_next_wrapper");
304+
lua_setglobal(L, "next");
305+
lua_getglobal(L, "__idle_shadow_itern");
306+
lua_getglobal(L, "idle_shadow_input");
307+
ljt_lua_pcall(L, 1, 2, "reopened IDLE ITERN invalidation");
308+
assert(lua_tointeger(L, -2) == 5);
309+
assert(lua_tointeger(L, -1) == 165);
310+
lua_pop(L, 2);
311+
assert(bc_op((BCIns)la_load32_acq((const uint32_t *)itern_patch.pc)) ==
312+
BC_ITERC);
297313
lua_getglobal(L, "idle_real_next");
298314
lua_setglobal(L, "next");
299315
restore_patch(&loop_patch);

0 commit comments

Comments
 (0)