diff -r d87771d1c1e6 Objects/listobject.c --- a/Objects/listobject.c Wed Dec 28 10:16:06 2016 +0200 +++ b/Objects/listobject.c Wed Dec 28 22:24:22 2016 +0900 @@ -34,37 +34,44 @@ */ if (allocated >= newsize && newsize >= (allocated >> 1)) { assert(self->ob_item != NULL || newsize == 0); 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 * enough to give linear-time amortized behavior over a long * sequence of appends() in the presence of a poorly-performing * system realloc(). * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... */ 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; } self->ob_item = items; Py_SIZE(self) = newsize; @@ -146,13 +153,13 @@ count_alloc++; #endif } 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(); } memset(op->ob_item, 0, nbytes); } @@ -305,13 +312,13 @@ thrashing when a *very* large list is created and immediately deleted. */ i = Py_SIZE(op); 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; else Py_TYPE(op)->tp_free((PyObject *)op); Py_TRASHCAN_SAFE_END(op) @@ -593,13 +600,13 @@ Py_SIZE(a) = 0; a->ob_item = NULL; a->allocated = 0; 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 at this point, because XDECREF may have populated it again! */ return 0; } @@ -669,13 +676,13 @@ item = a->ob_item; /* recycle the items that we are about to remove */ s = norig * sizeof(PyObject *); /* If norig == 0, item might be NULL, in which case we may not memcpy from it. */ if (s) { if (s > sizeof(recycle_on_stack)) { - recycle = (PyObject **)PyMem_MALLOC(s); + recycle = (PyObject **)PyObject_MALLOC(s); if (recycle == NULL) { PyErr_NoMemory(); goto Error; } } memcpy(recycle, &item[ilow], s); @@ -702,13 +709,13 @@ } for (k = norig - 1; k >= 0; --k) Py_XDECREF(recycle[k]); result = 0; Error: if (recycle != recycle_on_stack) - PyMem_FREE(recycle); + PyObject_FREE(recycle); Py_XDECREF(v_as_SF); return result; #undef b } int @@ -1414,13 +1421,13 @@ */ static void merge_freemem(MergeState *ms) { 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; } /* Ensure enough temp memory for 'need' array slots is available. * Returns 0 on success and -1 if the memory can't be gotten. @@ -1436,13 +1443,13 @@ */ merge_freemem(ms); if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) { 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; } PyErr_NoMemory(); merge_freemem(ms); /* reset to sane state */ @@ -2203,13 +2210,13 @@ if (final_ob_item != NULL) { /* we cannot use list_clear() for this because it does not guarantee that the list is really empty when it returns */ 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); return result; } #undef IFLT @@ -2641,13 +2648,13 @@ } assert((size_t)slicelength <= PY_SIZE_MAX / sizeof(PyObject*)); garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { PyErr_NoMemory(); return -1; } /* drawing pictures might help understand these for @@ -2682,13 +2689,13 @@ Py_SIZE(self) -= slicelength; list_resize(self, Py_SIZE(self)); for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); return 0; } else { /* assign slice */ PyObject *ins, *seq; @@ -2722,13 +2729,13 @@ if (!slicelength) { Py_DECREF(seq); return 0; } garbage = (PyObject**) - PyMem_MALLOC(slicelength*sizeof(PyObject*)); + PyObject_MALLOC(slicelength*sizeof(PyObject*)); if (!garbage) { Py_DECREF(seq); PyErr_NoMemory(); return -1; } @@ -2743,13 +2750,13 @@ } for (i = 0; i < slicelength; i++) { Py_DECREF(garbage[i]); } - PyMem_FREE(garbage); + PyObject_FREE(garbage); Py_DECREF(seq); return 0; } } else {