Author: Armin Rigo <ar...@tunes.org> Branch: cpyext-gc-support Changeset: r80286:937683219fcd Date: 2015-10-16 19:09 +0200 http://bitbucket.org/pypy/pypy/changeset/937683219fcd/
Log: Pass one test and a half 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 @@ -1602,6 +1602,10 @@ self._visit_old_objects_pointing_to_pinned, None) current_old_objects_pointing_to_pinned.delete() # + # visit the P list from rawrefcount, if enabled. + if self.rrc_enabled: + self.rrc_minor_collection_trace() + # while True: # If we are using card marking, do a partial trace of the arrays # that are flagged with GCFLAG_CARDS_SET. @@ -1650,6 +1654,10 @@ if self.young_rawmalloced_objects: self.free_young_rawmalloced_objects() # + # visit the P and O lists from rawrefcount, if enabled. + if self.rrc_enabled: + self.rrc_minor_collection_free() + # # All live nursery objects are out of the nursery or pinned inside # the nursery. Create nursery barriers to protect the pinned objects, # fill the rest of the nursery with zeros and reset the current nursery @@ -2734,10 +2742,16 @@ # ---------- # RawRefCount - OB_REFCNT = 0 - OB_PYPY_LINK = 1 + rrc_enabled = False - rrc_enabled = False + _ADDRARRAY = lltype.Array(llmemory.Address, hints={'nolength': True}) + PYOBJ_HDR = lltype.Struct('GCHdr_PyObject', + ('ob_refcnt', lltype.Signed), + ('ob_pypy_link', lltype.Signed)) + PYOBJ_HDR_PTR = lltype.Ptr(PYOBJ_HDR) + + def _pyobj(self, pyobjaddr): + return llmemory.cast_adr_to_ptr(pyobjaddr, self.PYOBJ_HDR_PTR) def rawrefcount_init(self): # see pypy/doc/discussion/rawrefcount.rst @@ -2747,17 +2761,20 @@ self.rrc_o_list_young = self.AddressStack() self.rrc_o_list_old = self.AddressStack() self.rrc_dict = self.AddressDict() + p = lltype.malloc(self._ADDRARRAY, 1, flavor='raw', + track_allocation=False) + self.rrc_singleaddr = llmemory.cast_ptr_to_adr(p) self.rrc_enabled = True def rawrefcount_create_link_pypy(self, gcobj, pyobject): ll_assert(self.rrc_enabled, "rawrefcount.init not called") obj = llmemory.cast_ptr_to_adr(gcobj) if self.is_young_object(obj): - self.rrc_p_list_young.append(obj) + self.rrc_p_list_young.append(pyobject) else: - self.rrc_p_list_old.append(obj) + self.rrc_p_list_old.append(pyobject) objint = llmemory.cast_adr_to_int(obj, mode="symbolic") - pyobject.signed[self.OB_PYPY_LINK] = objint + self._pyobj(pyobject).ob_pypy_link = objint self.rrc_dict.setitem(obj, pyobject) def rawrefcount_from_obj(self, gcobj): @@ -2765,5 +2782,67 @@ return self.rrc_dict.get(obj) def rawrefcount_to_obj(self, pyobject): - obj = llmemory.cast_int_to_adr(pyobject.signed[self.OB_PYPY_LINK]) + obj = llmemory.cast_int_to_adr(self._pyobj(pyobject).ob_pypy_link) return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF) + + + def rrc_minor_collection_trace(self): + self.rrc_p_list_young.foreach(self._rrc_minor_trace, + self.rrc_singleaddr) + + def _rrc_minor_trace(self, pyobject, singleaddr): + from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY + from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_DIRECT + # + rc = self._pyobj(pyobject).ob_refcnt + if rc == REFCNT_FROM_PYPY or rc == REFCNT_FROM_PYPY_DIRECT: + pass # the corresponding object may die + else: + # force the corresponding object to be alive + intobj = self._pyobj(pyobject).ob_pypy_link + singleaddr.address[0] = llmemory.cast_int_to_adr(intobj) + self._trace_drag_out(singleaddr, llmemory.NULL) + + def rrc_minor_collection_free(self): + lst = self.rrc_p_list_young + while lst.non_empty(): + self._rrc_minor_free(lst.pop(), self.rrc_p_list_old) + + def _rrc_minor_free(self, pyobject, add_into_list): + from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY + from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_DIRECT + # + intobj = self._pyobj(pyobject).ob_pypy_link + obj = llmemory.cast_int_to_adr(intobj) + if self.is_in_nursery(obj): + if self.is_forwarded(obj): + # Common case: survives and moves + obj = self.get_forwarding_address(obj) + intobj = llmemory.cast_adr_to_int(obj, mode="symbolic") + self._pyobj(pyobject).ob_pypy_link = intobj + self.rrc_dict.setitem(obj, pyobject) + surviving = True + else: + surviving = False + elif (bool(self.young_rawmalloced_objects) and + self.young_rawmalloced_objects.contains(pointing_to)): + # young weakref to a young raw-malloced object + if self.header(pointing_to).tid & GCFLAG_VISITED_RMY: + surviving = True # survives, but does not move + else: + surviving = False + # + if surviving: + add_into_list.append(obj) + else: + rc = self._pyobj(pyobject).ob_refcnt + if rc == self.REFCNT_FROM_PYPY_DIRECT: + llmemory.raw_free(pyobject) + else: + if rc > self.REFCNT_FROM_PYPY_DIRECT: + rc -= self.REFCNT_FROM_PYPY_DIRECT + else: + rc -= self.REFCNT_FROM_PYPY + if rc == 0: + xxx # _Py_Dealloc(pyobject) + self._pyobj(pyobject).ob_refcnt = rc 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 @@ -4,11 +4,8 @@ from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_DIRECT -PYOBJ_HDR = lltype.Array(lltype.Signed, hints={'nolength': True}) -PYOBJ_HDR_PTR = lltype.Ptr(PYOBJ_HDR) - -OB_REFCNT = IncrementalMiniMarkGC.OB_REFCNT -OB_PYPY_LINK = IncrementalMiniMarkGC.OB_PYPY_LINK +PYOBJ_HDR = IncrementalMiniMarkGC.PYOBJ_HDR +PYOBJ_HDR_PTR = IncrementalMiniMarkGC.PYOBJ_HDR_PTR S = lltype.GcForwardReference() S.become(lltype.GcStruct('S', @@ -29,9 +26,9 @@ p1 = self.malloc(S) p1.x = intval p1ref = lltype.cast_opaque_ptr(llmemory.GCREF, p1) - r1 = lltype.malloc(PYOBJ_HDR, 3, flavor='raw') - r1[OB_REFCNT] = rc - r1[OB_PYPY_LINK] = 0 + r1 = lltype.malloc(PYOBJ_HDR, flavor='raw') + r1.ob_refcnt = rc + r1.ob_pypy_link = 0 r1addr = llmemory.cast_ptr_to_adr(r1) self.gc.rawrefcount_init() if is_pyobj: @@ -39,8 +36,8 @@ self.gc.rawrefcount_create_link_pyobj(p1ref, r1addr) else: self.gc.rawrefcount_create_link_pypy(p1ref, r1addr) - assert r1[OB_REFCNT] == rc - assert r1[OB_PYPY_LINK] != 0 + assert r1.ob_refcnt == rc + assert r1.ob_pypy_link != 0 return p1, p1ref, r1, r1addr def test_rawrefcount_objects_basic(self): @@ -48,13 +45,13 @@ p2 = self.malloc(S) p2.x = 84 p2ref = lltype.cast_opaque_ptr(llmemory.GCREF, p2) - r2 = lltype.malloc(PYOBJ_HDR, 3, flavor='raw') - r2[0] = 1 - r2[1] = 0 + r2 = lltype.malloc(PYOBJ_HDR, flavor='raw') + r2.ob_refcnt = 1 + r2.ob_pypy_link = 0 r2addr = llmemory.cast_ptr_to_adr(r2) # p2 and r2 are not linked - assert r1[1] != 0 - assert r2[1] == 0 + assert r1.ob_pypy_link != 0 + assert r2.ob_pypy_link == 0 assert self.gc.rawrefcount_from_obj(p1ref) == r1addr assert self.gc.rawrefcount_from_obj(p2ref) == llmemory.NULL assert self.gc.rawrefcount_to_obj(r1addr) == p1ref @@ -66,11 +63,11 @@ def test_rawrefcount_objects_collection_survives_from_raw(self): for do_collect in [self.gc.minor_collection, self.gc.collect] * 2: p1, p1ref, r1, r1addr = self._rawrefcount_pair(42, is_direct=True) - assert r1.c_ob_refcnt == REFCNT_FROM_PYPY_DIRECT + assert r1.ob_refcnt == REFCNT_FROM_PYPY_DIRECT r1.ob_refcnt += 1 do_collect() - assert r1.ob_refcnt == REFCNT_FROM_PYPY_OBJECT + 1 - assert r1.ob_pypy_link != llmemory.NULL + assert r1.ob_refcnt == REFCNT_FROM_PYPY_DIRECT + 1 + assert r1.ob_pypy_link != 0 p1ref = self.gc.rawrefcount_to_obj(r1addr) assert lltype.cast_opaque_ptr(lltype.Ptr(S), p1ref).x == 42 assert self.gc.rawrefcount_from_obj(p1ref) == r1addr _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit