[pypy-commit] pypy stmgc-c8: some cleanup and some more tests
Raemi
noreply at buildbot.pypy.org
Wed Nov 25 10:58:34 EST 2015
Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c8
Changeset: r80948:cb4f5b7f309c
Date: 2015-11-25 12:46 +0100
http://bitbucket.org/pypy/pypy/changeset/cb4f5b7f309c/
Log: some cleanup and some more tests
diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -106,8 +106,10 @@
writeable = {}
#
if op.opname == "stm_ignored_start":
+ assert not self.in_stm_ignored
self.in_stm_ignored = True
elif op.opname == "stm_ignored_stop":
+ assert self.in_stm_ignored
self.in_stm_ignored = False
elif op.opname == "gc_writebarrier":
assert not self.in_stm_ignored
@@ -115,50 +117,49 @@
elif op.opname == "malloc":
rtti = get_rtti(op.args[0].value)
if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
- # XXX: not sure why that matters, copied from
- # find_initializing_stores
- continue
- writeable[op.result] = True
+ # objs with finalizers are allocated directly as "old", so
+ # they need write barriers
+ assert op not in self.clean_ops
+ else:
+ # freshly allocated object
+ writeable[op.result] = True
#
elif op.opname in ("cast_pointer", "same_as"):
if writeable.get(op.args[0], False):
writeable[op.result] = True
#
elif op.opname in ('setfield', 'setarrayitem', 'setinteriorfield', 'raw_store'):
+ # generic_set case
if op.args[-1].concretetype == lltype.Void:
+ # always ignore setfields of Void type
self.clean_ops.add(op)
- continue # ignore setfields of Void type
elif not var_needsgc(op.args[0]):
+ # raw setfields don't need a barrier
if (var_needsgc(op.args[-1]) and
'is_excdata' not in op.args[0].concretetype.TO._hints):
raise Exception("%s: GC pointer written into a non-GC location"
% (op,))
self.clean_ops.add(op)
- continue
elif self.in_stm_ignored:
- # detect if we're inside a 'stm_ignored' block and in
- # that case don't call stm_write(). This only works for
- # writing non-GC pointers.
+ # within stm_ignored, don't emit stm_write(). This only works
+ # for writing non-GC pointers.
if var_needsgc(op.args[-1]):
raise Exception("in stm_ignored block: write of a gc pointer")
self.clean_ops.add(op)
- continue
- elif self._set_into_gc_array_part(op) is None:
- # full write barrier required
- if writeable.get(op.args[0], False):
- # already writeable, this op is also clean
- self.clean_ops.add(op)
- elif op in self.clean_ops:
- # we changed our opinion in this iteration
- self.clean_ops.remove(op)
- # always writeable after this op
- writeable[op.args[0]] = True
- else:
+ elif self._set_into_gc_array_part(op) is not None:
# things that need partial write barriers (card marking)
if writeable.get(op.args[0], False):
self.clean_ops.add(op)
elif op in self.clean_ops:
self.clean_ops.remove(op)
+ else:
+ # full write barrier possibly required
+ if writeable.get(op.args[0], False):
+ self.clean_ops.add(op)
+ elif op in self.clean_ops:
+ self.clean_ops.remove(op)
+ # always writeable after this op
+ writeable[op.args[0]] = True
#
# update in_states of all successors
updated = set()
diff --git a/rpython/memory/gctransform/test/test_framework.py b/rpython/memory/gctransform/test/test_framework.py
--- a/rpython/memory/gctransform/test/test_framework.py
+++ b/rpython/memory/gctransform/test/test_framework.py
@@ -396,6 +396,141 @@
assert summary(ff)['stm_write'] == 3
+def test_remove_write_barrier_stm4():
+ from rpython.translator.c.genc import CStandaloneBuilder
+ from rpython.flowspace.model import summary
+
+ rS = lltype.Struct('rS')
+ S = lltype.GcStruct('S')
+ rA = lltype.Array(lltype.Ptr(rS))
+ A = lltype.GcArray(lltype.Ptr(S))
+ Ar = lltype.GcArray(lltype.Ptr(rS))
+ def f(ra, a, ar, i):
+ s = lltype.malloc(S)
+ rs = lltype.malloc(rS, flavor='raw')
+ ra[0] = rs
+ ra[1] = rs
+ a[0] = s
+ a[1] = s
+ ar[0] = rs
+ ar[1] = rs
+ def g(argv):
+ n = int(argv[1])
+ ra = lltype.malloc(rA, n, flavor='raw')
+ a = lltype.malloc(A, n)
+ ar = lltype.malloc(Ar, n)
+ f(ra, a, ar, n)
+ return 0
+ t = rtype(g, [s_list_of_strings])
+ t.config.translation.stm = True
+ gcpolicy = StmFrameworkGcPolicy
+ t.config.translation.gc = "stmgc"
+ cbuild = CStandaloneBuilder(t, g, t.config,
+ gcpolicy=gcpolicy)
+ db = cbuild.generate_graphs_for_llinterp()
+
+ ff = graphof(t, f)
+ #ff.show()
+ assert summary(ff)['stm_write'] == 4
+
+def test_remove_write_barrier_stm5():
+ from rpython.translator.c.genc import CStandaloneBuilder
+ from rpython.flowspace.model import summary
+
+ class B(object):
+ def __del__(self):
+ pass
+ class A(object): pass
+ def f():
+ b = B()
+ b.x = 1 # needs WB bc. of finalizer
+ a = A()
+ a.x = 1
+ def g(argv):
+ f()
+ return 0
+ t = rtype(g, [s_list_of_strings])
+ t.config.translation.stm = True
+ gcpolicy = StmFrameworkGcPolicy
+ t.config.translation.gc = "stmgc"
+ cbuild = CStandaloneBuilder(t, g, t.config,
+ gcpolicy=gcpolicy)
+ db = cbuild.generate_graphs_for_llinterp()
+
+ ff = graphof(t, f)
+ #ff.show()
+ assert summary(ff)['stm_write'] == 1
+
+def test_remove_write_barrier_stm6():
+ from rpython.translator.c.genc import CStandaloneBuilder
+ from rpython.flowspace.model import summary
+ #
+ rSi = lltype.Struct('rSi', ('i', lltype.Signed))
+ rSr = lltype.Struct('rSr', ('s', lltype.Ptr(rSi)))
+ Si = lltype.GcStruct('Si', ('i', lltype.Signed))
+ Ss = lltype.GcStruct('Ss', ('s', lltype.Ptr(Si)))
+ Sr = lltype.GcStruct('Sr', ('r', lltype.Ptr(rSi)))
+ def f(rsi, rsr, si, ss, sr):
+ rsi.i = 0
+ rsr.s = rsi
+ si.i = 0
+ ss.s = si
+ sr.r = rsi
+ def g(argv):
+ rsi = lltype.malloc(rSi, flavor='raw')
+ rsr = lltype.malloc(rSr, flavor='raw')
+ si = lltype.malloc(Si, flavor='gc')
+ ss = lltype.malloc(Ss, flavor='gc')
+ sr = lltype.malloc(Sr, flavor='gc')
+ f(rsi, rsr, si, ss, sr)
+ return 0
+ t = rtype(g, [s_list_of_strings])
+ t.config.translation.stm = True
+ gcpolicy = StmFrameworkGcPolicy
+ t.config.translation.gc = "stmgc"
+ cbuild = CStandaloneBuilder(t, g, t.config,
+ gcpolicy=gcpolicy)
+ db = cbuild.generate_graphs_for_llinterp()
+
+ ff = graphof(t, f)
+ #ff.show()
+ assert summary(ff)['stm_write'] == 3
+
+def test_remove_write_barrier_stm7():
+ from rpython.translator.c.genc import CStandaloneBuilder
+ from rpython.flowspace.model import summary
+ #
+ rSi = lltype.Struct('rSi', ('i', lltype.Signed))
+ rSr = lltype.Struct('rSr', ('s', rSi))
+ Si = lltype.GcStruct('Si', ('i', lltype.Signed))
+ Ss = lltype.GcStruct('Ss', ('s', Si))
+ Sr = lltype.GcStruct('Sr', ('r', rSi))
+ def f(rsi, rsr, si, ss, sr):
+ rsi.i = 0
+ rsr.s.i = 0
+ si.i = 0
+ ss.s.i = 0
+ sr.r.i = 0
+ def g(argv):
+ rsi = lltype.malloc(rSi, flavor='raw')
+ rsr = lltype.malloc(rSr, flavor='raw')
+ si = lltype.malloc(Si, flavor='gc')
+ ss = lltype.malloc(Ss, flavor='gc')
+ sr = lltype.malloc(Sr, flavor='gc')
+ f(rsi, rsr, si, ss, sr)
+ return 0
+ t = rtype(g, [s_list_of_strings])
+ t.config.translation.stm = True
+ gcpolicy = StmFrameworkGcPolicy
+ t.config.translation.gc = "stmgc"
+ cbuild = CStandaloneBuilder(t, g, t.config,
+ gcpolicy=gcpolicy)
+ db = cbuild.generate_graphs_for_llinterp()
+
+ ff = graphof(t, f)
+ #ff.show()
+ assert summary(ff)['stm_write'] == 3
+
def test_write_barrier_collector():
class A(object):
pass
More information about the pypy-commit
mailing list