[pypy-svn] r24174 - in pypy/dist/pypy: rpython/memory translator/c/test
mwh at codespeak.net
mwh at codespeak.net
Thu Mar 9 14:25:34 CET 2006
Author: mwh
Date: Thu Mar 9 14:25:29 2006
New Revision: 24174
Modified:
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/translator/c/test/test_newgc.py
Log:
support for non gc static roots.
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Thu Mar 9 14:25:29 2006
@@ -625,6 +625,25 @@
self.finalizer_funcptrs[TYPE] = fptr
return fptr
+
+def gc_pointers_inside(v, adr):
+ t = lltype.typeOf(v)
+ if isinstance(t, lltype.Struct):
+ for n, t2 in t._flds.iteritems():
+ if isinstance(t2, lltype.Ptr) and t2._needsgc() and t2.TO != lltype.PyObject:
+ yield adr + llmemory.offsetof(t, n)
+ elif isinstance(t2, (lltype.Array, lltype.Struct)):
+ for a in gc_pointers_inside(getattr(v, n), adr + llmemory.offsetof(t, n)):
+ yield a
+ elif isinstance(t, lltype.Array):
+ if isinstance(t.OF, lltype.Ptr) and t2._needsgc():
+ for i in range(len(v.items)):
+ yield adr + llmemory.itemoffsetof(t, i)
+ elif isinstance(t.OF, lltype.Struct):
+ for i in range(len(v.items)):
+ for a in gc_pointers_inside(v.items[i], adr + llmemory.itemoffsetof(t, i)):
+ yield a
+
class FrameworkGCTransformer(BoehmGCTransformer):
def __init__(self, translator):
@@ -673,6 +692,7 @@
immortal=True)
gcdata.static_roots = lltype.malloc(lltype.Array(llmemory.Address), 0,
immortal=True)
+ gcdata.static_root_start = gcdata.static_root_end = llmemory.cast_ptr_to_adr(gcdata.static_roots)
self.gcdata = gcdata
self.type_info_list = []
self.id_of_type = {} # {LLTYPE: type_id}
@@ -685,13 +705,19 @@
class StackRootIterator:
_alloc_flavor_ = 'raw'
def __init__(self):
- self.current = gcdata.root_stack_top
+ self.stack_current = gcdata.root_stack_top
+ self.static_current = gcdata.static_root_start
def pop(self):
- while self.current != gcdata.root_stack_base:
- self.current -= sizeofaddr
- if self.current.address[0] != NULL:
- return self.current
+ while self.static_current != gcdata.static_root_end:
+ result = self.static_current
+ self.static_current += sizeofaddr
+ if result.address[0].address[0] != NULL:
+ return result.address[0]
+ while self.stack_current != gcdata.root_stack_base:
+ self.stack_current -= sizeofaddr
+ if self.stack_current.address[0] != NULL:
+ return self.stack_current
return NULL
def frameworkgc_setup():
@@ -735,6 +761,12 @@
data_classdef.generalize_attr(
'static_roots',
annmodel.SomePtr(lltype.Ptr(lltype.Array(llmemory.Address))))
+ data_classdef.generalize_attr(
+ 'static_root_start',
+ annmodel.SomeAddress())
+ data_classdef.generalize_attr(
+ 'static_root_end',
+ annmodel.SomeAddress())
annhelper = annlowlevel.MixLevelHelperAnnotator(self.translator.rtyper)
frameworkgc_setup_graph = annhelper.getgraph(frameworkgc_setup, [],
@@ -817,8 +849,6 @@
# all types get an ID.
# and to find static roots
# XXX this replicates too much of pypy.rpython.memory.convertlltype :(
- static_roots = {}
-
seen_types = {}
def recursive_get_types(t):
@@ -838,6 +868,8 @@
recursive_get_types(t.OF)
ll_instance_memo = {}
+ static_gc_roots = {}
+ static_roots_inside_nongc = []
for graph in self.translator.graphs:
for block in graph.iterblocks():
@@ -851,11 +883,16 @@
if t is None:
continue
if isinstance(t, lltype.Ptr) and t.TO != lltype.PyObject and \
- t._needsgc() and find_gc_ptrs_in_type(t.TO):
- static_roots[id(v.value)] = v
+ find_gc_ptrs_in_type(t.TO):
+ if t._needsgc():
+ static_gc_roots[id(v.value)] = v
+ else:
+ for a in gc_pointers_inside(v.value._obj, llmemory.cast_ptr_to_adr(v.value)):
+ static_roots_inside_nongc.append(a)
for T, inst in lltype.dissect_ll_instance(v.value, t, ll_instance_memo):
if isinstance(T, (lltype.GcArray, lltype.GcStruct)):
self.get_type_id(T)
+
table = lltype.malloc(self.gcdata.TYPE_INFO_TABLE,
len(self.type_info_list), immortal=True)
@@ -883,18 +920,27 @@
#self.gcdata.type_info_table = table
ll_static_roots = lltype.malloc(lltype.Array(llmemory.Address),
- len(static_roots),
+ len(static_gc_roots),
immortal=True)
- static_roots = static_roots.values()
+ static_roots = static_gc_roots.values()
for i in range(len(static_roots)):
c = static_roots[i]
c_ll_c = rmodel.inputconst(c.concretetype, c.value)
ll_static_roots[i] = llmemory.cast_ptr_to_adr(c_ll_c.value)
ll_instance.inst_static_roots = ll_static_roots
+
+ ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
+ len(static_roots_inside_nongc),
+ immortal=True)
+ for i in range(len(static_roots_inside_nongc)):
+ ll_static_roots_inside[i] = static_roots_inside_nongc[i]
+ ll_instance.inst_static_root_start = llmemory.cast_ptr_to_adr(ll_static_roots_inside) + llmemory.ArrayItemsOffset(lltype.Array(llmemory.Address))
+ ll_instance.inst_static_root_end = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(static_roots_inside_nongc)
newgcdependencies = newgcdependencies or []
newgcdependencies.append(table)
newgcdependencies.append(ll_static_roots)
+ newgcdependencies.append(ll_static_roots_inside)
return newgcdependencies
def protect_roots(self, op, livevars):
Modified: pypy/dist/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_newgc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_newgc.py Thu Mar 9 14:25:29 2006
@@ -271,7 +271,6 @@
assert res == 42
def test_framework_nongc_static_root(self):
- py.test.skip("I don't know how to make this work")
S = lltype.GcStruct("S", ('x', lltype.Signed))
T = lltype.Struct("T", ('p', lltype.Ptr(S)))
t = lltype.malloc(T, immortal=True)
More information about the Pypy-commit
mailing list