Skip to content

Commit ea68ae2

Browse files
committed
refcount_insertion: fix stale PhxRegState* in kill_registers after erase
phx_rc_kill_registers cached PhxRegState* pointers from phx_sm_get into a local RegCopy array, then iterated calling phx_rc_kill_register which calls phx_sm_erase. Erase rehashes subsequent probe-chain entries, potentially moving them and invalidating cached pointers. Fix: store model keys and kind (int) in RegCopy, re-lookup PhxRegState via phx_sm_get before each kill_register call. Same pattern as bug python#15.
1 parent 9fba738 commit ea68ae2

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

‎Python/jit/hir/refcount_pass_c.c‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ void phx_rc_kill_registers(PhxRefcountEnv *env, void **regs, size_t n_regs,
174174
void *cursor) {
175175
if (n_regs == 0) return;
176176

177-
typedef struct { void *copy; PhxRegState *rstate; } RegCopy;
177+
typedef struct { void *copy; void *model; int kind; } RegCopy;
178178
RegCopy *rcs = (RegCopy *)PyMem_RawMalloc(n_regs * sizeof(RegCopy));
179179

180180
size_t n_rcs = 0;
@@ -183,7 +183,8 @@ void phx_rc_kill_registers(PhxRefcountEnv *env, void **regs, size_t n_regs,
183183
PhxRegState *rs = phx_sm_get(&env->live_regs, model);
184184
if (rs) {
185185
rcs[n_rcs].copy = regs[i];
186-
rcs[n_rcs].rstate = rs;
186+
rcs[n_rcs].model = model;
187+
rcs[n_rcs].kind = rs->kind;
187188
n_rcs++;
188189
}
189190
}
@@ -193,13 +194,13 @@ void phx_rc_kill_registers(PhxRefcountEnv *env, void **regs, size_t n_regs,
193194
RegCopy tmp = rcs[i];
194195
size_t j = i;
195196
while (j > 0) {
196-
int a_bor = (rcs[j-1].rstate->kind == PHX_REF_BORROWED) ? 1 : 0;
197-
int b_bor = (tmp.rstate->kind == PHX_REF_BORROWED) ? 1 : 0;
197+
int a_bor = (rcs[j-1].kind == PHX_REF_BORROWED) ? 1 : 0;
198+
int b_bor = (tmp.kind == PHX_REF_BORROWED) ? 1 : 0;
198199
int swap = 0;
199200
if (b_bor && !a_bor) swap = 1;
200201
else if (a_bor == b_bor) {
201-
int a_id = hir_reg_id(rcs[j-1].rstate->model);
202-
int b_id = hir_reg_id(tmp.rstate->model);
202+
int a_id = hir_reg_id(rcs[j-1].model);
203+
int b_id = hir_reg_id(tmp.model);
203204
if (b_id < a_id) swap = 1;
204205
}
205206
if (!swap) break;
@@ -210,7 +211,8 @@ void phx_rc_kill_registers(PhxRefcountEnv *env, void **regs, size_t n_regs,
210211
}
211212

212213
for (size_t i = 0; i < n_rcs; i++) {
213-
phx_rc_kill_register(env, rcs[i].rstate, rcs[i].copy, cursor);
214+
PhxRegState *rs = phx_sm_get(&env->live_regs, rcs[i].model);
215+
if (rs) phx_rc_kill_register(env, rs, rcs[i].copy, cursor);
214216
}
215217

216218
PyMem_RawFree(rcs);

0 commit comments

Comments
 (0)