Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-03-04 07:06:14 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-03-04 07:18:10 +0300
commit0d28e2a334a10d75c2c10054dddefabfc8766840 (patch)
tree11e9658a23f35ffd5e406c4bb0ed72f286747a57
parent67856d8c4afa6a35b15f00ce24ebe54f403c9fc7 (diff)
PyAPI: correct garbage collection for StructRNA types
By default objects are no longer GC tracked, this removes some overhead although it's not significant in my own testing. - Only enable GC for StructRNA when 'WITH_PYTHON_SAFETY' is on. - Only track StructRNA when their 'reference' is set. - Add missing NULL check when 'WITH_PYTHON_SAFETY' is on and objects new objects be created.
-rw-r--r--source/blender/python/intern/bpy_rna.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 555dd41b228..a006b81cb60 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1204,15 +1204,15 @@ static void pyrna_struct_dealloc(BPy_StructRNA *self)
static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
{
if (self->reference) {
- // PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */
- pyrna_struct_clear(self);
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->reference);
}
/* Reference is now NULL. */
if (reference) {
self->reference = reference;
Py_INCREF(reference);
- // PyObject_GC_Track(self); /* INITIALIZED TRACKED ? */
+ PyObject_GC_Track(self);
}
}
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
@@ -5822,6 +5822,11 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *
BPy_StructRNA *ret;
if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) {
ret->ptr = base->ptr;
+#ifdef USE_PYRNA_STRUCT_REFERENCE
+ /* #PyType_GenericAlloc will have set tracking.
+ * We only want tracking when `StructRNA.reference` has been set. */
+ PyObject_GC_UnTrack(ret);
+#endif
}
/* Pass on exception & NULL if tp_alloc fails. */
return (PyObject *)ret;
@@ -6525,7 +6530,11 @@ PyTypeObject pyrna_struct_Type = {
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+#ifdef USE_PYRNA_STRUCT_REFERENCE
+ | Py_TPFLAGS_HAVE_GC
+#endif
+ , /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
@@ -7462,13 +7471,28 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
if (tp) {
pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0);
+#ifdef USE_PYRNA_STRUCT_REFERENCE
+ /* #PyType_GenericAlloc will have set tracking.
+ * We only want tracking when `StructRNA.reference` has been set. */
+ if (pyrna != NULL) {
+ PyObject_GC_UnTrack(pyrna);
+ }
+#endif
Py_DECREF(tp); /* srna owns, can't hold a reference. */
}
else {
CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type));
+
+#ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna = (BPy_StructRNA *)PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
+#else
+ pyrna = (BPy_StructRNA *)PyObject_New(BPy_StructRNA, &pyrna_struct_Type);
+#endif
+
#ifdef USE_WEAKREFS
- pyrna->in_weakreflist = NULL;
+ if (pyrna != NULL) {
+ pyrna->in_weakreflist = NULL;
+ }
#endif
}
}