[pypy-commit] pypy gc-disable: implement the gctransoform and C backend part of rgc.{enable, disable, isenabled}
antocuni
pypy.commits at gmail.com
Mon May 21 10:07:59 EDT 2018
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: gc-disable
Changeset: r94637:a9e0a0777f86
Date: 2018-05-21 15:49 +0200
http://bitbucket.org/pypy/pypy/changeset/a9e0a0777f86/
Log: implement the gctransoform and C backend part of
rgc.{enable,disable,isenabled}
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
@@ -149,6 +149,16 @@
def get_size_incl_hash(self, obj):
return self.get_size(obj)
+ # these can be overriden by subclasses, called by the GCTransformer
+ def enable(self):
+ pass
+
+ def disable(self):
+ pass
+
+ def isenabled(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/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -522,6 +522,9 @@
def disable(self):
self.enabled = False
+ def isenabled(self):
+ return self.enabled
+
def _nursery_memory_size(self):
extra = self.nonlarge_max + 1
return self.nursery_size + extra
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,10 @@
self.collect_ptr = getfn(GCClass.collect.im_func,
[s_gc, annmodel.SomeInteger()], annmodel.s_None)
+ 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],
+ annmodel.s_Bool)
self.can_move_ptr = getfn(GCClass.can_move.im_func,
[s_gc, SomeAddress()],
annmodel.SomeBool())
@@ -884,6 +888,21 @@
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],
+ resultvar=op.result)
+
+ def gct_gc__disable(self, hop):
+ op = hop.spaceop
+ hop.genop("direct_call", [self.disable_ptr, self.c_const_gc],
+ resultvar=op.result)
+
+ def gct_gc__isenabled(self, hop):
+ op = hop.spaceop
+ hop.genop("direct_call", [self.isenabled_ptr, self.c_const_gc],
+ resultvar=op.result)
+
def gct_gc_can_move(self, hop):
op = hop.spaceop
v_addr = hop.genop('cast_ptr_to_adr',
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
@@ -1812,6 +1812,45 @@
res = self.run("ignore_finalizer")
assert res == 1 # translated: x1 is removed from the list
+ def define_enable_disable(self):
+ class Counter(object):
+ val = 0
+ counter = Counter()
+ class X(object):
+ def __del__(self):
+ counter.val += 1
+ def f(should_disable):
+ x1 = X()
+ rgc.collect() # make x1 old
+ assert not rgc.can_move(x1)
+ x1 = None
+ #
+ if should_disable:
+ gc.disable()
+ assert not gc.isenabled()
+ # try to trigger a major collection
+ N = 100 # this should be enough, increase if not
+ lst = []
+ for i in range(N):
+ lst.append(chr(i%256) * (1024*1024))
+ #print i, counter.val
+ #
+ gc.enable()
+ assert gc.isenabled()
+ return counter.val
+ return f
+
+ def test_enable_disable(self):
+ # first, run with normal gc. If the assert fails it means that in the
+ # loop we don't allocate enough mem to trigger a major collection. Try
+ # to increase N
+ deleted = self.run("enable_disable", 0)
+ assert deleted == 1, 'This should not fail, try to increment N'
+ #
+ # now, run with gc.disable: this should NOT free x1
+ deleted = self.run("enable_disable", 1)
+ assert deleted == 0
+
# ____________________________________________________________________
More information about the pypy-commit
mailing list