[pypy-svn] r51751 - in pypy/branch/unified-rtti/pypy: rpython/memory/gctransform translator/c

arigo at codespeak.net arigo at codespeak.net
Thu Feb 21 17:38:50 CET 2008


Author: arigo
Date: Thu Feb 21 17:38:50 2008
New Revision: 51751

Modified:
   pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py
   pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
   pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py
   pypy/branch/unified-rtti/pypy/translator/c/database.py
Log:
Refactor GCTransformer to assume that all transformers
have a HDR and a TYPEINFO.  Move code to the common base.


Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py	Thu Feb 21 17:38:50 2008
@@ -1,4 +1,5 @@
-from pypy.rpython.memory.gctransform.transform import GCTransformer, mallocHelpers
+from pypy.rpython.memory.gctransform.transform import GCTransformer
+from pypy.rpython.memory.gctransform.transform import mallocHelpers, RTTIPTR
 from pypy.rpython.memory.gctransform.support import type_contains_pyobjs, \
      _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor
 from pypy.rpython.lltypesystem import lltype, llmemory
@@ -9,12 +10,13 @@
 
 class BoehmGCTransformer(GCTransformer):
     FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
+    # XXX not all objects need a typeptr
+    HDR = lltype.Struct("header", ("typeptr", RTTIPTR))
     TYPEINFO = lltype.Struct('typeinfo')   # empty
 
     def __init__(self, translator, inline=False):
         super(BoehmGCTransformer, self).__init__(translator, inline=inline)
         self.finalizer_funcptrs = {}
-        self.rtticache = {}
 
         atomic_mh = mallocHelpers()
         atomic_mh.allocate = lambda size: llop.boehm_malloc_atomic(llmemory.Address, size)
@@ -45,9 +47,8 @@
             self.mixlevelannotator.finish()   # for now
             self.mixlevelannotator.backend_optimize()
 
-    def convert_rtti(self, rtti):
-        # no information in the TYPEINFO
-        return lltype.malloc(self.TYPEINFO, immortal=True)
+    def initialize_typeinfo(self, typeinfo, rtti, TYPE):
+        pass    # typeinfo is empty
 
     def push_alive_nopyobj(self, var, llops):
         pass

Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py	Thu Feb 21 17:38:50 2008
@@ -1,12 +1,12 @@
 import py
-from pypy.rpython.memory.gctransform.transform import GCTransformer, mallocHelpers
+from pypy.rpython.memory.gctransform.transform import GCTransformer
+from pypy.rpython.memory.gctransform.transform import mallocHelpers, RTTIPTR
 from pypy.rpython.memory.gctransform.support import find_gc_ptrs_in_type, \
      _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.translator.backendopt.support import var_needsgc
 from pypy.rpython import rmodel
-from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.debug import ll_assert
 from pypy.rpython.rbuiltin import gen_cast
@@ -32,7 +32,6 @@
 ##         print ' '*i, a, repr(b)[:100-i-len(a)], id(b)
 
 ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
-RTTIPTR = lltype.Ptr(lltype.RuntimeTypeInfo)
 
 class RefcountingGCTransformer(GCTransformer):
 
@@ -46,40 +45,30 @@
 
     def __init__(self, translator):
         super(RefcountingGCTransformer, self).__init__(translator, inline=True)
-        gchdrbuilder = GCHeaderBuilder(self.HDR, self.TYPEINFO)
-        self.gcheaderbuilder = gchdrbuilder
-        gc_header_offset = self.gcheaderbuilder.size_gc_header
         self.deallocator_graphs_needing_transforming = []
-        self.rtticache = {}
 
         # create incref, etc  graph
 
-        memoryError = MemoryError()
+        gchelpers = self.gchelpers
+        gc_header_offset = gchelpers.gc_header_offset
         HDRPTR = lltype.Ptr(self.HDR)
 
         def ll_incref(adr):
             if adr:
-                gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR)
+                gcheader = gchelpers.header(adr)
                 gcheader.refcount = gcheader.refcount + 1
         def ll_decref(adr):
             if adr:
-                gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR)
+                gcheader = gchelpers.header(adr)
                 refcount = gcheader.refcount - 1
                 gcheader.refcount = refcount
                 if refcount == 0:
-                    rtti = gcheader.typeptr
-                    typeinfo = gchdrbuilder.cast_rtti_to_typeinfo(rtti)
+                    typeinfo = gchelpers.typeof(adr)
                     typeinfo.dealloc(adr)
 
         def ll_no_pointer_dealloc(adr):
             llmemory.raw_free(adr)
 
