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 <campbell@blender.org>2022-09-28 09:09:12 +0300
committerCampbell Barton <campbell@blender.org>2022-09-28 10:53:30 +0300
commit5270ac5ed87fb5f9b5605fdc332f16ea0f7ee59d (patch)
tree4319932f4aee73faf1a56ec04a48b29c7055d9db /source/blender/python/generic/idprop_py_api.c
parentada2b9f6e43e687acba8b7b86394d3cc20eed291 (diff)
Fix GC tracking error for instances of mathutils types
Mathutils types were always GC tracked even when it wasn't intended. Not having to track objects speeds up Python execution. In an isolated benchmark created to stress test the GC creating 4-million vectors (re-assigning them 100 times), this gives an overall ~2.5x speedup, see: P3221. Details: Since [0] (which added support for sub-classed mathutils types) tp_alloc was called which defaults to PyType_GenericAlloc which always GC tracked the resulting object when Py_TPFLAGS_HAVE_GC was set. Avoid using PyType_GenericAlloc unless the type is sub-classed, in that case the object is un-tracked. Add asserts that the tracked state is as expected before tracking & un-tracking, to ensure changes to object creation don't cause objects to be tracked unintentionally. Also assign the PyTypeObject.tp_is_gc callback so types optionally GC track objects only do so when an object is referenced. [0]: fbd936494495d0de54eef24a97957e000306785f
Diffstat (limited to 'source/blender/python/generic/idprop_py_api.c')
-rw-r--r--source/blender/python/generic/idprop_py_api.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 333ab9487d1..3978f7f37cc 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -909,6 +909,11 @@ static int BPy_IDGroup_Iter_clear(BPy_IDGroup_Iter *self)
return 0;
}
+static int BPy_IDGroup_Iter_is_gc(BPy_IDGroup_Iter *self)
+{
+ return (self->group != NULL);
+}
+
static bool BPy_Group_Iter_same_size_or_raise_error(BPy_IDGroup_Iter *self)
{
if (self->len_init == self->group->prop->len) {
@@ -1000,6 +1005,7 @@ static void IDGroup_Iter_init_type(void)
SHARED_MEMBER_SET(tp_flags, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC);
SHARED_MEMBER_SET(tp_traverse, (traverseproc)BPy_IDGroup_Iter_traverse);
SHARED_MEMBER_SET(tp_clear, (inquiry)BPy_IDGroup_Iter_clear);
+ SHARED_MEMBER_SET(tp_is_gc, (inquiry)BPy_IDGroup_Iter_is_gc);
SHARED_MEMBER_SET(tp_iter, PyObject_SelfIter);
#undef SHARED_MEMBER_SET
@@ -1015,6 +1021,7 @@ static PyObject *IDGroup_Iter_New_WithType(BPy_IDProperty *group,
iter->group = group;
if (group != NULL) {
Py_INCREF(group);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
PyObject_GC_Track(iter);
iter->cur = (reversed ? group->prop->data.group.last : group->prop->data.group.first);
iter->len_init = group->prop->len;
@@ -1086,6 +1093,11 @@ static int BPy_IDGroup_View_clear(BPy_IDGroup_View *self)
return 0;
}
+static int BPy_IDGroup_View_is_gc(BPy_IDGroup_View *self)
+{
+ return (self->group != NULL);
+}
+
/* View Specific API's (Key/Value/Items). */
static PyObject *BPy_Group_ViewKeys_iter(BPy_IDGroup_View *self)
@@ -1233,6 +1245,7 @@ static void IDGroup_View_init_type(void)
SHARED_MEMBER_SET(tp_flags, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC);
SHARED_MEMBER_SET(tp_traverse, (traverseproc)BPy_IDGroup_View_traverse);
SHARED_MEMBER_SET(tp_clear, (inquiry)BPy_IDGroup_View_clear);
+ SHARED_MEMBER_SET(tp_is_gc, (inquiry)BPy_IDGroup_View_is_gc);
SHARED_MEMBER_SET(tp_methods, BPy_IDGroup_View_methods);
#undef SHARED_MEMBER_SET
@@ -2087,6 +2100,7 @@ static BPy_IDGroup_View *IDGroup_View_New_WithType(BPy_IDProperty *group, PyType
iter->group = group;
if (group != NULL) {
Py_INCREF(group);
+ BLI_assert(!PyObject_GC_IsTracked((PyObject *)iter));
PyObject_GC_Track(iter);
}
return iter;