summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/arrayobject.c2
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src7
-rw-r--r--numpy/core/src/multiarray/buffer.c4
-rw-r--r--numpy/core/src/multiarray/buffer.h2
-rw-r--r--numpy/core/src/multiarray/common.c10
-rw-r--r--numpy/core/src/multiarray/conversion_utils.c2
-rw-r--r--numpy/core/src/multiarray/ctors.c4
-rw-r--r--numpy/core/src/multiarray/descriptor.c2
-rw-r--r--numpy/core/src/multiarray/getset.c3
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src2
10 files changed, 31 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c
index 341682588..936a30426 100644
--- a/numpy/core/src/multiarray/arrayobject.c
+++ b/numpy/core/src/multiarray/arrayobject.c
@@ -471,7 +471,7 @@ array_dealloc(PyArrayObject *self)
{
PyArrayObject_fields *fa = (PyArrayObject_fields *)self;
- _array_dealloc_buffer_info(self);
+ _dealloc_cached_buffer_info((PyObject*)self);
if (fa->weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *)self);
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index 46a3ffb3d..d3aa1bd92 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -2,7 +2,8 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
-
+#include <limits.h>
+#include <assert.h>
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE
@@ -34,8 +35,7 @@
#include "cblasfuncs.h"
#include "npy_cblas.h"
-#include <limits.h>
-#include <assert.h>
+#include "buffer.h"
/* check for sequences, but ignore the types numpy considers scalars */
static NPY_INLINE npy_bool
@@ -921,6 +921,7 @@ VOID_setitem(PyObject *op, void *input, void *vap)
memset(ip + view.len, 0, itemsize - view.len);
}
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(op);
}
#else
{
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index 9a2750aea..2f66d7f2f 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -922,7 +922,7 @@ fail:
*/
NPY_NO_EXPORT void
-_array_dealloc_buffer_info(PyArrayObject *self)
+_dealloc_cached_buffer_info(PyObject *self)
{
int reset_error_state = 0;
PyObject *ptype, *pvalue, *ptraceback;
@@ -936,7 +936,7 @@ _array_dealloc_buffer_info(PyArrayObject *self)
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
}
- _buffer_clear_info((PyObject*)self);
+ _buffer_clear_info(self);
if (reset_error_state) {
PyErr_Restore(ptype, pvalue, ptraceback);
diff --git a/numpy/core/src/multiarray/buffer.h b/numpy/core/src/multiarray/buffer.h
index d5da8f440..fae413c85 100644
--- a/numpy/core/src/multiarray/buffer.h
+++ b/numpy/core/src/multiarray/buffer.h
@@ -4,7 +4,7 @@
extern NPY_NO_EXPORT PyBufferProcs array_as_buffer;
NPY_NO_EXPORT void
-_array_dealloc_buffer_info(PyArrayObject *self);
+_dealloc_cached_buffer_info(PyObject *self);
NPY_NO_EXPORT PyArray_Descr*
_descriptor_from_pep3118_format(char *s);
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 5b4611e8a..65a290770 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -312,6 +312,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
PyErr_Clear();
dtype = _descriptor_from_pep3118_format(buffer_view.format);
PyBuffer_Release(&buffer_view);
+ _dealloc_cached_buffer_info(obj);
if (dtype) {
goto promote_types;
}
@@ -323,6 +324,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
dtype = PyArray_DescrNewFromType(NPY_VOID);
dtype->elsize = buffer_view.itemsize;
PyBuffer_Release(&buffer_view);
+ _dealloc_cached_buffer_info(obj);
goto promote_types;
}
else {
@@ -636,6 +638,14 @@ _IsWriteable(PyArrayObject *ap)
return NPY_FALSE;
}
PyBuffer_Release(&view);
+ /*
+ * The first call to PyObject_GetBuffer stores a reference to a struct
+ * _buffer_info_t (from buffer.c, with format, ndim, strides and shape) in
+ * a static dictionary, with id(base) as the key. Usually we release it
+ * after the call to PyBuffer_Release, via a call to
+ * _dealloc_cached_buffer_info, but in this case leave it in the cache to
+ * speed up future calls to _IsWriteable.
+ */
#else
if (PyObject_AsWriteBuffer(base, &dummy, &n) < 0) {
PyErr_Clear();
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index 7e92e5991..cef3c27ed 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -16,6 +16,7 @@
#include "conversion_utils.h"
#include "alloc.h"
+#include "buffer.h"
static int
PyArray_PyIntAsInt_ErrMsg(PyObject *o, const char * msg) NPY_GCC_NONNULL(2);
@@ -185,6 +186,7 @@ PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
* sticks around after the release.
*/
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(obj);
/* Point to the base of the buffer object if present */
if (PyMemoryView_Check(obj)) {
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index bf888659d..23a8dcea2 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -743,12 +743,14 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it,
d[i] = buffer_view.shape[i];
}
PyBuffer_Release(&buffer_view);
+ _dealloc_cached_buffer_info(obj);
return 0;
}
else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) {
d[0] = buffer_view.len;
*maxndim = 1;
PyBuffer_Release(&buffer_view);
+ _dealloc_cached_buffer_info(obj);
return 0;
}
else {
@@ -2463,6 +2465,7 @@ PyArray_FromInterface(PyObject *origin)
* sticks around after the release.
*/
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(base);
#else
res = PyObject_AsWriteBuffer(base, (void **)&data, &buffer_len);
if (res < 0) {
@@ -3718,6 +3721,7 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type,
* sticks around after the release.
*/
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(buf);
#else
if (PyObject_AsWriteBuffer(buf, (void *)&data, &ts) == -1) {
writeable = 0;
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 7acac8059..b9be3c09f 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -19,6 +19,7 @@
#include "descriptor.h"
#include "alloc.h"
#include "assert.h"
+#include "buffer.h"
/*
* offset: A starting offset.
@@ -1760,6 +1761,7 @@ arraydescr_dealloc(PyArray_Descr *self)
Py_INCREF(self);
return;
}
+ _dealloc_cached_buffer_info((PyObject*)self);
Py_XDECREF(self->typeobj);
Py_XDECREF(self->names);
Py_XDECREF(self->fields);
diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c
index cae4273ff..24962da8a 100644
--- a/numpy/core/src/multiarray/getset.c
+++ b/numpy/core/src/multiarray/getset.c
@@ -20,6 +20,7 @@
#include "arrayobject.h"
#include "mem_overlap.h"
#include "alloc.h"
+#include "buffer.h"
/******************* array attribute get and set routines ******************/
@@ -143,6 +144,7 @@ array_strides_set(PyArrayObject *self, PyObject *obj)
offset = PyArray_BYTES(self) - (char *)view.buf;
numbytes = view.len + offset;
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info((PyObject*)new);
}
#else
if (PyArray_BASE(new) &&
@@ -376,6 +378,7 @@ array_data_set(PyArrayObject *self, PyObject *op)
* sticks around after the release.
*/
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(op);
#else
if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) {
PyErr_Clear();
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index 6dd8b1a29..0f201b966 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -139,6 +139,7 @@ gentype_alloc(PyTypeObject *type, Py_ssize_t nitems)
static void
gentype_dealloc(PyObject *v)
{
+ _dealloc_cached_buffer_info(v);
Py_TYPE(v)->tp_free(v);
}
@@ -1858,6 +1859,7 @@ gentype_reduce(PyObject *self, PyObject *NPY_UNUSED(args))
* sticks around after the release.
*/
PyBuffer_Release(&view);
+ _dealloc_cached_buffer_info(self);
}
else {
Py_DECREF(ret);