summaryrefslogtreecommitdiffstats
path: root/Objects/funcobject.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-10-21 16:51:29 (GMT)
committerGitHub <noreply@github.com>2024-10-21 16:51:29 (GMT)
commit9b0bfba2a265b8108610b037945c004d8e81f2b4 (patch)
tree3fe9053a4a9e298aff740c60ca4581461b9fd4a8 /Objects/funcobject.c
parentd880c83ff7fb2e464bc4f469d74cc3fc3eca082c (diff)
downloadcpython-9b0bfba2a265b8108610b037945c004d8e81f2b4.zip
cpython-9b0bfba2a265b8108610b037945c004d8e81f2b4.tar.gz
cpython-9b0bfba2a265b8108610b037945c004d8e81f2b4.tar.bz2
gh-124218: Use per-thread reference counting for globals and builtins (#125713)
Use per-thread refcounting for the reference from function objects to the globals and builtins dictionaries.
Diffstat (limited to 'Objects/funcobject.c')
-rw-r--r--Objects/funcobject.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 3cb2476..44fb4ac 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -3,6 +3,7 @@
#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()
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
@@ -112,8 +113,15 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr)
Py_XDECREF(module);
return NULL;
}
- op->func_globals = Py_NewRef(constr->fc_globals);
- op->func_builtins = Py_NewRef(constr->fc_builtins);
+ _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);
+ }
+ op->func_builtins = constr->fc_builtins;
op->func_name = Py_NewRef(constr->fc_name);
op->func_qualname = Py_NewRef(constr->fc_qualname);
_Py_INCREF_CODE((PyCodeObject *)constr->fc_code);
@@ -143,7 +151,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
{
assert(globals != NULL);
assert(PyDict_Check(globals));
- Py_INCREF(globals);
+ _Py_INCREF_DICT(globals);
PyThreadState *tstate = _PyThreadState_GET();
@@ -184,7 +192,12 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
if (builtins == NULL) {
goto error;
}
- Py_INCREF(builtins);
+ if (PyDict_Check(builtins)) {
+ _Py_INCREF_DICT(builtins);
+ }
+ else {
+ Py_INCREF(builtins);
+ }
PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
if (op == NULL) {
@@ -1057,8 +1070,21 @@ func_clear(PyObject *self)
{
PyFunctionObject *op = _PyFunction_CAST(self);
func_clear_version(_PyInterpreterState_GET(), op);
- Py_CLEAR(op->func_globals);
- Py_CLEAR(op->func_builtins);
+ PyObject *globals = op->func_globals;
+ op->func_globals = NULL;
+ if (globals != NULL) {
+ _Py_DECREF_DICT(globals);
+ }
+ 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_CLEAR(op->func_module);
Py_CLEAR(op->func_defaults);
Py_CLEAR(op->func_kwdefaults);