[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