diff -r 12502327d2c0 Objects/listobject.c --- a/Objects/listobject.c Tue Feb 16 13:27:45 2016 +1100 +++ b/Objects/listobject.c Tue Feb 16 15:35:50 2016 +0200 @@ -38,6 +38,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 @@ -48,21 +60,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; @@ -166,7 +173,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(); @@ -322,7 +329,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; @@ -558,7 +565,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 @@ -632,7 +639,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; @@ -669,7 +676,7 @@ result = 0; Error: if (recycle != recycle_on_stack) - PyMem_FREE(recycle); + PyObject_FREE(recycle); Py_XDECREF(v_as_SF); return result; #undef b @@ -1437,7 +1444,7 @@ { assert(ms != NULL); if (ms->a.keys != ms->temparray) - PyMem_Free(ms->a.keys); + PyObject_FREE(ms->a.keys); } /* Ensure enough temp memory for 'need' array slots is available. @@ -1462,7 +1469,7 @@ PyErr_NoMemory(); return -1; } - ms->a.keys = (PyObject**)PyMem_Malloc(multiplier * need + ms->a.keys = (PyObject**)PyObject_MALLOC(multiplier * need * sizeof(PyObject *)); if (ms->a.keys != NULL) { ms->alloced = need; @@ -1954,7 +1961,7 @@ /* Leverage stack space we allocated but won't otherwise use */ keys = &ms.temparray[saved_ob_size+1]; else { - keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + keys = PyObject_MALLOC(sizeof(PyObject *) * saved_ob_size); if (keys == NULL) { PyErr_NoMemory(); goto keyfunc_fail; @@ -1968,7 +1975,7 @@ for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyObject_FREE(keys); goto keyfunc_fail; } } @@ -2041,7 +2048,7 @@ for (i = 0; i < saved_ob_size; i++) Py_DECREF(keys[i]); if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) - PyMem_FREE(keys); + PyObject_FREE(keys); } if (self->allocated != -1 && result != NULL) { @@ -2069,7 +2076,7 @@ while (--i >= 0) { Py_XDECREF(final_ob_item[i]); } - PyMem_FREE(final_ob_item); + PyObject_FREE(final_ob_item); } Py_XINCREF(result); return result; @@ -2495,7 +2502,7 @@ PY_SIZE_MAX / sizeof(PyObject*)); garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { PyErr_NoMemory(); return -1; @@ -2536,7 +2543,7 @@ for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); return res; } @@ -2576,7 +2583,7 @@ } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { Py_DECREF(seq); PyErr_NoMemory(); @@ -2597,7 +2604,7 @@ Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); Py_DECREF(seq); return 0;