[pypy-commit] pypy cpyext-gc-support: test create_link_pypy() with REFCNT_FROM_PYPY
arigo
noreply at buildbot.pypy.org
Fri Oct 16 14:10:24 EDT 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80291:97943215d17a
Date: 2015-10-16 20:10 +0200
http://bitbucket.org/pypy/pypy/changeset/97943215d17a/
Log: test create_link_pypy() with REFCNT_FROM_PYPY
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
@@ -2761,7 +2761,7 @@
def _pyobj(self, pyobjaddr):
return llmemory.cast_adr_to_ptr(pyobjaddr, self.PYOBJ_HDR_PTR)
- def rawrefcount_init(self):
+ def rawrefcount_init(self, dealloc_callback):
# see pypy/doc/discussion/rawrefcount.rst
if not self.rrc_enabled:
self.rrc_p_list_young = self.AddressStack()
@@ -2772,6 +2772,7 @@
p = lltype.malloc(self._ADDRARRAY, 1, flavor='raw',
track_allocation=False)
self.rrc_singleaddr = llmemory.cast_ptr_to_adr(p)
+ self.rrc_dealloc_callback = dealloc_callback
self.rrc_enabled = True
def check_no_more_rawrefcount_state(self):
@@ -2854,19 +2855,19 @@
from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_DIRECT
#
rc = self._pyobj(pyobject).ob_refcnt
- if rc == REFCNT_FROM_PYPY_DIRECT:
+ if rc >= REFCNT_FROM_PYPY_DIRECT:
+ ll_assert(rc == REFCNT_FROM_PYPY_DIRECT,
+ "cpyext: rrc_trace() should have marked the pypy obj alive")
lltype.free(self._pyobj(pyobject), flavor='raw')
else:
+ ll_assert(rc >= REFCNT_FROM_PYPY, "refcount underflow?")
ll_assert(rc < int(REFCNT_FROM_PYPY_DIRECT * 0.99),
"refcount underflow from REFCNT_FROM_PYPY_DIRECT?")
- if rc > REFCNT_FROM_PYPY_DIRECT:
- rc -= REFCNT_FROM_PYPY_DIRECT
- else:
- ll_assert(rc >= REFCNT_FROM_PYPY, "refcount underflow?")
- rc -= REFCNT_FROM_PYPY
- if rc == 0:
- xxx # _Py_Dealloc(pyobject)
+ rc -= REFCNT_FROM_PYPY
self._pyobj(pyobject).ob_refcnt = rc
+ self._pyobj(pyobject).ob_pypy_link = 0
+ if rc == 0:
+ self.rrc_dealloc_callback(pyobject)
_rrc_free._always_inline_ = True
def rrc_major_collection_trace(self):
diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py
--- a/rpython/memory/gc/test/test_rawrefcount.py
+++ b/rpython/memory/gc/test/test_rawrefcount.py
@@ -31,7 +31,8 @@
r1.ob_refcnt = rc
r1.ob_pypy_link = 0
r1addr = llmemory.cast_ptr_to_adr(r1)
- self.gc.rawrefcount_init()
+ self.dealloc = []
+ self.gc.rawrefcount_init(self.dealloc.append)
if is_pyobj:
assert not is_direct
self.gc.rawrefcount_create_link_pyobj(p1ref, r1addr)
@@ -87,6 +88,7 @@
py.test.raises(RuntimeError, "r1.ob_refcnt") # dead
py.test.raises(RuntimeError, "p1.x") # dead
self.gc.check_no_more_rawrefcount_state()
+ assert self.dealloc == []
def test_rawrefcount_objects_collection_survives_from_obj(self):
p1, p1ref, r1, r1addr, check_alive = (
@@ -105,3 +107,47 @@
py.test.raises(RuntimeError, "r1.ob_refcnt") # dead
py.test.raises(RuntimeError, "p1.x") # dead
self.gc.check_no_more_rawrefcount_state()
+ assert self.dealloc == []
+
+ def test_pypy_nondirect_survives_from_raw(self):
+ p1, p1ref, r1, r1addr, check_alive = (
+ self._rawrefcount_pair(42, is_direct=False))
+ check_alive(0)
+ r1.ob_refcnt += 1
+ self.gc.minor_collection()
+ check_alive(+1)
+ self.gc.collect()
+ check_alive(+1)
+ r1.ob_refcnt -= 1
+ self.gc.minor_collection()
+ p1 = check_alive(0)
+ assert self.dealloc == []
+ self.gc.collect()
+ py.test.raises(RuntimeError, "p1.x") # dead
+ assert r1.ob_refcnt == 0
+ assert r1.ob_pypy_link == 0
+ assert self.dealloc == [r1addr]
+ self.gc.check_no_more_rawrefcount_state()
+ lltype.free(r1, flavor='raw')
+
+ def test_pypy_nondirect_survives_from_obj(self):
+ p1, p1ref, r1, r1addr, check_alive = (
+ self._rawrefcount_pair(42, is_direct=False))
+ check_alive(0)
+ self.stackroots.append(p1)
+ self.gc.minor_collection()
+ check_alive(0)
+ self.gc.collect()
+ check_alive(0)
+ p1 = self.stackroots.pop()
+ self.gc.minor_collection()
+ check_alive(0)
+ assert p1.x == 42
+ assert self.dealloc == []
+ self.gc.collect()
+ py.test.raises(RuntimeError, "p1.x") # dead
+ assert r1.ob_refcnt == 0
+ assert r1.ob_pypy_link == 0
+ assert self.dealloc == [r1addr]
+ self.gc.check_no_more_rawrefcount_state()
+ lltype.free(r1, flavor='raw')
More information about the pypy-commit
mailing list