Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r76628:881354657952 Date: 2015-03-29 21:30 +0200 http://bitbucket.org/pypy/pypy/changeset/881354657952/
Log: redo the equivalent of 994b78f6c6eb in a way that works (can't use rgc.no_collect for various reasons) 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 @@ -251,6 +251,8 @@ annhelper.finish() # at this point, annotate all mix-level helpers annhelper.backend_optimize() + self.check_custom_trace_funcs(gcdata.gc, translator.rtyper) + self.collect_analyzer = CollectAnalyzer(self.translator) self.collect_analyzer.analyze_all() @@ -540,6 +542,24 @@ self.gcdata._has_got_custom_trace(self.get_type_id(TP)) specialize.arg(2)(func) + def check_custom_trace_funcs(self, gc, rtyper): + # detect if one of the custom trace functions uses the GC + # (it must not!) + for TP, func in rtyper.custom_trace_funcs: + def no_op_callback(obj, arg): + pass + def ll_check_no_collect(obj): + func(gc, obj, no_op_callback, None) + annhelper = annlowlevel.MixLevelHelperAnnotator(rtyper) + graph1 = annhelper.getgraph(ll_check_no_collect, [SomeAddress()], + annmodel.s_None) + annhelper.finish() + collect_analyzer = CollectAnalyzer(self.translator) + if collect_analyzer.analyze_direct_call(graph1): + raise Exception( + "the custom trace hook %r for %r can cause " + "the GC to be called!" % (func, TP)) + def consider_constant(self, TYPE, value): self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc) 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 @@ -143,6 +143,31 @@ expected = "'no_collect' function can trigger collection: <function g at " assert str(f.value).startswith(expected) +def test_custom_trace_function_no_collect(): + from rpython.rlib import rgc + from rpython.translator.c.genc import CStandaloneBuilder + + S = lltype.GcStruct("MyStructure") + class Glob: + pass + glob = Glob() + def trace_func(gc, obj, callback, arg): + glob.foo = (gc, obj) + lambda_trace_func = lambda: trace_func + def entrypoint(argv): + lltype.malloc(S) + rgc.register_custom_trace_hook(S, lambda_trace_func) + return 0 + + t = rtype(entrypoint, [s_list_of_strings]) + t.config.translation.gc = "minimark" + cbuild = CStandaloneBuilder(t, entrypoint, t.config, + gcpolicy=FrameworkGcPolicy2) + f = py.test.raises(Exception, cbuild.generate_graphs_for_llinterp) + assert 'can cause the GC to be called' in str(f.value) + assert 'trace_func' in str(f.value) + assert 'MyStructure' in str(f.value) + class WriteBarrierTransformer(ShadowStackFrameworkGCTransformer): clean_sets = {} GC_PARAMS = {} _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit