Author: Antonio Cuni <anto.c...@gmail.com> Branch: gc-disable Changeset: r94712:868c42b150e9 Date: 2018-05-29 18:58 +0200 http://bitbucket.org/pypy/pypy/changeset/868c42b150e9/
Log: implement rgc.collect_step() through all the layers diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py --- a/rpython/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -159,6 +159,9 @@ def isenabled(self): return True + def collect_step(self): + return True + def malloc(self, typeid, length=0, zero=False): """NOT_RPYTHON For testing. The interface used by the gctransformer is 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 @@ -309,6 +309,8 @@ self.collect_ptr = getfn(GCClass.collect.im_func, [s_gc, annmodel.SomeInteger()], annmodel.s_None) + self.collect_step_ptr = getfn(GCClass.collect_step.im_func, [s_gc], + annmodel.s_Bool) self.enable_ptr = getfn(GCClass.enable.im_func, [s_gc], annmodel.s_None) self.disable_ptr = getfn(GCClass.disable.im_func, [s_gc], annmodel.s_None) self.isenabled_ptr = getfn(GCClass.isenabled.im_func, [s_gc], @@ -888,6 +890,13 @@ resultvar=op.result) self.pop_roots(hop, livevars) + def gct_gc__collect_step(self, hop): + op = hop.spaceop + livevars = self.push_roots(hop) + hop.genop("direct_call", [self.collect_step_ptr, self.c_const_gc], + resultvar=op.result) + self.pop_roots(hop, livevars) + def gct_gc__enable(self, hop): op = hop.spaceop hop.genop("direct_call", [self.enable_ptr, self.c_const_gc], diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -17,6 +17,14 @@ disable = gc.disable isenabled = gc.isenabled +def collect_step(): + """ + If the GC is incremental, run a single gc-collect-step. Return True when + the major collection is completed. + If the GC is not incremental, do nothing. + """ + return True + def set_max_heap_size(nbytes): """Limit the heap size to n bytes. """ @@ -153,6 +161,18 @@ return hop.genop('gc__isenabled', hop.args_v, resulttype=hop.r_result) +class CollectStepEntry(ExtRegistryEntry): + _about_ = collect_step + + def compute_result_annotation(self): + from rpython.annotator import model as annmodel + return annmodel.s_Bool + + def specialize_call(self, hop): + hop.exception_cannot_occur() + return hop.genop('gc__collect_step', hop.args_v, resulttype=hop.r_result) + + class SetMaxHeapSizeEntry(ExtRegistryEntry): _about_ = set_max_heap_size diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py --- a/rpython/rlib/test/test_rgc.py +++ b/rpython/rlib/test/test_rgc.py @@ -56,6 +56,19 @@ res = interpret(f, []) assert res +def test_collect_step(): + def f(): + return rgc.collect_step() + + assert f() + t, typer, graph = gengraph(f, []) + blockops = list(graph.iterblockops()) + opnames = [op.opname for block, op in blockops + if op.opname.startswith('gc__')] + assert opnames == ['gc__collect_step'] + res = interpret(f, []) + assert res + def test_can_move(): T0 = lltype.GcStruct('T') diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -819,6 +819,9 @@ def op_gc__collect(self, *gen): self.heap.collect(*gen) + def op_gc__collect_step(self): + return self.heap.collect_step() + def op_gc__enable(self): self.heap.enable() diff --git a/rpython/rtyper/lltypesystem/llheap.py b/rpython/rtyper/lltypesystem/llheap.py --- a/rpython/rtyper/lltypesystem/llheap.py +++ b/rpython/rtyper/lltypesystem/llheap.py @@ -5,7 +5,7 @@ setfield = setattr from operator import setitem as setarrayitem -from rpython.rlib.rgc import can_move, collect, enable, disable, isenabled, add_memory_pressure +from rpython.rlib.rgc import can_move, collect, enable, disable, isenabled, add_memory_pressure, collect_step def setinterior(toplevelcontainer, inneraddr, INNERTYPE, newvalue, offsets=None): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -450,6 +450,7 @@ # __________ GC operations __________ 'gc__collect': LLOp(canmallocgc=True), + 'gc__collect_step': LLOp(canmallocgc=True), 'gc__enable': LLOp(), 'gc__disable': LLOp(), 'gc__isenabled': LLOp(), diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py --- a/rpython/translator/c/test/test_newgc.py +++ b/rpython/translator/c/test/test_newgc.py @@ -1851,6 +1851,39 @@ deleted = self.run("enable_disable", 1) assert deleted == 0 + def define_collect_step(self): + class Counter(object): + val = 0 + counter = Counter() + class X(object): + def __del__(self): + counter.val += 1 + def f(): + x1 = X() + rgc.collect() # make x1 old + assert not rgc.can_move(x1) + x1 = None + # + gc.disable() + n = 0 + while True: + n += 1 + if rgc.collect_step(): + break + if n == 100: + print 'Endless loop!' + assert False, 'this looks like an endless loop' + + if n < 4: # we expect at least 4 steps + print 'Too few steps! n =', n + assert False + return counter.val + return f + + def test_collect_step(self): + deleted = self.run("collect_step") + assert deleted == 1 + # ____________________________________________________________________ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit