def test_cancollect_external(): fext1 = rffi.llexternal('fext1', [], lltype.Void, releasegil=False) def g(): fext1() t = rtype(g, []) gg = graphof(t, g) assert not CollectAnalyzer(t).analyze_direct_call(gg) fext2 = rffi.llexternal('fext2', [], lltype.Void, releasegil=True) def g(): fext2() t = rtype(g, []) gg = graphof(t, g) assert CollectAnalyzer(t).analyze_direct_call(gg) S = lltype.GcStruct('S', ('x', lltype.Signed)) FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, releasegil=False) def h(x): lltype.malloc(S, zero=True) def g(): fext3(h) t = rtype(g, []) gg = graphof(t, g) assert CollectAnalyzer(t).analyze_direct_call(gg)
def test_cancollect(): S = lltype.GcStruct('S', ('x', lltype.Signed)) def g(): lltype.malloc(S, zero=True) t = rtype(g, []) gg = graphof(t, g) assert CollectAnalyzer(t).analyze_direct_call(gg) def g(x): return -x t = rtype(g, [int]) gg = graphof(t, g) assert not CollectAnalyzer(t).analyze_direct_call(gg)
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) cbuild.make_entrypoint_wrapper = False with py.test.raises(Exception) as f: cbuild.build_database() 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)
def test_remove_duplicate_write_barrier(): from rpython.translator.c.genc import CStandaloneBuilder from rpython.flowspace.model import summary class A(object): pass glob_a_1 = A() glob_a_2 = A() def f(a, cond): a.x = a a.z = a if cond: a.y = a def g(): f(glob_a_1, 5) f(glob_a_2, 0) t = rtype(g, []) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, g, t.config, gcpolicy=FrameworkGcPolicy2) cbuild.make_entrypoint_wrapper = False db = cbuild.build_database() ff = graphof(t, f) #ff.show() assert summary(ff)['direct_call'] == 1 # only one remember_young_pointer
def test_find_initializing_stores_across_blocks(): class A(object): pass class B(object): pass def f(x): a1 = A() a2 = A() a = A() b = B() b.a = a if x: b.b = a1 b.c = a2 else: b.c = a1 b.b = a2 t = rtype(f, [int]) etrafo = ExceptionTransformer(t) graphs = etrafo.transform_completely() collect_analyzer = CollectAnalyzer(t) init_stores = find_initializing_stores(collect_analyzer, t.graphs[0], mkentrymap(t.graphs[0])) assert len(init_stores) == 5
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) with py.test.raises(Exception) as f: cbuild.build_database() 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)
def test_no_collect_detection(): from rpython.rlib import rgc from rpython.translator.c.genc import CStandaloneBuilder class A(object): def __init__(self, x): self.x = x @rgc.no_collect def g(): return A(1).x assert g._dont_inline_ assert g._gc_no_collect_ def entrypoint(argv): return g() + 2 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) expected = "'no_collect' function can trigger collection: <function g at " assert str(f.value).startswith(expected)
def test_remove_duplicate_write_barrier(): from rpython.translator.c.genc import CStandaloneBuilder from rpython.flowspace.model import summary class A(object): pass glob_a_1 = A() glob_a_2 = A() def f(a, cond): a.x = a a.z = a if cond: a.y = a def g(): f(glob_a_1, 5) f(glob_a_2, 0) t = rtype(g, []) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, g, t.config, gcpolicy=FrameworkGcPolicy2) db = cbuild.generate_graphs_for_llinterp() ff = graphof(t, f) #ff.show() assert summary(ff)['direct_call'] == 1 # only one remember_young_pointer
def test_framework_simple(): def g(x): return x + 1 class A(object): pass def entrypoint(argv): a = A() a.b = g(1) return str(a.b) from rpython.rtyper.llinterp import LLInterpreter from rpython.translator.c.genc import CStandaloneBuilder t = rtype(entrypoint, [s_list_of_strings]) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) db = cbuild.generate_graphs_for_llinterp() entrypointptr = cbuild.getentrypointptr() entrygraph = entrypointptr._obj.graph r_list_of_strings = t.rtyper.getrepr(s_list_of_strings) ll_argv = r_list_of_strings.convert_const([]) llinterp = LLInterpreter(t.rtyper) # FIIIIISH setupgraph = db.gctransformer.frameworkgc_setup_ptr.value._obj.graph llinterp.eval_graph(setupgraph, []) res = llinterp.eval_graph(entrygraph, [ll_argv]) assert ''.join(res.chars) == "2"
def test_no_collect_detection(): from rpython.rlib import rgc from rpython.translator.c.genc import CStandaloneBuilder class A(object): def __init__(self, x): self.x = x @rgc.no_collect def g(): return A(1).x assert g._dont_inline_ assert g._gc_no_collect_ def entrypoint(argv): return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) cbuild.make_entrypoint_wrapper = False with py.test.raises(Exception) as f: cbuild.build_database() expected = "'no_collect' function can trigger collection: <function g at " assert str(f.value).startswith(expected)
def test_framework_simple(): def g(x): return x + 1 class A(object): pass def entrypoint(argv): a = A() a.b = g(1) return str(a.b) from rpython.rtyper.llinterp import LLInterpreter from rpython.translator.c.genc import CStandaloneBuilder t = rtype(entrypoint, [s_list_of_strings]) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) cbuild.make_entrypoint_wrapper = False db = cbuild.build_database() entrypointptr = cbuild.getentrypointptr() entrygraph = entrypointptr._obj.graph r_list_of_strings = t.rtyper.getrepr(s_list_of_strings) ll_argv = r_list_of_strings.convert_const([]) llinterp = LLInterpreter(t.rtyper) # FIIIIISH setupgraph = db.gctransformer.frameworkgc_setup_ptr.value._obj.graph llinterp.eval_graph(setupgraph, []) res = llinterp.eval_graph(entrygraph, [ll_argv]) assert ''.join(res.chars) == "2"
def run_rtyper(fn): t = rtype(fn, [s_list_of_strings]) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, fn, t.config, gcpolicy=FrameworkGcPolicy2) cbuild.make_entrypoint_wrapper = False cbuild.build_database() return True
def test_count_vars_simple(): S = lltype.GcStruct('abc', ('x', lltype.Signed)) def f(): s1 = lltype.malloc(S) s2 = lltype.malloc(S) s1.x = 1 s2.x = 2 return s1.x + s2.x t = rtype(f, []) assert relevant_gcvars_graph(graphof(t, f)) == [0, 1]
def test_canrelease_external(): for rel in ['auto', True, False]: for sbxs in [True, False]: fext = rffi.llexternal('fext2', [], lltype.Void, releasegil=rel, sandboxsafe=sbxs) def g(): fext() t = rtype(g, []) gg = graphof(t, g) releases = (rel == 'auto' and not sbxs) or rel is True assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call(gg)
def test_count_vars_big(): from rpython.translator.goal.targetrpystonex import make_target_definition from rpython.translator.backendopt.all import backend_optimizations entrypoint, _, _ = make_target_definition(10) t = rtype(entrypoint, [int]) backend_optimizations(t) # does not crash rel = relevant_gcvars(t) print rel print sum(rel) / float(len(rel)), max(rel), min(rel) rel = relevant_gcvars(t, filter_for_nongcptr) print rel print sum(rel) / float(len(rel)), max(rel), min(rel)
def test_canrelease_instantiate(): class O: pass class A(O): pass class B(O): pass classes = [A, B] def g(i): classes[i]() t = rtype(g, [int]) gg = graphof(t, g) assert not gilanalysis.GilAnalyzer(t).analyze_direct_call(gg)
def test_no_release_gil(): from rpython.rlib import rgc @rgc.no_release_gil def g(): return 1 assert g._dont_inline_ assert g._no_release_gil_ def entrypoint(argv): return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) gilanalysis.analyze(t.graphs, t)
def test_find_initializing_stores(): class A(object): pass class B(object): pass def f(): a = A() b = B() b.a = a b.b = 1 t = rtype(f, []) etrafo = ExceptionTransformer(t) graphs = etrafo.transform_completely() collect_analyzer = CollectAnalyzer(t) init_stores = find_initializing_stores(collect_analyzer, t.graphs[0]) assert len(init_stores) == 1
def test_canrelease_external(): for rel in ['auto', True, False]: for sbxs in [True, False]: fext = rffi.llexternal('fext2', [], lltype.Void, releasegil=rel, sandboxsafe=sbxs) def g(): fext() t = rtype(g, []) gg = graphof(t, g) releases = (rel == 'auto' and not sbxs) or rel is True assert releases == gilanalysis.GilAnalyzer(t).analyze_direct_call( gg)
def test_list_operations(): class A(object): pass def f(): l = [A(), A()] l.append(A()) l[1] = l[0] return len(l) t = rtype(f, []) backend_optimizations(t, clever_malloc_removal=False, storesink=True) etrafo = ExceptionTransformer(t) graph = etrafo.transform_completely() collect_analyzer = CollectAnalyzer(t) clean_setarrayitems = find_clean_setarrayitems(collect_analyzer, t.graphs[0]) assert len(clean_setarrayitems) == 1
def test_no_release_gil_detect(gc="minimark"): from rpython.rlib import rgc fext1 = rffi.llexternal('fext1', [], lltype.Void, releasegil=True) @rgc.no_release_gil def g(): fext1() return 1 assert g._dont_inline_ assert g._no_release_gil_ def entrypoint(argv): return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) f = py.test.raises(Exception, gilanalysis.analyze, t.graphs, t) expected = "'no_release_gil' function can release the GIL: <function g at " assert str(f.value).startswith(expected)
def test_no_collect(): from rpython.rlib import rgc from rpython.translator.c.genc import CStandaloneBuilder @rgc.no_collect def g(): return 1 assert g._dont_inline_ assert g._gc_no_collect_ def entrypoint(argv): return g() + 2 t = rtype(entrypoint, [s_list_of_strings]) t.config.translation.gc = "minimark" cbuild = CStandaloneBuilder(t, entrypoint, t.config, gcpolicy=FrameworkGcPolicy2) db = cbuild.generate_graphs_for_llinterp()
def test_find_clean_setarrayitems(): S = lltype.GcStruct('S') A = lltype.GcArray(lltype.Ptr(S)) def f(): l = lltype.malloc(A, 3) l[0] = lltype.malloc(S) l[1] = lltype.malloc(S) l[2] = lltype.malloc(S) x = l[1] l[0] = x return len(l) t = rtype(f, []) etrafo = ExceptionTransformer(t) graph = etrafo.transform_completely() collect_analyzer = CollectAnalyzer(t) clean_setarrayitems = find_clean_setarrayitems(collect_analyzer, t.graphs[0]) assert len(clean_setarrayitems) == 1