diff options
author | Sam Gross <colesbury@gmail.com> | 2024-10-24 16:44:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-24 16:44:38 (GMT) |
commit | 3c4a7fa6178d852ccb73527aaa2d0a5e93022e89 (patch) | |
tree | e74c8d15c6dab8e3b58478aa5e0d9915477f83de /Objects/funcobject.c | |
parent | 5003ad5c5ea508f0dde1b374cd8bc6a481ad5c5d (diff) | |
download | cpython-3c4a7fa6178d852ccb73527aaa2d0a5e93022e89.zip cpython-3c4a7fa6178d852ccb73527aaa2d0a5e93022e89.tar.gz cpython-3c4a7fa6178d852ccb73527aaa2d0a5e93022e89.tar.bz2 |
gh-124218: Avoid refcount contention on builtins module (GH-125847)
This replaces `_PyEval_BuiltinsFromGlobals` with
`_PyDict_LoadBuiltinsFromGlobals`, which returns a new reference
instead of a borrowed reference. Internally, the new function uses
per-thread reference counting when possible to avoid contention on the
refcount fields on the builtins module.
Diffstat (limited to 'Objects/funcobject.c')
-rw-r--r-- | Objects/funcobject.c | 25 |
1 files changed, 3 insertions, 22 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 44fb4ac..e72a7d9 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -2,7 +2,6 @@ /* Function object implementation */ #include "Python.h" -#include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() #include "pycore_dict.h" // _Py_INCREF_DICT() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKeywords() @@ -115,12 +114,7 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr) } _Py_INCREF_DICT(constr->fc_globals); op->func_globals = constr->fc_globals; - if (PyDict_Check(constr->fc_builtins)) { - _Py_INCREF_DICT(constr->fc_builtins); - } - else { - Py_INCREF(constr->fc_builtins); - } + _Py_INCREF_BUILTINS(constr->fc_builtins); op->func_builtins = constr->fc_builtins; op->func_name = Py_NewRef(constr->fc_name); op->func_qualname = Py_NewRef(constr->fc_qualname); @@ -153,8 +147,6 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname assert(PyDict_Check(globals)); _Py_INCREF_DICT(globals); - PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *code_obj = (PyCodeObject *)code; _Py_INCREF_CODE(code_obj); @@ -188,16 +180,10 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname goto error; } - builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref + builtins = _PyDict_LoadBuiltinsFromGlobals(globals); if (builtins == NULL) { goto error; } - if (PyDict_Check(builtins)) { - _Py_INCREF_DICT(builtins); - } - else { - Py_INCREF(builtins); - } PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); if (op == NULL) { @@ -1078,12 +1064,7 @@ func_clear(PyObject *self) PyObject *builtins = op->func_builtins; op->func_builtins = NULL; if (builtins != NULL) { - if (PyDict_Check(builtins)) { - _Py_DECREF_DICT(builtins); - } - else { - Py_DECREF(builtins); - } + _Py_DECREF_BUILTINS(builtins); } Py_CLEAR(op->func_module); Py_CLEAR(op->func_defaults); |