Skip to content

Commit e4172bc

Browse files
committed
gc: restore stock-sized allocation pacing
1 parent 7277890 commit e4172bc

4 files changed

Lines changed: 36 additions & 1 deletion

File tree

notes/m6.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,3 +843,15 @@ M6 token-owned JIT controls:
843843
token across `jit.opt.start()`, then verifies the public call waits, publishes
844844
option flag/parameter changes, and leaves the token free after a later invalid
845845
option is caught.
846+
847+
M6 GC2 stock-pacing compatibility:
848+
- Lowered `LJ_GC2_TRIGGER_MIN` from a 256 MiB floor to 256 KiB. The old floor
849+
kept `collectgarbage("count")` growing through stock-style single-thread
850+
`ffi.new()` bursts without an automatic step, failing the stock
851+
`lib/ffi/ffi_new.lua` "GC step missing for ffi.new" check. The new floor
852+
still batches allocation accounting above `LJ_GC2_ACCT_FLUSH`, but lets the
853+
normal idle threshold bridge trigger cycles at LuaJIT-like heap growth.
854+
- `tests/t-ffi-cdata-alloc.lua` now includes the stock aligned-`ffi.new`
855+
GC-step guard before the existing threaded cdata allocation stress.
856+
Verification: direct stock `ffi_new.lua`, `m6_jit_alloc_account`, and
857+
`m7_ffi_cdata_alloc` passed.

plan/05_gc_concurrent.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,10 @@ driver ownership.
619619
## 5.11 Pacing & assists
620620
Trigger when `alloc_since_trigger > trigger_bytes` where trigger_bytes =
621621
live_estimate * gcpause_pct/100 (default 100% ⇒ 2x heap growth, Lua-like).
622+
Current bridge: `trigger_bytes` keeps only a 256 KiB minimum floor
623+
(`8 * LJ_GC2_ACCT_FLUSH`). This preserves stock single-thread pacing for
624+
short bursts such as aligned `ffi.new()` loops while still batching GC2
625+
allocation-trigger accounting above the per-TG flush quantum.
622626
Hard limit `hard_bytes = trigger*2`: an allocating thread past it runs a
623627
bounded **mark assist** in alloc_slow: pop ≤2^assist_shift objects from the
624628
SSB-stack/steal and trace them (mutator tracing reuses worker code with

src/lj_gc2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ enum {
143143
#define LJ_GC2_HS_STOPREQ 0x00000400u
144144

145145
#define LJ_GC2_ACCT_FLUSH 32768u
146-
#define LJ_GC2_TRIGGER_MIN (LJ_GC2_ACCT_FLUSH * 8192u)
146+
#define LJ_GC2_TRIGGER_MIN (LJ_GC2_ACCT_FLUSH * 8u)
147147
#define LJ_GC2_HELPER_IDLE_STEP (LJ_GC2_ACCT_FLUSH * 4u)
148148
#define LJ_GC2_WORKER_DRAIN_BATCH 64u
149149
#define LJ_GC2_WEAK_DRAIN_BATCH 64u

tests/t-ffi-cdata-alloc.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local th = require"threading"
22
local ffi = require"ffi"
3+
local bit = require"bit"
34
local harness = require"thread_harness"
45

56
local nthreads = harness.arg_number(1, "LJ_M7_FFI_CDATA_THREADS", 6)
@@ -10,6 +11,24 @@ typedef struct { int x; double y; } lj_m7_cdata_alloc_t;
1011
]]
1112

1213
assert(ffi.sizeof("lj_m7_cdata_alloc_t") == 16)
14+
15+
do
16+
local oc = collectgarbage("count")
17+
for al = 0, 15 do
18+
local align = 2 ^ al
19+
local ct = ffi.typeof("struct { char __attribute__((aligned("..
20+
align.."))) a; }")
21+
for _ = 1, 100 do
22+
local cd = ct()
23+
local addr = tonumber(ffi.cast("intptr_t", ffi.cast("void *", cd)))
24+
assert(bit.band(addr, align - 1) == 0)
25+
end
26+
end
27+
local nc = collectgarbage("count")
28+
assert(nc < oc + 3000, "GC step missing for ffi.new")
29+
collectgarbage("collect")
30+
end
31+
1332
local ready, start = harness.channels(nthreads)
1433
local workers = {}
1534

0 commit comments

Comments
 (0)