[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