diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py index 138297bef18..54ccb263e10 100644 --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -159,6 +159,10 @@ def __del__(self): lltype.free(self._buffer, flavor='raw') def setlen(self, size, zero=False, overallocate=True): + if self._buffer: + delta_memory_pressure = -self.allocated * self.itemsize + else: + delta_memory_pressure = 0 if size > 0: if size > self.allocated or size < self.allocated / 2: if overallocate: @@ -171,14 +175,13 @@ def setlen(self, size, zero=False, overallocate=True): some = 0 self.allocated = size + some byte_size = self.allocated * self.itemsize + delta_memory_pressure += byte_size if zero: new_buffer = lltype.malloc( - rffi.CCHARP.TO, byte_size, flavor='raw', - add_memory_pressure=True, zero=True) + rffi.CCHARP.TO, byte_size, flavor='raw', zero=True) else: new_buffer = lltype.malloc( - rffi.CCHARP.TO, byte_size, flavor='raw', - add_memory_pressure=True) + rffi.CCHARP.TO, byte_size, flavor='raw') copy_bytes = min(size, self.len) * self.itemsize rffi.c_memcpy(rffi.cast(rffi.VOIDP, new_buffer), rffi.cast(rffi.VOIDP, self._buffer), @@ -195,6 +198,11 @@ def setlen(self, size, zero=False, overallocate=True): lltype.free(self._buffer, flavor='raw') self._buffer = new_buffer self.len = size + # adds the difference between the old and the new raw-malloced + # size. If setlen() is called a lot on the same array object, + # it is important to take into account the fact that we also do + # lltype.free() above. + rgc.add_memory_pressure(delta_memory_pressure) def _fromiterable(self, w_seq): # used by fromsequence(). @@ -239,8 +247,10 @@ def delitem(self, space, i, j): return None oldbuffer = self._buffer self._buffer = lltype.malloc(rffi.CCHARP.TO, - (self.len - (j - i)) * self.itemsize, flavor='raw', - add_memory_pressure=True) + (self.len - (j - i)) * self.itemsize, flavor='raw') + # Issue #2913: don't pass add_memory_pressure here, otherwise + # memory pressure grows but actual raw memory usage doesn't---we + # are freeing the old buffer at the end of this function. if i: rffi.c_memcpy( rffi.cast(rffi.VOIDP, self._buffer),