[pypy-svn] r23321 - in pypy: branch/genc-gc-refactoring dist/pypy/rpython/memory dist/pypy/rpython/memory/test
mwh at codespeak.net
mwh at codespeak.net
Tue Feb 14 13:49:25 CET 2006
Author: mwh
Date: Tue Feb 14 13:49:23 2006
New Revision: 23321
Modified:
pypy/branch/genc-gc-refactoring/gc.py
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
changes to the interface of gctransformer -- instead of providing graphs
of deallocators it now provides function pointers to deallocators.
also fix a rather embarrassing bug in my last change to gctransformer.
Modified: pypy/branch/genc-gc-refactoring/gc.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/gc.py (original)
+++ pypy/branch/genc-gc-refactoring/gc.py Tue Feb 14 13:49:23 2006
@@ -81,11 +81,8 @@
def struct_setup(self, structdefnode, rtti):
if rtti is not None:
transformer = structdefnode.db.gctransformer
- graph = transformer.static_deallocation_graph_for_type(structdefnode.STRUCT)
- # XXX come up with a nicer interface in gctransformer
- structdefnode.db.translator.rtyper.specialize_more_blocks()
- FUNCTYPE = lltype.FuncType([llmemory.Address], lltype.Void)
- fptr = lltype.functionptr(FUNCTYPE, graph.name, graph=graph)
+ fptr = transformer.static_deallocation_funcptr_for_type(
+ structdefnode.STRUCT)
structdefnode.gcinfo = RefcountingInfo()
structdefnode.gcinfo.static_deallocator = structdefnode.db.get(fptr)
@@ -153,11 +150,8 @@
def setup_gcinfo(self, defnode):
transformer = defnode.db.gctransformer
- graph = transformer.finalizer_graph_for_type(defnode.LLTYPE)
- if graph:
- defnode.db.translator.rtyper.specialize_more_blocks()
- FUNCTYPE = lltype.FuncType([llmemory.Address], lltype.Void)
- fptr = lltype.functionptr(FUNCTYPE, graph.name, graph=graph)
+ fptr = transformer.finalizer_funcptr_for_type(defnode.LLTYPE)
+ if fptr:
defnode.gcinfo = BoehmInfo()
defnode.gcinfo.finalizer = defnode.db.get(fptr)
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Tue Feb 14 13:49:23 2006
@@ -259,6 +259,8 @@
for i, (a, b) in enumerate(stack):
print ' '*i, a, repr(b)[:100-i-len(a)], id(b)
+ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
+
class RefcountingGCTransformer(GCTransformer):
gc_header_offset = gc.GCHeaderOffset(lltype.Struct("header", ("refcount", lltype.Signed)))
@@ -280,29 +282,31 @@
def no_pointer_dealloc(adr):
objectmodel.llop.gc_free(lltype.Void, adr)
if self.translator is not None and self.translator.rtyper is not None:
- self.increfgraph = self.annotate_helper(
+ increfgraph = self.annotate_helper(
incref, [annmodel.SomeAddress()])
self.translator.rtyper.specialize_more_blocks()
- self.increfptr = const_funcptr_fromgraph(self.increfgraph)
- self.seen_graphs[self.increfgraph] = True
+ self.increfptr = const_funcptr_fromgraph(increfgraph)
+ self.seen_graphs[increfgraph] = True
- self.decref_graph = self.annotate_helper(
- decref, [annmodel.SomeAddress(), lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))])
+ decref_graph = self.annotate_helper(
+ decref, [annmodel.SomeAddress(), lltype.Ptr(ADDRESS_VOID_FUNC)])
self.translator.rtyper.specialize_more_blocks()
- self.decref_ptr = const_funcptr_fromgraph(self.decref_graph)
- self.seen_graphs[self.decref_graph] = True
+ self.decref_ptr = const_funcptr_fromgraph(decref_graph)
+ self.seen_graphs[decref_graph] = True
- self.no_pointer_dealloc_graph = self.annotate_helper(
+ no_pointer_dealloc_graph = self.annotate_helper(
no_pointer_dealloc, [annmodel.SomeAddress()])
self.translator.rtyper.specialize_more_blocks()
- self.no_pointer_dealloc_ptr = const_funcptr_fromgraph(self.no_pointer_dealloc_graph)
- self.seen_graphs[self.no_pointer_dealloc_graph] = True
- self.deallocators_needing_transforming = []
+ self.no_pointer_dealloc_ptr = lltype.functionptr(
+ ADDRESS_VOID_FUNC, no_pointer_dealloc_graph.name,
+ graph=no_pointer_dealloc_graph)
+ self.seen_graphs[no_pointer_dealloc_graph] = True
+ self.deallocator_graphs_needing_transforming = []
# cache graphs:
- self.decref_graphs = {}
- self.static_deallocator_graphs = {}
- self.dynamic_deallocator_graphs = {}
- self.queryptr2dynamic_deallocator_graph = {}
+ self.decref_funcptrs = {}
+ self.static_deallocator_funcptrs = {}
+ self.dynamic_deallocator_funcptrs = {}
+ self.queryptr2dynamic_deallocator_funcptr = {}
def push_alive_nopyobj(self, var):
@@ -317,13 +321,12 @@
adr1 = varoftype(llmemory.Address)
result = [SpaceOperation("cast_ptr_to_adr", [var], adr1)]
- graph = self.dynamic_deallocation_graph_for_type(PTRTYPE.TO)
-
- FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
- dealloc_fptr = rmodel.inputconst(
- lltype.Ptr(FUNC), lltype.functionptr(FUNC, graph.name, graph=graph))
-
- result.append(SpaceOperation("direct_call", [self.decref_ptr, adr1, dealloc_fptr],
+ dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(PTRTYPE.TO)
+ cdealloc_fptr = rmodel.inputconst(
+ lltype.Ptr(ADDRESS_VOID_FUNC), dealloc_fptr)
+
+ result.append(SpaceOperation("direct_call",
+ [self.decref_ptr, adr1, cdealloc_fptr],
varoftype(lltype.Void)))
return result
@@ -332,7 +335,8 @@
return [op]
oldval = Variable()
oldval.concretetype = op.args[2].concretetype
- getoldvalop = SpaceOperation("getfield", [op.args[0], op.args[1]], oldval)
+ getoldvalop = SpaceOperation("getfield",
+ [op.args[0], op.args[1]], oldval)
result = [getoldvalop]
result.extend(self.pop_alive(oldval))
result.extend(self.push_alive(op.args[2]))
@@ -360,19 +364,19 @@
pass
return None
- def static_deallocation_graph_for_type(self, TYPE):
- if TYPE in self.static_deallocator_graphs:
- return self.static_deallocator_graphs[TYPE]
- g = self._static_deallocation_graph_for_type(TYPE)
+ def static_deallocation_funcptr_for_type(self, TYPE):
+ if TYPE in self.static_deallocator_funcptrs:
+ return self.static_deallocator_funcptrs[TYPE]
+ fptr = self._static_deallocation_funcptr_for_type(TYPE)
self.specialize_more_blocks()
- for g in self.deallocators_needing_transforming:
+ for g in self.deallocator_graphs_needing_transforming:
MinimalGCTransformer(self.translator).transform_graph(g)
- self.deallocators_needing_transforming = []
- return g
+ self.deallocator_graphs_needing_transforming = []
+ return fptr
- def _static_deallocation_graph_for_type(self, TYPE):
- if TYPE in self.static_deallocator_graphs:
- return self.static_deallocator_graphs[TYPE]
+ def _static_deallocation_funcptr_for_type(self, TYPE):
+ if TYPE in self.static_deallocator_funcptrs:
+ return self.static_deallocator_funcptrs[TYPE]
#print_call_chain(self)
def compute_pop_alive_ll_ops(hop):
hop.llops.extend(self.pop_alive(hop.args_v[1]))
@@ -392,9 +396,9 @@
if destrptr is None and not find_gc_ptrs_in_type(TYPE):
#print repr(TYPE)[:80], 'is dealloc easy'
- g = self.no_pointer_dealloc_graph
- self.static_deallocator_graphs[TYPE] = g
- return g
+ p = self.no_pointer_dealloc_ptr
+ self.static_deallocator_funcptrs[TYPE] = p
+ return p
if destrptr is not None:
body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 2))
@@ -438,32 +442,27 @@
if destrptr:
# however, the direct_call to the destructor needs to get
# .cleanup attached
- self.deallocators_needing_transforming.append(g)
-
- opcount = 0
- for block in g.iterblocks():
- opcount += len(block.operations)
- if opcount == 0:
- result = None
- else:
- result = g
- self.static_deallocator_graphs[TYPE] = result
- return result
+ self.deallocator_graphs_needing_transforming.append(g)
- def dynamic_deallocation_graph_for_type(self, TYPE):
- if TYPE in self.dynamic_deallocator_graphs:
- return self.dynamic_deallocator_graphs[TYPE]
+ fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+
+ self.static_deallocator_funcptrs[TYPE] = fptr
+ return fptr
+
+ def dynamic_deallocation_funcptr_for_type(self, TYPE):
+ if TYPE in self.dynamic_deallocator_funcptrs:
+ return self.dynamic_deallocator_funcptrs[TYPE]
#print_call_chain(self)
rtti = self.get_rtti(TYPE)
if rtti is None:
- g = self._static_deallocation_graph_for_type(TYPE)
- self.dynamic_deallocator_graphs[TYPE] = g
- return g
+ p = self._static_deallocation_funcptr_for_type(TYPE)
+ self.dynamic_deallocator_funcptrs[TYPE] = p
+ return p
queryptr = rtti._obj.query_funcptr
- if queryptr._obj in self.queryptr2dynamic_deallocator_graph:
- return self.queryptr2dynamic_deallocator_graph[queryptr._obj]
+ if queryptr._obj in self.queryptr2dynamic_deallocator_funcptr:
+ return self.queryptr2dynamic_deallocator_funcptr[queryptr._obj]
RTTI_PTR = lltype.Ptr(lltype.RuntimeTypeInfo)
QUERY_ARG_TYPE = lltype.typeOf(queryptr).TO.ARGS[0]
@@ -476,10 +475,12 @@
gcheader.signed[0] = 0
objectmodel.llop.gc_call_rtti_destructor(lltype.Void, rtti, addr)
g = self.annotate_helper(dealloc, [llmemory.Address])
- self.dynamic_deallocator_graphs[TYPE] = g
- self.queryptr2dynamic_deallocator_graph[queryptr._obj] = g
self.seen_graphs[g] = True
- return g
+
+ fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+ self.dynamic_deallocator_funcptrs[TYPE] = fptr
+ self.queryptr2dynamic_deallocator_funcptr[queryptr._obj] = fptr
+ return fptr
def varoftype(concretetype):
var = Variable()
@@ -525,7 +526,7 @@
def __init__(self, translator):
super(BoehmGCTransformer, self).__init__(translator)
- self.finalizer_graphs = {}
+ self.finalizer_funcptrs = {}
def push_alive_nopyobj(self, var):
return []
@@ -541,9 +542,9 @@
pass
return None
- def finalizer_graph_for_type(self, TYPE):
- if TYPE in self.finalizer_graphs:
- return self.finalizer_graphs[TYPE]
+ def finalizer_funcptr_for_type(self, TYPE):
+ if TYPE in self.finalizer_funcptrs:
+ return self.finalizer_funcptrs[TYPE]
def compute_pop_alive_ll_ops(hop):
hop.llops.extend(self.pop_alive(hop.args_v[1]))
@@ -588,8 +589,13 @@
if g:
self.seen_graphs[g] = True
- self.finalizer_graphs[TYPE] = g
- return g
+
+ fptr = lltype.functionptr(ADDRESS_VOID_FUNC, g.name, graph=g)
+ self.finalizer_funcptrs[TYPE] = fptr
+ return fptr
+ else:
+ self.finalizer_funcptrs[TYPE] = None
+ return None
# ___________________________________________________________________
# calculate some statistics about the number of variables that need
Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py Tue Feb 14 13:49:23 2006
@@ -329,7 +329,7 @@
# test deallocators
def make_deallocator(TYPE,
- attr="static_deallocation_graph_for_type",
+ attr="static_deallocation_funcptr_for_type",
cls=gctransform.RefcountingGCTransformer):
def f():
pass
@@ -337,14 +337,17 @@
t.buildannotator().build_types(f, [])
t.buildrtyper().specialize(t)
transformer = cls(t)
- graph = getattr(transformer, attr)(TYPE)
+ fptr = getattr(transformer, attr)(TYPE)
t.rtyper.specialize_more_blocks()
if conftest.option.view:
t.view()
- return graph, t
+ if fptr:
+ return fptr._obj.graph, t
+ else:
+ return None, t
def make_boehm_finalizer(TYPE):
- return make_deallocator(TYPE, attr="finalizer_graph_for_type",
+ return make_deallocator(TYPE, attr="finalizer_funcptr_for_type",
cls=gctransform.BoehmGCTransformer)
def test_deallocator_simple():
@@ -446,11 +449,11 @@
t.buildannotator().build_types(f, [])
t.buildrtyper().specialize(t)
transformer = gctransform.RefcountingGCTransformer(t)
- graph_S = transformer.dynamic_deallocation_graph_for_type(S)
- graph_S1 = transformer.dynamic_deallocation_graph_for_type(S1)
- graph_T = transformer.dynamic_deallocation_graph_for_type(T)
- assert graph_S is not graph_T
- assert graph_S is graph_S1
+ p_S = transformer.dynamic_deallocation_funcptr_for_type(S)
+ p_S1 = transformer.dynamic_deallocation_funcptr_for_type(S1)
+ p_T = transformer.dynamic_deallocation_funcptr_for_type(T)
+ assert p_S is not p_T
+ assert p_S is p_S1
def test_dynamic_deallocator():
class A(object):
@@ -468,10 +471,11 @@
else:
c = b
return c.x
- t, transformer = rtype_and_transform(f, [int], gctransform.RefcountingGCTransformer, check=False)
+ t, transformer = rtype_and_transform(
+ f, [int], gctransform.RefcountingGCTransformer, check=False)
fgraph = graphof(t, f)
TYPE = fgraph.startblock.operations[0].result.concretetype.TO
- graph = transformer.dynamic_deallocation_graph_for_type(TYPE)
+ p = transformer.dynamic_deallocation_funcptr_for_type(TYPE)
t.rtyper.specialize_more_blocks()
def test_recursive_structure():
@@ -482,7 +486,8 @@
s1 = lltype.malloc(S)
s2 = lltype.malloc(S)
s1.x = s2
- t, transformer = rtype_and_transform(f, [], gctransform.RefcountingGCTransformer, check=False)
+ t, transformer = rtype_and_transform(
+ f, [], gctransform.RefcountingGCTransformer, check=False)
def test_boehm_finalizer_simple():
More information about the Pypy-commit
mailing list