Author: Remi Meier <remi.me...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit