Author: Stefan Beyer <h...@sbeyer.at> Branch: cpyext-gc-cycle Changeset: r96947:b048d08d615e Date: 2019-06-30 19:41 +0200 http://bitbucket.org/pypy/pypy/changeset/b048d08d615e/
Log: Fixed some issues with rrc finalizers 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 @@ -3456,7 +3456,11 @@ self._rrc_mark_garbage() self._rrc_debug_check_consistency(print_label="end-legacy-fin") self.rrc_state = self.RAWREFCOUNT_STATE_DEFAULT - use_cylicrc = not self._rrc_find_finalizer() # modern finalizers + found_finalizer = self._rrc_find_finalizer() # modern finalizers + if found_finalizer: + self._rrc_gc_list_move(self.rrc_pyobj_old_list, + self.rrc_pyobj_isolate_list) + use_cylicrc = not found_finalizer self._rrc_debug_check_consistency(print_label="end-mark-cyclic") else: use_cylicrc = False # don't sweep any objects in cyclic isolates @@ -3820,15 +3824,18 @@ def _rrc_check_finalizer(self): # Check, if the cyclic isolate from the last collection cycle # is reachable from outside, after the finalizers have been - # executed. - self._rrc_collect_roots(self.rrc_pyobj_old_list) - found_alive = False - gchdr = self.rrc_pyobj_old_list.c_gc_next - while gchdr <> self.rrc_pyobj_old_list: - if (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0: - found_alive = True - break - gchdr = gchdr.c_gc_next + # executed (and if all finalizers have been executed). + found_alive = self._rrc_gc_list_is_empty(self.rrc_pyobj_isolate_list) + if not found_alive: + found_alive = self._rrc_find_finalizer() + if not found_alive: + self._rrc_collect_roots(self.rrc_pyobj_old_list) + gchdr = self.rrc_pyobj_old_list.c_gc_next + while gchdr <> self.rrc_pyobj_old_list: + if (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0: + found_alive = True + break + gchdr = gchdr.c_gc_next if found_alive: self._rrc_gc_list_merge(self.rrc_pyobj_old_list, self.rrc_pyobj_list) @@ -3840,17 +3847,13 @@ return True def _rrc_find_finalizer(self): - found_finalizer = False gchdr = self.rrc_pyobj_old_list.c_gc_next while gchdr <> self.rrc_pyobj_old_list: if self.rrc_finalizer_type(gchdr) == \ self.RAWREFCOUNT_FINALIZER_MODERN: - found_finalizer = True + return True gchdr = gchdr.c_gc_next - if found_finalizer: - self._rrc_gc_list_move(self.rrc_pyobj_old_list, - self.rrc_pyobj_isolate_list) - return found_finalizer + return False def _rrc_visit(pyobj, self_ptr): from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance 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 @@ -62,10 +62,9 @@ def rawrefcount_finalizer_type(gc): pyobj = self.pyobjs[self.gcobjs.index(gc)] - if pyobj in self.pyobjs and \ - self.pyobj_finalizer.has_key(self.pyobjs.index(pyobj)): - # TODO: improve test, so that NONE is returned, if finalizer - # has already been called (only for modern) + index = self.pyobjs.index(pyobj) + if pyobj in self.pyobjs and self.pyobj_finalizer.has_key(index) \ + and not self.pyobj_finalized.has_key(index): return self.pyobj_finalizer[self.pyobjs.index(pyobj)] else: return RAWREFCOUNT_FINALIZER_NONE _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit