[pypy-commit] pypy counter-decay: Simplify and "stand-alone-ize" the clean-up of old jitcells from
arigo
noreply at buildbot.pypy.org
Tue Dec 20 09:42:33 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: counter-decay
Changeset: r50746:5f38cbc2c7f7
Date: 2011-12-20 09:30 +0100
http://bitbucket.org/pypy/pypy/changeset/5f38cbc2c7f7/
Log: Simplify and "stand-alone-ize" the clean-up of old jitcells from the
jitcell dict.
diff --git a/pypy/jit/metainterp/test/test_warmstate.py b/pypy/jit/metainterp/test/test_warmstate.py
--- a/pypy/jit/metainterp/test/test_warmstate.py
+++ b/pypy/jit/metainterp/test/test_warmstate.py
@@ -277,65 +277,50 @@
assert res is True
def test_cleanup_jitcell_dict():
- from pypy.jit.metainterp.memmgr import MemoryManager
- class FakeWarmRunnerDesc:
- memory_manager = MemoryManager()
- class cpu:
- pass
class FakeJitDriverSD:
_green_args_spec = [lltype.Signed]
#
# Test creating tons of jitcells that remain at 0
- warmstate = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD())
+ warmstate = WarmEnterState(None, FakeJitDriverSD())
get_jitcell = warmstate._make_jitcell_getter_default()
cell1 = get_jitcell(True, -1)
assert len(warmstate._jitcell_dict) == 1
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 1
#
for i in range(1, 20005):
get_jitcell(True, i) # should trigger a clean-up at 20001
assert len(warmstate._jitcell_dict) == (i % 20000) + 1
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 2
#
# Same test, with one jitcell that has a counter of BASE instead of 0
- warmstate = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD())
- warmstate.set_param_decay_halflife(2)
- warmstate.set_param_threshold(5)
- warmstate.set_param_function_threshold(0)
+ warmstate = WarmEnterState(None, FakeJitDriverSD())
get_jitcell = warmstate._make_jitcell_getter_default()
cell2 = get_jitcell(True, -2)
- cell2.counter = BASE = warmstate.increment_threshold * 3
+ cell2.counter = BASE = warmstate.THRESHOLD_LIMIT // 2 # 50%
#
for i in range(0, 20005):
get_jitcell(True, i)
assert len(warmstate._jitcell_dict) == (i % 19999) + 2
#
assert cell2 in warmstate._jitcell_dict.values()
- assert cell2.counter == int(BASE * math.sqrt(0.5)) # decayed once
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 3
+ assert cell2.counter == int(BASE * 0.92) # decayed once
#
- # Same test, with jitcells that are compiled and free by the memmgr
- warmstate = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD())
+ # Same test, with jitcells that are compiled and freed by the memmgr
+ warmstate = WarmEnterState(None, FakeJitDriverSD())
get_jitcell = warmstate._make_jitcell_getter_default()
get_jitcell(True, -1)
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 3
#
for i in range(1, 20005):
cell = get_jitcell(True, i)
cell.counter = -1
cell.wref_procedure_token = None # or a dead weakref, equivalently
assert len(warmstate._jitcell_dict) == (i % 20000) + 1
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 4
#
# Same test, with counter == -2 (rare case, kept alive)
- warmstate = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD())
+ warmstate = WarmEnterState(None, FakeJitDriverSD())
get_jitcell = warmstate._make_jitcell_getter_default()
cell = get_jitcell(True, -1)
cell.counter = -2
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 4
#
for i in range(1, 20005):
cell = get_jitcell(True, i)
cell.counter = -2
assert len(warmstate._jitcell_dict) == i + 1
- assert FakeWarmRunnerDesc.memory_manager.current_generation == 5
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -446,44 +446,32 @@
except AttributeError:
pass
#
- memmgr = self.warmrunnerdesc and self.warmrunnerdesc.memory_manager
- if memmgr:
- def _cleanup_dict():
- minimum = sys.maxint
- if self.increment_threshold > 0:
- minimum = min(minimum, self.increment_threshold)
- if self.increment_function_threshold > 0:
- minimum = min(minimum, self.increment_function_threshold)
- currentgen = memmgr.get_current_generation_uint()
- killme = []
- for key, cell in jitcell_dict.iteritems():
- if cell.counter >= 0:
- cell.adjust_counter(currentgen, self.log_decay_factor)
- if cell.counter < minimum:
- killme.append(key)
- elif (cell.counter == -1
- and cell.get_procedure_token() is None):
+ def _cleanup_dict():
+ minimum = self.THRESHOLD_LIMIT // 20 # minimum 5%
+ killme = []
+ for key, cell in jitcell_dict.iteritems():
+ if cell.counter >= 0:
+ cell.counter = int(cell.counter * 0.92)
+ if cell.counter < minimum:
killme.append(key)
- for key in killme:
- del jitcell_dict[key]
- #
- def _maybe_cleanup_dict():
- # If no tracing goes on at all because the jitcells are
- # each time for new greenargs, the dictionary grows forever.
- # So every one in a (rare) while, we decide to force an
- # artificial next_generation() and _cleanup_dict().
- self._trigger_automatic_cleanup += 1
- if self._trigger_automatic_cleanup > 20000:
- self._trigger_automatic_cleanup = 0
- memmgr.next_generation(do_cleanups_now=False)
- _cleanup_dict()
- #
- self._trigger_automatic_cleanup = 0
- self._jitcell_dict = jitcell_dict # for tests
- memmgr.record_jitcell_dict(_cleanup_dict)
- else:
- def _maybe_cleanup_dict():
- pass
+ elif (cell.counter == -1
+ and cell.get_procedure_token() is None):
+ killme.append(key)
+ for key in killme:
+ del jitcell_dict[key]
+ #
+ def _maybe_cleanup_dict():
+ # Once in a while, rarely, when too many entries have
+ # been put in the jitdict_dict, we do a cleanup phase:
+ # we decay all counters and kill entries with a too
+ # low counter.
+ self._trigger_automatic_cleanup += 1
+ if self._trigger_automatic_cleanup > 20000:
+ self._trigger_automatic_cleanup = 0
+ _cleanup_dict()
+ #
+ self._trigger_automatic_cleanup = 0
+ self._jitcell_dict = jitcell_dict # for tests
#
def get_jitcell(build, *greenargs):
try:
@@ -503,7 +491,7 @@
get_jitcell_at_ptr = self.jitdriver_sd._get_jitcell_at_ptr
set_jitcell_at_ptr = self.jitdriver_sd._set_jitcell_at_ptr
lltohlhack = {}
- # note that there is no equivalent of record_jitcell_dict()
+ # note that there is no equivalent of _maybe_cleanup_dict()
# in the case of custom getters. We assume that the interpreter
# stores the JitCells on some objects that can go away by GC,
# like the PyCode objects in PyPy.
More information about the pypy-commit
mailing list