diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/include/numpy/ufuncobject.h | 8 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 48 | ||||
-rw-r--r-- | numpy/core/src/umath/umathmodule.c | 1 |
3 files changed, 47 insertions, 10 deletions
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h index 90d837a9b..15dcdf010 100644 --- a/numpy/core/include/numpy/ufuncobject.h +++ b/numpy/core/include/numpy/ufuncobject.h @@ -120,7 +120,11 @@ typedef struct _tagPyUFuncObject { */ int nin, nout, nargs; - /* Identity for reduction, either PyUFunc_One or PyUFunc_Zero */ + /* + * Identity for reduction, any of PyUFunc_One, PyUFunc_Zero + * PyUFunc_MinusOne, PyUFunc_None, PyUFunc_ReorderableNone, + * PyUFunc_IdentityValue. + */ int identity; /* Array of one-dimensional core loops */ @@ -301,7 +305,7 @@ typedef struct _tagPyUFuncObject { */ #define PyUFunc_ReorderableNone -2 /* - * UFunc unit is in identity_value, and the order of operations can be reordered + * UFunc unit is an identity_value, and the order of operations can be reordered * This case allows reduction with multiple axes at once. */ #define PyUFunc_IdentityValue -3 diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index ac641c610..ab986caa1 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -4928,12 +4928,15 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi return NULL; } - ufunc = PyArray_malloc(sizeof(PyUFuncObject)); + ufunc = PyObject_GC_New(PyUFuncObject, &PyUFunc_Type); + /* + * We use GC_New here for ufunc->obj, but do not use GC_Track since + * ufunc->obj is still NULL at the end of this function. + * See ufunc_frompyfunc where ufunc->obj is set and GC_Track is called. + */ if (ufunc == NULL) { return NULL; } - memset(ufunc, 0, sizeof(PyUFuncObject)); - PyObject_Init((PyObject *)ufunc, &PyUFunc_Type); ufunc->nin = nin; ufunc->nout = nout; @@ -4941,13 +4944,30 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi ufunc->identity = identity; if (ufunc->identity == PyUFunc_IdentityValue) { Py_INCREF(identity_value); + ufunc->identity_value = identity_value; + } + else { + ufunc->identity_value = NULL; } - ufunc->identity_value = identity_value; ufunc->functions = func; ufunc->data = data; ufunc->types = types; ufunc->ntypes = ntypes; + ufunc->core_signature = NULL; + ufunc->core_enabled = 0; + ufunc->obj = NULL; + ufunc->core_num_dims = NULL; + ufunc->core_num_dim_ix = 0; + ufunc->core_offsets = NULL; + ufunc->core_dim_ixs = NULL; + ufunc->core_dim_sizes = NULL; + ufunc->core_dim_flags = NULL; + ufunc->userloops = NULL; + ufunc->ptr = NULL; + ufunc->reserved2 = NULL; + ufunc->reserved1 = 0; + ufunc->iter_flags = 0; /* Type resolution and inner loop selection functions */ ufunc->type_resolver = &PyUFunc_DefaultTypeResolver; @@ -5313,6 +5333,7 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, static void ufunc_dealloc(PyUFuncObject *ufunc) { + PyObject_GC_UnTrack((PyObject *)ufunc); PyArray_free(ufunc->core_num_dims); PyArray_free(ufunc->core_dim_ixs); PyArray_free(ufunc->core_dim_sizes); @@ -5322,11 +5343,13 @@ ufunc_dealloc(PyUFuncObject *ufunc) PyArray_free(ufunc->ptr); PyArray_free(ufunc->op_flags); Py_XDECREF(ufunc->userloops); - Py_XDECREF(ufunc->obj); if (ufunc->identity == PyUFunc_IdentityValue) { Py_DECREF(ufunc->identity_value); } - PyArray_free(ufunc); + if (ufunc->obj != NULL) { + Py_DECREF(ufunc->obj); + } + PyObject_GC_Del(ufunc); } static PyObject * @@ -5335,6 +5358,15 @@ ufunc_repr(PyUFuncObject *ufunc) return PyUString_FromFormat("<ufunc '%s'>", ufunc->name); } +static int +ufunc_traverse(PyUFuncObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->obj); + if (self->identity == PyUFunc_IdentityValue) { + Py_VISIT(self->identity_value); + } + return 0; +} /****************************************************************************** *** UFUNC METHODS *** @@ -6051,9 +6083,9 @@ NPY_NO_EXPORT PyTypeObject PyUFunc_Type = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - 0, /* tp_traverse */ + (traverseproc)ufunc_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c index 4d3151328..23e3ffcfc 100644 --- a/numpy/core/src/umath/umathmodule.c +++ b/numpy/core/src/umath/umathmodule.c @@ -161,6 +161,7 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUS self->type_resolver = &object_ufunc_type_resolver; self->legacy_inner_loop_selector = &object_ufunc_loop_selector; + PyObject_GC_Track(self); return (PyObject *)self; } |