[pypy-svn] r54671 - in pypy/branch/hybrid-io/pypy/rpython/memory: gc gctransform

fijal at codespeak.net fijal at codespeak.net
Mon May 12 13:40:24 CEST 2008


Author: fijal
Date: Mon May 12 13:40:23 2008
New Revision: 54671

Modified:
   pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py
   pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/boehm.py
   pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/transform.py
Log:
Implement resizable buffer on top of hybrid gc. Test seems to pass,
but realloc ops are not implemented on top of C backend.


Modified: pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py	Mon May 12 13:40:23 2008
@@ -10,6 +10,7 @@
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.debug import ll_assert
 from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rpython.lltypesystem import rffi
 
 #   _______in the semispaces_________      ______external (non-moving)_____
 #  /                                 \    /                                \
@@ -68,7 +69,6 @@
 # number of calls to semispace_collect():
 GENERATION3_COLLECT_THRESHOLD = 20
 
-
 class HybridGC(GenerationGC):
     """A two-generations semi-space GC like the GenerationGC,
     except that objects above a certain size are handled separately:
@@ -76,6 +76,7 @@
     """
     first_unused_gcflag = _gcflag_next_bit
     prebuilt_gc_objects_are_static_roots = True
+    can_realloc = True
 
     # the following values override the default arguments of __init__ when
     # translating to a real backend.
@@ -211,6 +212,29 @@
             raise NotImplementedError("Not supported")
         return llmemory.cast_ptr_to_adr(gcref)
 
+    def realloc(self, ptr, newsize, const_size, itemsize, lengthofs, grow):
+        size_gc_header = self.size_gc_header()
+        addr = llmemory.cast_ptr_to_adr(ptr)
+        tid = self.get_type_id(addr)
+        tot_size = size_gc_header + const_size + newsize * itemsize
+        oldsize = (addr + lengthofs).signed[0]
+        old_tot_size = size_gc_header + const_size + oldsize * itemsize
+        source_addr = addr - size_gc_header
+        if grow:
+            result = llop.raw_realloc_grow(llmemory.Address, source_addr,
+                                           old_tot_size, tot_size)
+        else:
+            result = llop.raw_realloc_shrink(llmemory.Address, source_addr,
+                                             old_tot_size, tot_size)
+        if not result:
+            raise MemoryError()
+        if result != addr:
+            flags = self.GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS | GCFLAG_UNVISITED
+            self.gen2_rawmalloced_objects.append(result)
+            self.init_gc_object(result, tid, flags)
+        (result + size_gc_header + lengthofs).signed[0] = newsize
+        return llmemory.cast_adr_to_ptr(result + size_gc_header, llmemory.GCREF)
+
     def can_move(self, addr):
         tid = self.header(addr).tid
         return not (tid & GCFLAG_EXTERNAL)

Modified: pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/boehm.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/boehm.py	Mon May 12 13:40:23 2008
@@ -64,7 +64,7 @@
         return True
 
     def perform_realloc(self, hop, v_ptr, v_newlgt, c_const_size, c_item_size,
-                        c_lengthofs):
+                        c_lengthofs, c_grow):
         args = [self.realloc_ptr, v_ptr, v_newlgt, c_const_size,
                 c_item_size, c_lengthofs]
         return hop.genop('direct_call', args, resulttype=llmemory.Address)

Modified: pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/framework.py	Mon May 12 13:40:23 2008
@@ -284,6 +284,14 @@
         else:
             self.malloc_varsize_nonmovable_ptr = None
 
+        if getattr(GCClass, 'realloc', False):
+            self.realloc_ptr = getfn(
+                GCClass.realloc.im_func,
+                [s_gc, s_gcref] +
+                [annmodel.SomeInteger(nonneg=True)] * 4 +
+                [annmodel.SomeBool()],
+                s_gcref)
+
         if GCClass.moving_gc:
             self.id_ptr = getfn(GCClass.id.im_func,
                                 [s_gc, s_gcref], annmodel.SomeInteger(),
@@ -508,6 +516,16 @@
     def _can_realloc(self):
         return self.gcdata.gc.can_realloc
 
+    def perform_realloc(self, hop, v_ptr, v_newsize, c_const_size,
+                        c_itemsize, c_lengthofs, c_grow):
+        vlist = [self.realloc_ptr, self.c_const_gc, v_ptr, v_newsize,
+                 c_const_size, c_itemsize, c_lengthofs, c_grow]
+        livevars = self.push_roots(hop)
+        v_result = hop.genop('direct_call', vlist,
+                             resulttype=llmemory.GCREF)
+        self.pop_roots(hop, livevars)
+        return v_result
+
     def gct_gc__disable_finalizers(self, hop):
         # cannot collect()
         op = hop.spaceop

Modified: pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/transform.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/gctransform/transform.py	Mon May 12 13:40:23 2008
@@ -539,6 +539,7 @@
     def gct_malloc_resizable_buffer(self, hop):
         flags = hop.spaceop.args[1].value
         flags['varsize'] = True
+        flags['nonmovable'] = True
         flavor = flags['flavor']
         assert flavor != 'cpy', "cannot malloc CPython objects directly"
         meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None)
@@ -548,14 +549,14 @@
     def gct_resize_buffer(self, hop):
         op = hop.spaceop
         if self._can_realloc():
-            self._gct_resize_buffer_realloc(hop, op.args[2])
+            self._gct_resize_buffer_realloc(hop, op.args[2], True)
         else:
             self._gct_resize_buffer_no_realloc(hop, op.args[1])
 
     def _can_realloc(self):
         return False
 
-    def _gct_resize_buffer_realloc(self, hop, v_newsize):
+    def _gct_resize_buffer_realloc(self, hop, v_newsize, grow=True):
         def intconst(c): return rmodel.inputconst(lltype.Signed, c)
         op = hop.spaceop
         flags = {'flavor':'gc', 'varsize': True}
@@ -568,8 +569,10 @@
 
         c_lengthofs = intconst(offset_to_length)
         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_newsize, c_const_size,
-                                     c_item_size, c_lengthofs)
+                                     c_item_size, c_lengthofs, c_grow)
         hop.cast_result(v_raw)
 
     def _gct_resize_buffer_no_realloc(self, hop, v_lgt):
@@ -603,7 +606,7 @@
     def gct_finish_building_buffer(self, hop):
         op = hop.spaceop
         if self._can_realloc():
-            return self._gct_resize_buffer_realloc(hop, op.args[1])
+            return self._gct_resize_buffer_realloc(hop, op.args[1], False)
         else:
             return self._gct_resize_buffer_no_realloc(hop, op.args[1])
 



More information about the Pypy-commit mailing list