Author: Armin Rigo <[email protected]>
Branch: counter-decay
Changeset: r50542:f7182dd71d78
Date: 2011-12-15 10:53 +0100
http://bitbucket.org/pypy/pypy/changeset/f7182dd71d78/
Log: Test and fix.
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
@@ -286,3 +286,67 @@
assert cell.counter == 90
cell.adjust_counter(r_uint(9), math.log(0.9))
assert cell.counter == int(90 * (0.9**3))
+
+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())
+ 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)
+ get_jitcell = warmstate._make_jitcell_getter_default()
+ cell2 = get_jitcell(True, -2)
+ cell2.counter = BASE = warmstate.increment_threshold * 3
+ #
+ 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
+ #
+ # Same test, with jitcells that are compiled and free by the memmgr
+ warmstate = WarmEnterState(FakeWarmRunnerDesc(), 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())
+ 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
@@ -494,8 +494,11 @@
memmgr = self.warmrunnerdesc and self.warmrunnerdesc.memory_manager
if memmgr:
def _cleanup_dict():
- minimum = min(self.increment_threshold,
- self.increment_function_threshold)
+ 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():
@@ -503,6 +506,9 @@
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):
+ killme.append(key)
for key in killme:
del jitcell_dict[key]
#
@@ -518,6 +524,7 @@
_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():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit