gh-124218: Use per-thread refcounts for code objects (#125216)

Use per-thread refcounting for the reference from function objects to
their corresponding code object. This can be a source of contention when
frequently creating nested functions. Deferred refcounting alone isn't a
great fit here because these references are on the heap and may be
modified by other libraries.
This commit is contained in:
Sam Gross 2024-10-15 15:06:41 -04:00 committed by GitHub
parent 206de4155b
commit 3ea488aac4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 126 additions and 83 deletions

View file

@ -14,6 +14,7 @@
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_uniqueid.h" // _PyObject_AssignUniqueId()
#include "clinic/codeobject.c.h"
static const char *
@ -676,7 +677,7 @@ _PyCode_New(struct _PyCodeConstructor *con)
}
init_code(co, con);
#ifdef Py_GIL_DISABLED
_PyObject_SetDeferredRefcount((PyObject *)co);
co->_co_unique_id = _PyObject_AssignUniqueId((PyObject *)co);
_PyObject_GC_TRACK(co);
#endif
Py_XDECREF(replacement_locations);
@ -1864,6 +1865,9 @@ code_dealloc(PyCodeObject *co)
Py_XDECREF(co->co_qualname);
Py_XDECREF(co->co_linetable);
Py_XDECREF(co->co_exceptiontable);
#ifdef Py_GIL_DISABLED
assert(co->_co_unique_id == -1);
#endif
if (co->_co_cached != NULL) {
Py_XDECREF(co->_co_cached->_co_code);
Py_XDECREF(co->_co_cached->_co_cellvars);