-        def ll_gc_runtime_type_info(adr):
-            gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR)
-            rtti = gcheader.typeptr
-            ll_assert(bool(rtti), "NULL rtti pointer")
-            return rtti
-
         mh = mallocHelpers()
         mh.allocate = llmemory.raw_malloc
         def ll_malloc_fixedsize(size):
@@ -120,8 +109,6 @@
                 ll_decref, [llmemory.Address], lltype.Void)
             self.no_pointer_dealloc_ptr = self.inittime_helper(
                 ll_no_pointer_dealloc, [llmemory.Address], lltype.Void)
-            self.gc_runtime_type_info_ptr = self.inittime_helper(
-                ll_gc_runtime_type_info, [llmemory.Address], RTTIPTR)
             self.malloc_fixedsize_ptr = self.inittime_helper(
                 ll_malloc_fixedsize_rtti, [lltype.Signed, RTTIPTR],
                 llmemory.Address)
@@ -185,26 +172,6 @@
                                resulttype=llmemory.Address)
         return v_raw
 
-    def gct_gc_runtime_type_info(self, hop):
-        [v_ptr] = hop.spaceop.args
-        v_adr = hop.genop("cast_ptr_to_adr", [v_ptr],
-                          resulttype=llmemory.Address)
-        v_result = hop.spaceop.result
-        assert v_result.concretetype == RTTIPTR
-        hop.genop("direct_call",
-                  [self.gc_runtime_type_info_ptr, v_adr],
-                  resultvar = v_result)
-
-    def consider_constant(self, TYPE, value):
-        if value is not lltype.top_container(value):
-                return
-        if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
-            p = value._as_ptr()
-            if not self.gcheaderbuilder.get_header(p):
-                hdr = self.gcheaderbuilder.new_header(p)
-                hdr.refcount = sys.maxint // 2
-                hdr.typeptr = lltype.getRuntimeTypeInfo(TYPE, self.rtticache)
-
     def static_deallocation_funcptr_for_type(self, TYPE):
         """The 'static deallocator' for a type is the function that can
         free a pointer that we know points exactly to a TYPE structure
@@ -282,18 +249,9 @@
             self.static_deallocation_funcptr_for_type(p.TO)
         return fptr
 
-    def convert_rtti(self, rtti):
-        rtti = rtti._as_ptr()
-        try:
-            return self.gcheaderbuilder.typeinfo_from_rtti(rtti)
-        except KeyError:
-            typeinfo = self.gcheaderbuilder.new_typeinfo(rtti)
-            try:
-                TYPE = lltype.getGcTypeForRtti(rtti)
-            except ValueError:
-                pass      # ignore rtti's not attached anywhere, e.g. in the
-                          # vtable of raw-flavored RPython classes
-            else:
-                fn = self.static_deallocation_funcptr_for_type(TYPE)
-                typeinfo.dealloc = fn
-            return typeinfo
+    def initialize_constant_header(self, hdr, TYPE, value):
+        hdr.refcount = sys.maxint // 2
+
+    def initialize_typeinfo(self, typeinfo, rtti, TYPE):
+        fn = self.static_deallocation_funcptr_for_type(TYPE)
+        typeinfo.dealloc = fn

Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py	Thu Feb 21 17:38:50 2008
@@ -13,6 +13,7 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython import rmodel, annlowlevel
 from pypy.rpython.memory import gc
+from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rpython.memory.gctransform.support import var_ispyobj
 from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
 from pypy.rpython.rtyper import LowLevelOpList
@@ -23,6 +24,7 @@
 from pypy.translator.simplify import join_blocks, cleanup_graph
 
 PyObjPtr = lltype.Ptr(lltype.PyObject)
+RTTIPTR = lltype.Ptr(lltype.RuntimeTypeInfo)
 
 class GcHighLevelOp(object):
     def __init__(self, gct, op, index, llops):
@@ -457,10 +459,51 @@
 
     return mh
 
+def GCHelpers(gcheaderbuilder):
+    class _GcHelpers(object):
+        def _freeze_(self):
+            return True
+    gh = _GcHelpers()
+
+    gc_header_offset = gh.gc_header_offset = gcheaderbuilder.size_gc_header
+    HDRPTR = lltype.Ptr(gcheaderbuilder.HDR)
+
+    def header(objaddr):
+        "Get the header of an object identified by its address."
+        hdraddr = objaddr - gc_header_offset
+        return llmemory.cast_adr_to_ptr(hdraddr, HDRPTR)
+    gh.header = header
+
+    def gc_runtime_type_info(objaddr):
+        "Implementation of the gc_runtime_type_info operation."
+        # NB. this assumes that the HDR contains a typeptr field.
+        # A bit of manual inlining...
+        hdraddr = objaddr - gc_header_offset
+        return llmemory.cast_adr_to_ptr(hdraddr, HDRPTR).typeptr
+    gh.gc_runtime_type_info = gc_runtime_type_info
+
+    def typeof(objaddr):
+        "Get the typeinfo describing the type of the object at 'objaddr'."
+        # NB. this assumes that the HDR contains a typeptr field
+        # A bit of manual inlining...
+        hdraddr = objaddr - gc_header_offset
+        rtti = llmemory.cast_adr_to_ptr(hdraddr, HDRPTR).typeptr
+        return gcheaderbuilder.cast_rtti_to_typeinfo(rtti)
+    gh.typeof = typeof
+
+    return gh
+
+
 class GCTransformer(BaseGCTransformer):
 
     def __init__(self, translator, inline=False):
         super(GCTransformer, self).__init__(translator, inline=inline)
+        # at the moment, all GC transformers define a HDR structure that
+        # is added in front of all GC objects, and a TYPEINFO structure
+        # that works as RuntimeTypeInfo
+        self.gcheaderbuilder = GCHeaderBuilder(self.HDR, self.TYPEINFO)
+        self.gchelpers = GCHelpers(self.gcheaderbuilder)
+        self.rtticache = {}
 
         mh = mallocHelpers()
         mh.allocate = llmemory.raw_malloc
@@ -486,6 +529,10 @@
             self.stack_malloc_fixedsize_ptr = self.inittime_helper(
                 ll_stack_malloc_fixedsize, [lltype.Signed], llmemory.Address)
 
+            self.gc_runtime_type_info_ptr = self.inittime_helper(
+                self.gchelpers.gc_runtime_type_info, [llmemory.Address],
+                RTTIPTR)
+
     def gct_malloc(self, hop):
         TYPE = hop.spaceop.result.concretetype.TO
         assert not TYPE._is_varsize()
@@ -611,3 +658,41 @@
             hop.genop('raw_free', [v])
         else:
             assert False, "%s has no support for free with flavor %r" % (self, flavor)           
+
+    def gct_gc_runtime_type_info(self, hop):
+        [v_ptr] = hop.spaceop.args
+        v_adr = hop.genop("cast_ptr_to_adr", [v_ptr],
+                          resulttype=llmemory.Address)
+        v_result = hop.spaceop.result
+        assert v_result.concretetype == RTTIPTR
+        hop.genop("direct_call",
+                  [self.gc_runtime_type_info_ptr, v_adr],
+                  resultvar = v_result)
+
+    def consider_constant(self, TYPE, value):
+        if value is not lltype.top_container(value):
+            return
+        if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
+            p = value._as_ptr()
+            if not self.gcheaderbuilder.get_header(p):
+                hdr = self.gcheaderbuilder.new_header(p)
+                hdr.typeptr = lltype.getRuntimeTypeInfo(TYPE, self.rtticache)
+                self.initialize_constant_header(hdr, TYPE, value)
+
+    def initialize_constant_header(self, hdr, TYPE, value):
+        pass
+
+    def convert_rtti(self, rtti):
+        rtti = rtti._as_ptr()
+        try:
+            return self.gcheaderbuilder.typeinfo_from_rtti(rtti)
+        except KeyError:
+            typeinfo = self.gcheaderbuilder.new_typeinfo(rtti)
+            try:
+                TYPE = lltype.getGcTypeForRtti(rtti)
+            except ValueError:
+                pass      # ignore rtti's not attached anywhere, e.g. in the
+                          # vtable of raw-flavored RPython classes
+            else:
+                self.initialize_typeinfo(typeinfo, rtti, TYPE)
+            return typeinfo

Modified: pypy/branch/unified-rtti/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/database.py	(original)
+++ pypy/branch/unified-rtti/pypy/translator/c/database.py	Thu Feb 21 17:38:50 2008
@@ -153,7 +153,7 @@
         except KeyError:
             T = typeOf(container)
             if isinstance(T, (lltype.Array, lltype.Struct)):
-                if hasattr(self.gctransformer, 'consider_constant'):
+                if self.gctransformer is not None:
                     self.gctransformer.consider_constant(T, container)
             nodefactory = ContainerNodeFactory[T.__class__]
             node = nodefactory(self, T, container, **buildkwds)



More information about the Pypy-commit mailing list