summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-10-24 16:44:38 (GMT)
committerGitHub <noreply@github.com>2024-10-24 16:44:38 (GMT)
commit3c4a7fa6178d852ccb73527aaa2d0a5e93022e89 (patch)
treee74c8d15c6dab8e3b58478aa5e0d9915477f83de /Python
parent5003ad5c5ea508f0dde1b374cd8bc6a481ad5c5d (diff)
downloadcpython-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 'Python')
-rw-r--r--Python/ceval.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index ca75646..ece7ef1 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -639,7 +639,7 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
if (locals == NULL) {
locals = globals;
}
- PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
+ PyObject *builtins = _PyDict_LoadBuiltinsFromGlobals(globals);
if (builtins == NULL) {
return NULL;
}
@@ -654,6 +654,7 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
.fc_closure = NULL
};
PyFunctionObject *func = _PyFunction_FromConstructor(&desc);
+ _Py_DECREF_BUILTINS(builtins);
if (func == NULL) {
return NULL;
}
@@ -1899,7 +1900,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
if (defaults == NULL) {
return NULL;
}
- PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
+ PyObject *builtins = _PyDict_LoadBuiltinsFromGlobals(globals);
if (builtins == NULL) {
Py_DECREF(defaults);
return NULL;
@@ -1954,6 +1955,7 @@ fail:
Py_XDECREF(func);
Py_XDECREF(kwnames);
PyMem_Free(newargs);
+ _Py_DECREF_BUILTINS(builtins);
Py_DECREF(defaults);
return res;
}