mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
When the jmp_buf table is full, give the new buffer the slot of the one filled longest ago instead of ending the process.
The table never removes entries and a session keeps meeting new buffer addresses: 12 to 15 more with every reload of a save. A longjmp to a replaced buffer ends the process as one to an unknown buffer always did. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -31,11 +31,13 @@ typedef struct {
|
||||
uint64_t x[12], sp; // x19-x30, sp
|
||||
__uint128_t d[8]; // d8-d15 (the low halves are what the ABI keeps)
|
||||
PlatJmp frame;
|
||||
uint64_t seq; // jt_seq at its last setjmp: the smallest is the entry filled longest ago
|
||||
} JmpEnt;
|
||||
|
||||
#define JMP_N 1024
|
||||
static JmpEnt jt[JMP_N];
|
||||
static PlatMutex jt_lock = PLAT_MUTEX_INIT;
|
||||
static uint64_t jt_seq; // jt_lock
|
||||
|
||||
// Host function starts of the lifted code, sorted, with their guest starts: the guest function a host address runs.
|
||||
typedef struct { uintptr_t host; uint64_t guest; } Rev;
|
||||
@@ -124,9 +126,24 @@ static void ov_setjmp(Cpu *c) {
|
||||
(unsigned long long)caller, (unsigned long long)c->x[30]);
|
||||
plat_mutex_lock(&jt_lock);
|
||||
JmpEnt *s = slot_of(env, 1);
|
||||
if (!s) rt_fatal("setjmp: more than %d buffers", JMP_N);
|
||||
int replaced = 0;
|
||||
if (!s) {
|
||||
// Every slot holds a buffer (entries are never removed, and a long session keeps meeting new buffer
|
||||
// addresses): the one filled longest ago gives its slot. With no free slot left a lookup walks the whole
|
||||
// table, so the new buffer is found wherever it sits. A longjmp to the replaced buffer ends the process as
|
||||
// one to an unknown buffer does (ov_longjmp); before, the 1025th buffer itself ended it.
|
||||
s = &jt[0];
|
||||
for (int k = 1; k < JMP_N; k++)
|
||||
if (jt[k].seq < s->seq) s = &jt[k];
|
||||
replaced = 1;
|
||||
}
|
||||
e.seq = ++jt_seq;
|
||||
*s = e;
|
||||
plat_mutex_unlock(&jt_lock);
|
||||
static volatile int32_t n_replaced;
|
||||
if (replaced && plat_inc32(&n_replaced) == 1)
|
||||
rt_log("setjmp: all %d buffer slots are in use; the buffer filled longest ago gives its slot from now on "
|
||||
"(logged once)", JMP_N);
|
||||
c->x[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user