8000 Update test so that RNG is in _Py_Dealloc · python/cpython@7c86a25 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c86a25

Browse files
committed
Update test so that RNG is in _Py_Dealloc
1 parent 92e82ac commit 7c86a25

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

Include/cpython/pystate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ struct _ts {
210210
_PyRemoteDebuggerSupport remote_debugger_support;
211211

212212
uint64_t prng;
213+
Py_ssize_t ob_dealloc_depth;
213214
};
214215

215216
/* other API */

Include/internal/pycore_pystate.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,16 +325,6 @@ _Py_RecursionLimit_GetMargin(PyThreadState *tstate)
325325
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
326326
assert(_tstate->c_stack_hard_limit != 0);
327327
intptr_t here_addr = _Py_get_machine_stack_pointer();
328-
329-
// splitmix64 from https://prng.di.unimi.it/splitmix64.c
330-
uint64_t z = (tstate->prng += 0x9e3779b97f4a7c15);
331-
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
332-
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
333-
uint64_t r = z ^ (z >> 31);
334-
if ((r & 0xFF) < 2) { // 2/256 chance = ~ 0.8% chance
335-
return 1;
336-
}
337-
338328
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, here_addr - (intptr_t)_tstate->c_stack_soft_limit, PYOS_STACK_MARGIN_SHIFT);
339329
}
340330

Objects/object.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,16 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg,
31553155
Py_FatalError("_PyObject_AssertFailed");
31563156
}
31573157

3158+
static int
3159+
should_randomly_deposit_object(PyThreadState *tstate)
3160+
{
3161+
// splitmix64 from https://prng.di.unimi.it/splitmix64.c
3162+
uint64_t z = (tstate->prng += 0x9e3779b97f4a7c15);
3163+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
3164+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
3165+
uint64_t r = z ^ (z >> 31);
3166+
return (r & 0xFF) < 2;
3167+
}
31583168

31593169
/*
31603170
When deallocating a container object, it's possible to trigger an unbounded
@@ -3170,7 +3180,7 @@ _Py_Dealloc(PyObject *op)
31703180
destructor dealloc = type->tp_dealloc;
31713181
PyThreadState *tstate = _PyThreadState_GET();
31723182
intptr_t margin = _Py_RecursionLimit_GetMargin(tstate);
3173-
if (margin < 2) {
3183+
if (margin < 2 || (tstate->ob_dealloc_depth > 0 && should_randomly_deposit_object(tstate))) {
31743184
_PyTrash_thread_deposit_object(tstate, (PyObject *)op);
31753185
return;
31763186
}
@@ -3192,7 +3202,9 @@ _Py_Dealloc(PyObject *op)
31923202
_Py_ForgetReference(op);
31933203
#endif
31943204
_PyReftracerTrack(op, PyRefTracer_DESTROY);
3205+
tstate->ob_dealloc_depth++;
31953206
(*dealloc)(op);
3207+
tstate->ob_dealloc_depth--;
31963208

31973209
#ifdef Py_DEBUG
31983210
// gh-89373: The tp_dealloc function must leave the current exception

0 commit comments

Comments
 (0)
0