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.
This commit is contained in:
parent
67856d8c4a
commit
0d28e2a334
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue