diff -r 58ebfa7c1361 Objects/listobject.c --- a/Objects/listobject.c Mon Feb 15 16:51:24 2016 +1100 +++ b/Objects/listobject.c Tue Feb 16 15:38:47 2016 +0200 @@ -37,6 +37,18 @@ Py_SIZE(self) = newsize; return 0; } + + /* resize to zero: free up space used by the ob_item array, update + structure accordingly and return + */ + if (newsize == 0) { + PyObject_FREE(self->ob_item); + self->ob_item = NULL; + self->allocated = 0; + Py_SIZE(self) = 0; + + return 0; + } /* This over-allocates proportional to the list size, making room * for additional growth. The over-allocation is mild, but is @@ -47,21 +59,16 @@ */ new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); - /* check for integer overflow */ - if (new_allocated > PY_SIZE_MAX - newsize) { + /* check for integer overflow by keeping in mind that new_allocated will + be multiplied by sizeof(PyObject*) */ + if (new_allocated > (PY_SIZE_MAX - newsize) / sizeof(PyObject*)) { PyErr_NoMemory(); return -1; - } else { - new_allocated += newsize; } - - if (newsize == 0) - new_allocated = 0; - items = self->ob_item; - if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *))) - PyMem_RESIZE(items, PyObject *, new_allocated); - else - items = NULL; + + new_allocated += newsize; + items = self->ob_item; + items = PyObject_REALLOC(items, new_allocated * sizeof(PyObject*)); if (items == NULL) { PyErr_NoMemory(); return -1; @@ -149,7 +156,7 @@ if (size <= 0) op->ob_item = NULL; else { - op->ob_item = (PyObject **) PyMem_MALLOC(nbytes); + op->ob_item = (PyObject **) PyObject_MALLOC(nbytes); if (op->ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory(); @@ -308,7 +315,7 @@ while (--i >= 0) { Py_XDECREF(op->ob_item[i]); } - PyMem_FREE(op->ob_item); + PyObject_FREE(op->ob_item); } if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) free_list[numfree++] = op; @@ -596,7 +603,7 @@ while (--i >= 0) { Py_XDECREF(item[i]); } - PyMem_FREE(item); + PyObject_FREE(item); } /* Never fails; the return value can be ignored. Note that there is no guarantee that the list is actually empty @@ -670,7 +677,7 @@ /* recycle the items that we are about to remove */ s = norig * sizeof(PyObject *); if (s > sizeof(recycle_on_stack)) { - recycle = (PyObject **)PyMem_MALLOC(s); + recycle = (PyObject **)PyObject_MALLOC(s); if (recycle == NULL) { PyErr_NoMemory(); goto Error; @@ -702,7 +709,7 @@ result = 0; Error: if (recycle != recycle_on_stack) - PyMem_FREE(recycle); + PyObject_FREE(recycle); Py_XDECREF(v_as_SF); return result; #undef b @@ -1414,7 +1421,7 @@ { assert(ms != NULL); if (ms->a != ms->temparray) - PyMem_Free(ms->a); + PyObject_Free(ms->a); ms->a = ms->temparray; ms->alloced = MERGESTATE_TEMP_SIZE; } @@ -1436,7 +1443,7 @@ PyErr_NoMemory(); return -1; } - ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*)); + ms->a = (PyObject **)PyObject_MALLOC(need * sizeof(PyObject*)); if (ms->a) { ms->alloced = need; return 0; @@ -2203,7 +2210,7 @@ while (--i >= 0) { Py_XDECREF(final_ob_item[i]); } - PyMem_FREE(final_ob_item); + PyObject_FREE(final_ob_item); } Py_XDECREF(compare); Py_XINCREF(result); @@ -2641,7 +2648,7 @@ PY_SIZE_MAX / sizeof(PyObject*)); garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { PyErr_NoMemory(); return -1; @@ -2682,7 +2689,7 @@ for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); return 0; } @@ -2722,7 +2729,7 @@ } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { Py_DECREF(seq); PyErr_NoMemory(); @@ -2743,7 +2750,7 @@ Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); Py_DECREF(seq); return 0;