[pypy-svn] r70851 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem memory memory/gc memory/gc/test memory/gctransform
arigo at codespeak.net
arigo at codespeak.net
Mon Jan 25 19:54:09 CET 2010
Author: arigo
Date: Mon Jan 25 19:54:08 2010
New Revision: 70851
Modified:
pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py
pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py
pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py
pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py
pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py
pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py
Log:
Shrink the arrays in-place, if they are living in the
main gc space.
Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py Mon Jan 25 19:54:08 2010
@@ -1528,6 +1528,9 @@
def getlength(self):
return len(self.items)
+ def shrinklength(self, newlength):
+ del self.items[newlength:]
+
def getbounds(self):
stop = len(self.items)
return 0, stop
@@ -1658,7 +1661,9 @@
def setitem(self, index, value):
assert index == 0
if value != self.array.getlength():
- raise Exception("can't change the length of an array")
+ if value > self.array.getlength():
+ raise Exception("can't grow an array in-place")
+ self.array.shrinklength(value)
def _makeptr(array, solid=False):
try:
Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Mon Jan 25 19:54:08 2010
@@ -210,10 +210,6 @@
raise NotImplementedError("Not supported")
return llmemory.cast_ptr_to_adr(gcref)
- #def realloc(self, ...):
- # here we can write a bit more sophisticated realloc, that cares
- # about rawmalloced objects
-
def can_move(self, addr):
tid = self.header(addr).tid
return not (tid & GCFLAG_EXTERNAL)
Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py Mon Jan 25 19:54:08 2010
@@ -119,6 +119,15 @@
self.free = result + llarena.round_up_for_allocation(totalsize)
return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
+ def shrink_array(self, addr, smallersize):
+ if self._is_in_the_space(addr):
+ typeid = self.get_type_id(addr)
+ offset_to_length = self.varsize_offset_to_length(typeid)
+ (addr + offset_to_length).signed[0] = smallersize
+ return True
+ else:
+ return False
+
def obtain_free_space(self, needed):
# a bit of tweaking to maximize the performance and minimize the
# amount of code in an inlined version of malloc_fixedsize_clear()
@@ -572,6 +581,9 @@
def _is_external(self, obj):
return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0
+ def _is_in_the_space(self, obj):
+ return self.tospace <= obj < self.free
+
def debug_check_object(self, obj):
"""Check the invariants about 'obj' that should be true
between collections."""
Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py Mon Jan 25 19:54:08 2010
@@ -268,6 +268,22 @@
class TestSemiSpaceGC(DirectGCTest):
from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass
+ def test_shrink_array(self):
+ S1 = lltype.GcStruct('S1', ('h', lltype.Char),
+ ('v', lltype.Array(lltype.Char)))
+ p1 = self.malloc(S1, 2)
+ p1.h = '?'
+ for i in range(2):
+ p1.v[i] = chr(50 + i)
+ addr = llmemory.cast_ptr_to_adr(p1)
+ ok = self.gc.shrink_array(addr, 1)
+ assert ok
+ assert p1.h == '?'
+ assert len(p1.v) == 1
+ for i in range(1):
+ assert p1.v[i] == chr(50 + i)
+
+
class TestGenerationGC(TestSemiSpaceGC):
from pypy.rpython.memory.gc.generation import GenerationGC as GCClass
@@ -358,7 +374,7 @@
gc.collect(9)
assert calls == [('semispace_collect', True)]
- calls = []
+ calls = []
class TestMarkCompactGC(DirectGCTest):
Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Mon Jan 25 19:54:08 2010
@@ -563,80 +563,6 @@
def gct_malloc_nonmovable_varsize(self, *args, **kwds):
return self.gct_malloc_varsize(*args, **kwds)
- def gct_malloc_resizable_buffer(self, hop):
- flags = hop.spaceop.args[1].value
- flags['varsize'] = True
- flags['nonmovable'] = True
- flags['resizable'] = True
- flavor = flags['flavor']
- assert flavor != 'cpy', "cannot malloc CPython objects directly"
- meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None)
- assert meth, "%s has no support for malloc_varsize with flavor %r" % (self, flavor)
- return self.varsize_malloc_helper(hop, flags, meth, [])
-
- def gct_resize_buffer(self, hop):
- op = hop.spaceop
- # if we want to support a general realloc, support goes here
- self._malloc_and_copy(hop, op.args[1], op.args[2])
-
- # def _malloc_and_copy(self, hop, v_oldsize, v_newsize, grow=True):
- # def intconst(c): return rmodel.inputconst(lltype.Signed, c)
- # op = hop.spaceop
- # flags = {'flavor':'gc', 'varsize': True}
- # TYPE = op.args[0].concretetype.TO
- # ARRAY = TYPE._flds[TYPE._arrayfld]
- # offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \
- # llmemory.ArrayLengthOffset(ARRAY)
- # c_const_size = intconst(llmemory.sizeof(TYPE, 0))
- # c_item_size = intconst(llmemory.sizeof(ARRAY.OF))
-
- # c_lengthofs = intconst(offset_to_length)
- # c_itemsofs = intconst(llmemory.itemoffsetof(TYPE, 0))
- # v_ptr = op.args[0]
- # v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr)
- # c_grow = rmodel.inputconst(lltype.Bool, grow)
- # v_raw = self.perform_realloc(hop, v_ptr, v_oldsize, v_newsize,
- # c_const_size, c_item_size, c_lengthofs,
- # c_itemsofs, c_grow)
- # hop.cast_result(v_raw)
-
- def _malloc_and_copy(self, hop, v_lgt):
- op = hop.spaceop
- meth = self.gct_fv_gc_malloc_varsize
- flags = {'flavor':'gc', 'varsize': True, 'keep_current_args': True}
- self.varsize_malloc_helper(hop, flags, meth, [])
- # fish resvar
- v_newbuf = hop.llops[-1].result
- v_src = op.args[0]
- TYPE = v_src.concretetype.TO
- c_fldname = rmodel.inputconst(lltype.Void, TYPE._arrayfld)
- v_adrsrc = hop.genop('cast_ptr_to_adr', [v_src],
- resulttype=llmemory.Address)
- v_adrnewbuf = hop.genop('cast_ptr_to_adr', [v_newbuf],
- resulttype=llmemory.Address)
- ofs = (llmemory.offsetof(TYPE, TYPE._arrayfld) +
- llmemory.itemoffsetof(getattr(TYPE, TYPE._arrayfld), 0))
- v_ofs = rmodel.inputconst(lltype.Signed, ofs)
- v_adrsrc = hop.genop('adr_add', [v_adrsrc, v_ofs],
- resulttype=llmemory.Address)
- v_adrnewbuf = hop.genop('adr_add', [v_adrnewbuf, v_ofs],
- resulttype=llmemory.Address)
- size = llmemory.sizeof(getattr(TYPE, TYPE._arrayfld).OF)
- c_size = rmodel.inputconst(lltype.Signed, size)
- v_lgtsym = hop.genop('int_mul', [c_size, v_lgt],
- resulttype=lltype.Signed)
- vlist = [v_adrsrc, v_adrnewbuf, v_lgtsym]
- hop.genop('raw_memcopy', vlist)
-
- def gct_finish_building_buffer(self, hop):
- xxx
- op = hop.spaceop
- if self._can_realloc():
- return self._gct_resize_buffer_realloc(hop, op.args[1],
- op.args[2], False)
- else:
- return self._gct_resize_buffer_no_realloc(hop, op.args[1])
-
def varsize_malloc_helper(self, hop, flags, meth, extraargs):
def intconst(c): return rmodel.inputconst(lltype.Signed, c)
op = hop.spaceop
@@ -697,3 +623,6 @@
def gct_gc_can_move(self, hop):
return hop.cast_result(rmodel.inputconst(lltype.Bool, False))
+
+ def gct_shrink_array(self, hop):
+ return hop.cast_result(rmodel.inputconst(lltype.Bool, False))
Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py (original)
+++ pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Mon Jan 25 19:54:08 2010
@@ -59,6 +59,9 @@
return result
def shrink_array(self, p, smallersize):
+ if hasattr(self.gc, 'shrink_array'):
+ addr = llmemory.cast_ptr_to_adr(p)
+ return self.gc.shrink_array(addr, smallersize)
return False
def free(self, TYPE, flavor='gc'):
More information about the Pypy-commit
mailing list