[pypy-commit] pypy gc-disable: implement rgc.collect_step() through all the layers
antocuni
pypy.commits at gmail.com
Wed May 30 12:43:41 EDT 2018
Author: Antonio Cuni <anto.cuni at 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
+
# ____________________________________________________________________
More information about the pypy-commit
mailing list