mirror of
https://github.com/python/cpython.git
synced 2025-11-25 21:11:09 +00:00
gh-123923: Defer refcounting for f_funcobj in _PyInterpreterFrame (#124026)
Use a `_PyStackRef` and defer the reference to `f_funcobj` when possible. This avoids some reference count contention in the common case of executing the same code object from multiple threads concurrently in the free-threaded build.
This commit is contained in:
parent
d3c76dff44
commit
f4997bb3ac
17 changed files with 143 additions and 137 deletions
|
|
@ -1634,7 +1634,7 @@ frame_dealloc(PyFrameObject *f)
|
|||
/* Kill all local variables including specials, if we own them */
|
||||
if (f->f_frame == frame && frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) {
|
||||
PyStackRef_CLEAR(frame->f_executable);
|
||||
Py_CLEAR(frame->f_funcobj);
|
||||
PyStackRef_CLEAR(frame->f_funcobj);
|
||||
Py_CLEAR(frame->f_locals);
|
||||
_PyStackRef *locals = _PyFrame_GetLocalsArray(frame);
|
||||
_PyStackRef *sp = frame->stackpointer;
|
||||
|
|
@ -1790,7 +1790,7 @@ static void
|
|||
init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
|
||||
{
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
_PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func),
|
||||
_PyFrame_Initialize(frame, PyStackRef_FromPyObjectNew(func),
|
||||
Py_XNewRef(locals), code, 0, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1861,14 +1861,15 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
|
|||
PyCodeObject *co = _PyFrame_GetCode(frame);
|
||||
int lasti = _PyInterpreterFrame_LASTI(frame);
|
||||
if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS
|
||||
&& PyFunction_Check(frame->f_funcobj)))
|
||||
&& PyStackRef_FunctionCheck(frame->f_funcobj)))
|
||||
{
|
||||
/* Free vars are initialized */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free vars have not been initialized -- Do that */
|
||||
PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
|
||||
PyFunctionObject *func = _PyFrame_GetFunction(frame);
|
||||
PyObject *closure = func->func_closure;
|
||||
int offset = PyUnstable_Code_GetFirstFree(co);
|
||||
for (int i = 0; i < co->co_nfreevars; ++i) {
|
||||
PyObject *o = PyTuple_GET_ITEM(closure, i);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue