Author: Alex Gaynor <alex.gay...@gmail.com> Branch: unroll-if-alt Changeset: r46117:d190258333e1 Date: 2011-07-30 18:00 -0700 http://bitbucket.org/pypy/pypy/changeset/d190258333e1/
Log: Merged default. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -226,7 +226,8 @@ some += size >> 3 self.allocated = size + some new_buffer = lltype.malloc(mytype.arraytype, - self.allocated, flavor='raw') + self.allocated, flavor='raw', + track_allocation=False) for i in range(min(size, self.len)): new_buffer[i] = self.buffer[i] else: diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -187,17 +187,17 @@ def _getnums(self, comma): if self.find_size() > 1000: nums = [ - float2string(self.getitem(index)) + float2string(self.eval(index)) for index in range(3) ] nums.append("..." + "," * comma) nums.extend([ - float2string(self.getitem(index)) + float2string(self.eval(index)) for index in range(self.find_size() - 3, self.find_size()) ]) else: nums = [ - float2string(self.getitem(index)) + float2string(self.eval(index)) for index in range(self.find_size()) ] return nums @@ -229,7 +229,7 @@ start, stop, step, slice_length = space.decode_index4(w_idx, self.find_size()) if step == 0: # Single index - return space.wrap(self.get_concrete().getitem(start)) + return space.wrap(self.get_concrete().eval(start)) else: # Slice res = SingleDimSlice(start, stop, step, slice_length, self, self.signature.transition(SingleDimSlice.static_signature)) @@ -416,14 +416,12 @@ # in fact, ViewArray never gets "concrete" as it never stores data. # This implementation is needed for BaseArray getitem/setitem to work, # can be refactored. + self.parent.get_concrete() return self def eval(self, i): return self.parent.eval(self.calc_index(i)) - def getitem(self, item): - return self.parent.getitem(self.calc_index(item)) - @unwrap_spec(item=int, value=float) def setitem(self, item, value): return self.parent.setitem(self.calc_index(item), value) @@ -497,9 +495,6 @@ def descr_len(self, space): return space.wrap(self.size) - def getitem(self, item): - return self.storage[item] - def setitem(self, item, value): self.invalidated() self.storage[item] = value diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -70,6 +70,7 @@ from numpy import array, zeros a = array(range(5)) assert str(a) == "[0.0 1.0 2.0 3.0 4.0]" + assert str((2*a)[:]) == "[0.0 2.0 4.0 6.0 8.0]" a = zeros(1001) assert str(a) == "[0.0 0.0 0.0 ..., 0.0 0.0 0.0]" diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -63,6 +63,7 @@ i7 = int_gt(i4, 1) guard_true(i7, descr=...) p9 = call(ConstClass(fromint), i4, descr=...) + guard_no_exception(descr=...) p11 = call(ConstClass(rbigint.mul), p5, p9, descr=...) guard_no_exception(descr=...) i13 = int_sub(i4, 1) diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -154,7 +154,7 @@ x = 0x345678 z = len(wrappeditems) for w_item in wrappeditems: - y = space.int_w(space.hash(w_item)) + y = space.hash_w(w_item) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z 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 @@ -390,6 +390,11 @@ # initialize the threshold self.min_heap_size = max(self.min_heap_size, self.nursery_size * self.major_collection_threshold) + # the following two values are usually equal, but during raw mallocs + # of arrays, next_major_collection_threshold is decremented to make + # the next major collection arrive earlier. + # See translator/c/test/test_newgc, test_nongc_attached_to_gc + self.next_major_collection_initial = self.min_heap_size self.next_major_collection_threshold = self.min_heap_size self.set_major_threshold_from(0.0) debug_stop("gc-set-nursery-size") @@ -397,7 +402,7 @@ def set_major_threshold_from(self, threshold, reserving_size=0): # Set the next_major_collection_threshold. - threshold_max = (self.next_major_collection_threshold * + threshold_max = (self.next_major_collection_initial * self.growth_rate_max) if threshold > threshold_max: threshold = threshold_max @@ -412,6 +417,7 @@ else: bounded = False # + self.next_major_collection_initial = threshold self.next_major_collection_threshold = threshold return bounded @@ -718,9 +724,18 @@ def set_max_heap_size(self, size): self.max_heap_size = float(size) if self.max_heap_size > 0.0: + if self.max_heap_size < self.next_major_collection_initial: + self.next_major_collection_initial = self.max_heap_size if self.max_heap_size < self.next_major_collection_threshold: self.next_major_collection_threshold = self.max_heap_size + def raw_malloc_varsize_hint(self, sizehint): + self.next_major_collection_threshold -= sizehint + if self.next_major_collection_threshold < 0: + # cannot trigger a full collection now, but we can ensure + # that one will occur very soon + self.nursery_free = self.nursery_top + def can_malloc_nonmovable(self): return True @@ -1600,7 +1615,7 @@ # Max heap size: gives an upper bound on the threshold. If we # already have at least this much allocated, raise MemoryError. if bounded and (float(self.get_total_memory_used()) + reserving_size >= - self.next_major_collection_threshold): + self.next_major_collection_initial): # # First raise MemoryError, giving the program a chance to # quit cleanly. It might still allocate in the nursery, diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -386,6 +386,18 @@ else: self.malloc_varsize_nonmovable_ptr = None + if getattr(GCClass, 'raw_malloc_varsize_hint', False): + def raw_malloc_varsize_hint(length, itemsize): + totalmem = length * itemsize + if totalmem > 0: + gcdata.gc.raw_malloc_varsize_hint(totalmem) + #else: probably an overflow -- the following rawmalloc + # will fail then + self.raw_malloc_varsize_hint_ptr = getfn( + raw_malloc_varsize_hint, + [annmodel.SomeInteger(), annmodel.SomeInteger()], + annmodel.s_None, minimal_transform = False) + self.identityhash_ptr = getfn(GCClass.identityhash.im_func, [s_gc, s_gcref], annmodel.SomeInteger(), diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py --- a/pypy/rpython/memory/gctransform/transform.py +++ b/pypy/rpython/memory/gctransform/transform.py @@ -590,6 +590,16 @@ def gct_fv_raw_malloc_varsize(self, hop, flags, TYPE, v_length, c_const_size, c_item_size, c_offset_to_length): + track_allocation = flags.get('track_allocation', True) + if not track_allocation: + # idea: raw mallocs with track_allocation=False correspond + # generally to raw mallocs of stuff that we store in GC objects. + # So we tell the GC about such raw mallocs, so that it can + # adjust its total size estimate. + if hasattr(self, 'raw_malloc_varsize_hint_ptr'): + hop.genop("direct_call", + [self.raw_malloc_varsize_hint_ptr, + v_length, c_item_size]) if c_offset_to_length is None: if flags.get('zero'): fnptr = self.raw_malloc_varsize_no_length_zero_ptr @@ -605,7 +615,7 @@ [self.raw_malloc_varsize_ptr, v_length, c_const_size, c_item_size, c_offset_to_length], resulttype=llmemory.Address) - if flags.get('track_allocation', True): + if track_allocation: hop.genop("track_alloc_start", [v_raw]) return v_raw diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py --- a/pypy/translator/c/test/test_newgc.py +++ b/pypy/translator/c/test/test_newgc.py @@ -1390,6 +1390,34 @@ def test_gc_heap_stats(self): py.test.skip("not implemented") + def define_nongc_attached_to_gc(cls): + from pypy.rpython.lltypesystem import rffi + ARRAY = rffi.CArray(rffi.INT) + class A: + def __init__(self, n): + self.buf = lltype.malloc(ARRAY, n, flavor='raw', + track_allocation=False) + def __del__(self): + lltype.free(self.buf, flavor='raw', track_allocation=False) + def f(): + # allocate a total of ~77GB, but if the automatic gc'ing works, + # it should never need more than a few MBs at once + am1 = am2 = am3 = None + res = 0 + for i in range(1, 100001): + if am3 is not None: + res += rffi.cast(lltype.Signed, am3.buf[0]) + am3 = am2 + am2 = am1 + am1 = A(i * 4) + am1.buf[0] = rffi.cast(rffi.INT, i-50000) + return res + return f + + def test_nongc_attached_to_gc(self): + res = self.run("nongc_attached_to_gc") + assert res == -99997 + # ____________________________________________________________________ class TaggedPointersTest(object): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit