Author: Armin Rigo <ar...@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') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit