Commit 40e4f131 authored by Stefan Behnel's avatar Stefan Behnel

Move less common ref-counting cases for memory views out of the fast-path and...

Move less common ref-counting cases for memory views out of the fast-path and only look up the atomic acquisition count value once per INC/DEC operation.
parent 6313c867
...@@ -483,18 +483,17 @@ __pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count, ...@@ -483,18 +483,17 @@ __pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
static CYTHON_INLINE void static CYTHON_INLINE void
__Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno) __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno)
{ {
int first_time; __pyx_atomic_int_type old_acquisition_count;
struct {{memview_struct_name}} *memview = memslice->memview; struct {{memview_struct_name}} *memview = memslice->memview;
if (unlikely(!memview || (PyObject *) memview == Py_None)) if (unlikely(!memview || (PyObject *) memview == Py_None)) {
return; /* allow uninitialized memoryview assignment */ // Allow uninitialized memoryview assignment and do not ref-count None.
return;
if (unlikely(__pyx_get_slice_count(memview) < 0)) }
__pyx_fatalerror("Acquisition count is %d (line %d)",
__pyx_get_slice_count(memview), lineno);
first_time = __pyx_add_acquisition_count(memview) == 0;
if (unlikely(first_time)) { old_acquisition_count = __pyx_add_acquisition_count(memview);
if (unlikely(old_acquisition_count <= 0)) {
if (likely(old_acquisition_count == 0)) {
// First acquisition => keep the memoryview object alive.
if (have_gil) { if (have_gil) {
Py_INCREF((PyObject *) memview); Py_INCREF((PyObject *) memview);
} else { } else {
...@@ -502,28 +501,31 @@ __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno) ...@@ -502,28 +501,31 @@ __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno)
Py_INCREF((PyObject *) memview); Py_INCREF((PyObject *) memview);
PyGILState_Release(_gilstate); PyGILState_Release(_gilstate);
} }
} else {
__pyx_fatalerror("Acquisition count is %d (line %d)",
__pyx_get_slice_count(memview), lineno);
}
} }
} }
static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice, static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
int have_gil, int lineno) { int have_gil, int lineno) {
int last_time; __pyx_atomic_int_type old_acquisition_count;
struct {{memview_struct_name}} *memview = memslice->memview; struct {{memview_struct_name}} *memview = memslice->memview;
if (unlikely(!memview || (PyObject *) memview == Py_None)) { if (unlikely(!memview || (PyObject *) memview == Py_None)) {
// we do not ref-count None // Do not ref-count None.
memslice->memview = NULL; memslice->memview = NULL;
return; return;
} }
if (unlikely(__pyx_get_slice_count(memview) <= 0)) old_acquisition_count = __pyx_sub_acquisition_count(memview);
__pyx_fatalerror("Acquisition count is %d (line %d)",
__pyx_get_slice_count(memview), lineno);
last_time = __pyx_sub_acquisition_count(memview) == 1;
memslice->data = NULL; memslice->data = NULL;
if (likely(old_acquisition_count > 1)) {
if (unlikely(last_time)) { // Still other slices out there => we do not own the reference.
memslice->memview = NULL;
} else if (likely(old_acquisition_count == 1)) {
// Last slice => discard owned Python reference to memoryview object.
if (have_gil) { if (have_gil) {
Py_CLEAR(memslice->memview); Py_CLEAR(memslice->memview);
} else { } else {
...@@ -532,7 +534,8 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice, ...@@ -532,7 +534,8 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
PyGILState_Release(_gilstate); PyGILState_Release(_gilstate);
} }
} else { } else {
memslice->memview = NULL; __pyx_fatalerror("Acquisition count is %d (line %d)",
__pyx_get_slice_count(memview), lineno);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment