diff options
author | Campbell Barton <campbell@blender.org> | 2022-09-28 09:09:12 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-09-28 10:53:30 +0300 |
commit | 5270ac5ed87fb5f9b5605fdc332f16ea0f7ee59d (patch) | |
tree | 4319932f4aee73faf1a56ec04a48b29c7055d9db /source/blender/python/gpu | |
parent | ada2b9f6e43e687acba8b7b86394d3cc20eed291 (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/gpu')
-rw-r--r-- | source/blender/python/gpu/gpu_py_batch.c | 7 | ||||
-rw-r--r-- | source/blender/python/gpu/gpu_py_buffer.c | 7 |
2 files changed, 14 insertions, 0 deletions
diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c index 879e1c0ce8b..a36b1dfd1b5 100644 --- a/source/blender/python/gpu/gpu_py_batch.c +++ b/source/blender/python/gpu/gpu_py_batch.c @@ -111,6 +111,7 @@ static PyObject *pygpu_batch__tp_new(PyTypeObject *UNUSED(type), PyObject *args, Py_INCREF(py_indexbuf); } + BLI_assert(!PyObject_GC_IsTracked((PyObject *)ret)); PyObject_GC_Track(ret); #endif @@ -273,6 +274,11 @@ static int pygpu_batch__tp_clear(BPyGPUBatch *self) return 0; } +static int pygpu_batch__tp_is_gc(BPyGPUBatch *self) +{ + return self->references != NULL; +} + #endif static void pygpu_batch__tp_dealloc(BPyGPUBatch *self) @@ -313,6 +319,7 @@ PyTypeObject BPyGPUBatch_Type = { .tp_doc = pygpu_batch__tp_doc, .tp_traverse = (traverseproc)pygpu_batch__tp_traverse, .tp_clear = (inquiry)pygpu_batch__tp_clear, + .tp_is_gc = (inquiry)pygpu_batch__tp_is_gc, #else .tp_flags = Py_TPFLAGS_DEFAULT, #endif diff --git a/source/blender/python/gpu/gpu_py_buffer.c b/source/blender/python/gpu/gpu_py_buffer.c index 551eb4451c2..30a434f8667 100644 --- a/source/blender/python/gpu/gpu_py_buffer.c +++ b/source/blender/python/gpu/gpu_py_buffer.c @@ -153,6 +153,7 @@ static BPyGPUBuffer *pygpu_buffer_make_from_data(PyObject *parent, if (parent) { Py_INCREF(parent); buffer->parent = parent; + BLI_assert(!PyObject_GC_IsTracked((PyObject *)buffer)); PyObject_GC_Track(buffer); } return buffer; @@ -422,6 +423,11 @@ static PyObject *pygpu_buffer__tp_new(PyTypeObject *UNUSED(type), PyObject *args return (PyObject *)buffer; } +static int pygpu_buffer__tp_is_gc(BPyGPUBuffer *self) +{ + return self->parent != NULL; +} + /* BPyGPUBuffer sequence methods */ static int pygpu_buffer__sq_length(BPyGPUBuffer *self) @@ -677,6 +683,7 @@ PyTypeObject BPyGPU_BufferType = { .tp_methods = pygpu_buffer__tp_methods, .tp_getset = pygpu_buffer_getseters, .tp_new = pygpu_buffer__tp_new, + .tp_is_gc = (inquiry)pygpu_buffer__tp_is_gc, }; static size_t pygpu_buffer_calc_size(const int format, |