[Bf-blender-cvs] [0d28e2a334a] master: PyAPI: correct garbage collection for StructRNA types

Campbell Barton noreply at git.blender.org
Thu Mar 4 05:18:52 CET 2021


Commit: 0d28e2a334a10d75c2c10054dddefabfc8766840
Author: Campbell Barton
Date:   Thu Mar 4 15:06:14 2021 +1100
Branches: master
https://developer.blender.org/rB0d28e2a334a10d75c2c10054dddefabfc8766840

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.

===================================================================

M	source/blender/python/intern/bpy_rna.c

===================================================================

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
     }
   }



More information about the Bf-blender-cvs mailing list