[pypy-commit] pypy cpyext-gc-cycle: Implemented incremental limit for non-rrc objects during rrc marking
stevie_92
pypy.commits at gmail.com
Thu Nov 21 10:33:01 EST 2019
Author: Stefan Beyer <home at sbeyer.at>
Branch: cpyext-gc-cycle
Changeset: r98130:6a71ef8d2b2c
Date: 2019-11-21 15:50 +0100
http://bitbucket.org/pypy/pypy/changeset/6a71ef8d2b2c/
Log: Implemented incremental limit for non-rrc objects during rrc marking
Added flag to enable/disable tuple untracking for debugging
diff --git a/rpython/memory/gc/rrc/base.py b/rpython/memory/gc/rrc/base.py
--- a/rpython/memory/gc/rrc/base.py
+++ b/rpython/memory/gc/rrc/base.py
@@ -84,6 +84,8 @@
RAWREFCOUNT_REFS_UNTRACKED = -2 << RAWREFCOUNT_REFS_SHIFT
RAWREFCOUNT_REFS_REACHABLE = -3 << RAWREFCOUNT_REFS_SHIFT
+ UNTRACK_TUPLES_DEFAULT = True
+
def _pyobj(self, pyobjaddr):
return llmemory.cast_adr_to_ptr(pyobjaddr, self.PYOBJ_HDR_PTR)
def _pygchdr(self, pygchdraddr):
@@ -124,6 +126,13 @@
self.state = self.STATE_DEFAULT
self.marking_state = 0
inc_limit = env.read_uint_from_env('PYPY_RRC_GC_INCREMENT_STEP')
+ untrack = env.read_uint_from_env('PYPY_RRC_GC_UNTRACK_TUPLES')
+ if untrack == 1:
+ self.untrack_tuples = True
+ elif untrack == 2:
+ self.untrack_tuples = False
+ else:
+ self.untrack_tuples = self.UNTRACK_TUPLES_DEFAULT
if inc_limit > 0:
self.inc_limit = inc_limit
else:
@@ -469,17 +478,20 @@
self._free(pyobject, True)
def _untrack_tuples(self):
- gchdr = self.tuple_list.c_gc_next
- while gchdr <> self.tuple_list:
- gchdr_next = gchdr.c_gc_next
- pyobj = self.gc_as_pyobj(gchdr)
- result = self.tuple_maybe_untrack(pyobj)
- if result == 1: # contains gc objects -> promote to pyobj list
- next = gchdr.c_gc_next
- next.c_gc_prev = gchdr.c_gc_prev
- gchdr.c_gc_prev.c_gc_next = next
- self._gc_list_add(self.pyobj_list, gchdr)
- gchdr = gchdr_next
+ if self.untrack_tuples:
+ self._debug_check_consistency(print_label="before-untrack")
+ gchdr = self.tuple_list.c_gc_next
+ while gchdr <> self.tuple_list:
+ gchdr_next = gchdr.c_gc_next
+ pyobj = self.gc_as_pyobj(gchdr)
+ result = self.tuple_maybe_untrack(pyobj)
+ if result == 1: # contains gc objects -> promote to pyobj list
+ next = gchdr.c_gc_next
+ next.c_gc_prev = gchdr.c_gc_prev
+ gchdr.c_gc_prev.c_gc_next = next
+ self._gc_list_add(self.pyobj_list, gchdr)
+ gchdr = gchdr_next
+ self._debug_check_consistency(print_label="after-untrack")
def _find_garbage(self, use_dict):
found_garbage = False
diff --git a/rpython/memory/gc/rrc/incmark.py b/rpython/memory/gc/rrc/incmark.py
--- a/rpython/memory/gc/rrc/incmark.py
+++ b/rpython/memory/gc/rrc/incmark.py
@@ -2,6 +2,7 @@
from rpython.rtyper.lltypesystem import rffi
from rpython.memory.gc.rrc.base import RawRefCountBaseGC
from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop
+from rpython.rlib.rarithmetic import intmask
import time
class RawRefCountIncMarkGC(RawRefCountBaseGC):
@@ -367,9 +368,22 @@
snapobj.refcnt += 1
self._mark_rawrefcount_obj(snapobj)
simple_limit += 1
- if simple_limit > self.inc_limit: # TODO: add test
+ if simple_limit > intmask(self.inc_limit): # TODO: add test
reached_limit = True
- self.gc.visit_all_objects() # TODO: implement sane limit
+
+ if not reached_limit:
+ # "split" the limit between rrc and non-rrc
+ # if 25% of rrc limit have been used, now use max 75% or non-rrc limit
+ if simple_limit > 0:
+ estimate = intmask(self.gc.gc_increment_step) * intmask(self.inc_limit) / simple_limit
+ else:
+ estimate = intmask(self.gc.gc_increment_step)
+ remaining = self.gc.visit_all_objects_step(estimate)
+ if remaining == 0:
+ reached_limit = True
+ else:
+ # if 25% of the non-rrc limit have been used, add 25% of the rrc limit to the counter
+ simple_limit += intmask(self.inc_limit) * remaining / estimate
first = False
return not reached_limit # are there any objects left?
diff --git a/rpython/memory/gc/rrc/simple.py b/rpython/memory/gc/rrc/simple.py
--- a/rpython/memory/gc/rrc/simple.py
+++ b/rpython/memory/gc/rrc/simple.py
@@ -2,6 +2,12 @@
class RawRefCountSimpleGC(RawRefCountBaseGC):
+ UNTRACK_TUPLES_DEFAULT = False
+
def major_collection_trace_step(self):
+ self._untrack_tuples()
self.p_list_old.foreach(self._major_trace, (False, False))
- return True
\ No newline at end of file
+ return True
+
+ def visit_pyobj(self, gcobj):
+ pass
\ No newline at end of file
More information about the pypy-commit
mailing list