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

Reply via email to