[pypy-svn] r80007 - pypy/branch/out-of-line-guards/pypy/jit/metainterp

fijal at codespeak.net fijal at codespeak.net
Sun Dec 12 20:29:33 CET 2010


Author: fijal
Date: Sun Dec 12 20:29:30 2010
New Revision: 80007

Added:
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py
Log:
Simply copy memmgr.py here. Not sure what svn merge did


Added: pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py
==============================================================================
--- (empty file)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py	Sun Dec 12 20:29:30 2010
@@ -0,0 +1,79 @@
+import math
+from pypy.rlib.rarithmetic import r_int64
+from pypy.rlib.debug import debug_start, debug_print, debug_stop
+from pypy.rlib.objectmodel import we_are_translated
+
+#
+# Logic to decide which loops are old and not used any more.
+#
+# All the long-lived references to LoopToken are weakrefs (see JitCell
+# in warmstate.py), apart from the 'alive_loops' set in MemoryManager,
+# which is the only (long-living) place that keeps them alive.  If a
+# loop was not called for long enough, then it is removed from
+# 'alive_loops'.  It will soon be freed by the GC.  LoopToken.__del__
+# calls the method cpu.free_loop_and_bridges().
+#
+# The alive_loops set is maintained using the notion of a global
+# 'current generation' which is, in practice, the total number of loops
+# and bridges produced so far.  A LoopToken is declared "old" if its
+# 'generation' field is much smaller than the current generation, and
+# removed from the set.
+#
+
+class MemoryManager(object):
+
+    def __init__(self):
+        self.check_frequency = -1
+        # NB. use of r_int64 to be extremely far on the safe side:
+        # this is increasing by one after each loop or bridge is
+        # compiled, and it must not overflow.  If the backend implements
+        # complete freeing in cpu.free_loop_and_bridges(), then it may
+        # be possible to get arbitrary many of them just by waiting long
+        # enough.  But in this day and age, you'd still never have the
+        # patience of waiting for a slowly-increasing 64-bit number to
+        # overflow :-)
+        self.current_generation = r_int64(1)
+        self.next_check = r_int64(-1)
+        self.alive_loops = {}
+
+    def set_max_age(self, max_age, check_frequency=0):
+        if max_age <= 0:
+            self.next_check = r_int64(-1)
+        else:
+            self.max_age = max_age
+            if check_frequency <= 0:
+                check_frequency = int(math.sqrt(max_age))
+            self.check_frequency = check_frequency
+            self.next_check = self.current_generation + 1
+
+    def next_generation(self):
+        self.current_generation += 1
+        if self.current_generation == self.next_check:
+            self._kill_old_loops_now()
+            self.next_check = self.current_generation + self.check_frequency
+
+    def keep_loop_alive(self, looptoken):
+        if looptoken.generation != self.current_generation:
+            looptoken.generation = self.current_generation
+            self.alive_loops[looptoken] = None
+
+    def _kill_old_loops_now(self):
+        debug_start("jit-mem-collect")
+        oldtotal = len(self.alive_loops)
+        #print self.alive_loops.keys()
+        debug_print("Current generation:", self.current_generation)
+        debug_print("Loop tokens before:", oldtotal)
+        max_generation = self.current_generation - (self.max_age-1)
+        for looptoken in self.alive_loops.keys():
+            if 0 <= looptoken.generation < max_generation:
+                del self.alive_loops[looptoken]
+        newtotal = len(self.alive_loops)
+        debug_print("Loop tokens freed: ", oldtotal - newtotal)
+        debug_print("Loop tokens left:  ", newtotal)
+        #print self.alive_loops.keys()
+        if not we_are_translated() and oldtotal != newtotal:
+            looptoken = None
+            from pypy.rlib import rgc
+            # a single one is not enough for all tests :-(
+            rgc.collect(); rgc.collect(); rgc.collect()
+        debug_stop("jit-mem-collect")



More information about the Pypy-commit mailing list