Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r46198:d24ebc2e9708 Date: 2011-08-02 14:30 +0200 http://bitbucket.org/pypy/pypy/changeset/d24ebc2e9708/
Log: merge diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py --- a/pypy/rpython/lltypesystem/rlist.py +++ b/pypy/rpython/lltypesystem/rlist.py @@ -14,7 +14,6 @@ from pypy.rpython.lltypesystem import rstr from pypy.rpython import robject from pypy.rlib.debug import ll_assert -from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.lltypesystem import rffi from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib import rgc @@ -200,12 +199,11 @@ else: some = 6 some += newsize >> 3 - try: - new_allocated = ovfcheck(newsize + some) - except OverflowError: - raise MemoryError + new_allocated = newsize + some # new_allocated is a bit more than newsize, enough to ensure an amortized - # linear complexity for e.g. repeated usage of l.append(). + # linear complexity for e.g. repeated usage of l.append(). In case + # it overflows sys.maxint, it is guaranteed negative, and the following + # malloc() will fail. items = l.items newitems = malloc(typeOf(l).TO.items.TO, new_allocated) before_len = l.length diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -345,6 +345,8 @@ def ll_strconcat(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) + # a single '+' like this is allowed to overflow: it gets + # a negative result, and the gc will complain newstr = s1.malloc(len1 + len2) s1.copy_contents(s1, newstr, 0, 0, len1) s1.copy_contents(s2, newstr, 0, len1, len2) @@ -412,9 +414,18 @@ itemslen = 0 i = 0 while i < num_items: - itemslen += len(items[i].chars) + try: + itemslen = ovfcheck(itemslen + len(items[i].chars)) + except OverflowError: + raise MemoryError i += 1 - result = s.malloc(itemslen + s_len * (num_items - 1)) + try: + seplen = ovfcheck(s_len * (num_items - 1)) + except OverflowError: + raise MemoryError + # a single '+' at the end is allowed to overflow: it gets + # a negative result, and the gc will complain + result = s.malloc(itemslen + seplen) res_index = len(items[0].chars) s.copy_contents(items[0], result, 0, 0, res_index) i = 1 @@ -688,7 +699,10 @@ itemslen = 0 i = 0 while i < num_items: - itemslen += len(items[i].chars) + try: + itemslen = ovfcheck(itemslen + len(items[i].chars)) + except OverflowError: + raise MemoryError i += 1 if typeOf(items).TO.OF.TO == STR: malloc = mallocstr diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py --- a/pypy/rpython/memory/gc/minimark.py +++ b/pypy/rpython/memory/gc/minimark.py @@ -517,17 +517,19 @@ # constant-folded because self.nonlarge_max, size and itemsize # are all constants (the arguments are constant due to # inlining). - if not raw_malloc_usage(itemsize): - too_many_items = raw_malloc_usage(nonvarsize) > self.nonlarge_max + maxsize = self.nonlarge_max - raw_malloc_usage(nonvarsize) + if maxsize < 0: + toobig = r_uint(0) # the nonvarsize alone is too big + elif raw_malloc_usage(itemsize): + toobig = r_uint(maxsize // raw_malloc_usage(itemsize)) + 1 else: - maxlength = self.nonlarge_max - raw_malloc_usage(nonvarsize) - maxlength = maxlength // raw_malloc_usage(itemsize) - too_many_items = length > maxlength + toobig = r_uint(sys.maxint) + 1 - if too_many_items: + if r_uint(length) >= r_uint(toobig): # # If the total size of the object would be larger than - # 'nonlarge_max', then allocate it externally. + # 'nonlarge_max', then allocate it externally. We also + # go there if 'length' is actually negative. obj = self.external_malloc(typeid, length) # else: @@ -610,13 +612,18 @@ # this includes the case of fixed-size objects, for which we # should not even ask for the varsize_item_sizes(). totalsize = nonvarsize - else: + elif length > 0: + # var-sized allocation with at least one item itemsize = self.varsize_item_sizes(typeid) try: varsize = ovfcheck(itemsize * length) totalsize = ovfcheck(nonvarsize + varsize) except OverflowError: raise MemoryError + else: + # negative length! This likely comes from an overflow + # earlier. We will just raise MemoryError here. + raise MemoryError # # If somebody calls this function a lot, we must eventually # force a full collection. _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit