Author: Alex Gaynor <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit