summaryrefslogtreecommitdiffstats
path: root/Objects/funcobject.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-10-15 19:06:41 (GMT)
committerGitHub <noreply@github.com>2024-10-15 19:06:41 (GMT)
commit3ea488aac44887a7cdb30be69580c81a0ca6afe2 (patch)
tree925b843905d373016f38c08431a7658fd10db081 /Objects/funcobject.c
parent206de4155b01f6285c5551d2224391fa1fa0ac14 (diff)
downloadcpython-3ea488aac44887a7cdb30be69580c81a0ca6afe2.zip
cpython-3ea488aac44887a7cdb30be69580c81a0ca6afe2.tar.gz
cpython-3ea488aac44887a7cdb30be69580c81a0ca6afe2.tar.bz2
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.
Diffstat (limited to 'Objects/funcobject.c')
-rw-r--r--Objects/funcobject.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 855d1a2..6119a96 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -116,7 +116,8 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr)
op->func_builtins = Py_NewRef(constr->fc_builtins);
op->func_name = Py_NewRef(constr->fc_name);
op->func_qualname = Py_NewRef(constr->fc_qualname);
- op->func_code = Py_NewRef(constr->fc_code);
+ _Py_INCREF_CODE((PyCodeObject *)constr->fc_code);
+ op->func_code = constr->fc_code;
op->func_defaults = Py_XNewRef(constr->fc_defaults);
op->func_kwdefaults = Py_XNewRef(constr->fc_kwdefaults);
op->func_closure = Py_XNewRef(constr->fc_closure);
@@ -146,7 +147,8 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
PyThreadState *tstate = _PyThreadState_GET();
- PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code);
+ PyCodeObject *code_obj = (PyCodeObject *)code;
+ _Py_INCREF_CODE(code_obj);
assert(code_obj->co_name != NULL);
PyObject *name = Py_NewRef(code_obj->co_name);
@@ -1094,7 +1096,7 @@ func_dealloc(PyObject *self)
}
(void)func_clear((PyObject*)op);
// These aren't cleared by func_clear().
- Py_DECREF(op->func_code);
+ _Py_DECREF_CODE((PyCodeObject *)op->func_code);
Py_DECREF(op->func_name);
Py_DECREF(op->func_qualname);
PyObject_GC_Del(op);