[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