Author: Armin Rigo <[email protected]>
Branch: counter-decay
Changeset: r50541:ba32c0042356
Date: 2011-12-15 01:43 +0100
http://bitbucket.org/pypy/pypy/changeset/ba32c0042356/
Log: Fix yet another obscure case in which we can end up with an apparent
leak.
diff --git a/pypy/jit/metainterp/memmgr.py b/pypy/jit/metainterp/memmgr.py
--- a/pypy/jit/metainterp/memmgr.py
+++ b/pypy/jit/metainterp/memmgr.py
@@ -50,9 +50,9 @@
self.check_frequency = check_frequency
self.next_check = self.current_generation + 1
- def next_generation(self):
+ def next_generation(self, do_cleanups_now=True):
self.current_generation += 1
- if self.current_generation == self.next_check:
+ if do_cleanups_now and self.current_generation >= self.next_check:
self._kill_old_loops_now()
self._cleanup_jitcell_dicts()
self.next_check = self.current_generation + self.check_frequency
@@ -89,7 +89,7 @@
To use only as an approximation for decaying counters."""
return r_uint(self.current_generation)
- def record_jitcell_dict(self, warmstate, jitcell_dict):
+ def record_jitcell_dict(self, callback):
"""NOT_RPYTHON. The given jitcell_dict is a dict that needs
occasional clean-ups of old cells. A cell is old if it never
reached the threshold, and its counter decayed to a tiny value."""
@@ -97,17 +97,7 @@
# so we have to make a different function for each one. These
# functions are chained to each other: each calls the previous one.
def cleanup_dict():
- minimum = min(warmstate.increment_threshold,
- warmstate.increment_function_threshold)
- current = self.get_current_generation_uint()
- killme = []
- for key, cell in jitcell_dict.iteritems():
- if cell.counter >= 0:
- cell.adjust_counter(current, warmstate.log_decay_factor)
- if cell.counter < minimum:
- killme.append(key)
- for key in killme:
- del jitcell_dict[key]
+ callback()
cleanup_previous()
#
cleanup_previous = self._cleanup_jitcell_dicts
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
@@ -490,9 +490,38 @@
self.warmrunnerdesc.stats.jitcell_dicts.append(jitcell_dict)
except AttributeError:
pass
- memmgr = self.warmrunnerdesc.memory_manager
+ #
+ memmgr = self.warmrunnerdesc and self.warmrunnerdesc.memory_manager
if memmgr:
- memmgr.record_jitcell_dict(self, jitcell_dict)
+ def _cleanup_dict():
+ minimum = min(self.increment_threshold,
+ 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)
+ 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
+ memmgr.record_jitcell_dict(_cleanup_dict)
+ else:
+ def _maybe_cleanup_dict():
+ pass
#
def get_jitcell(build, *greenargs):
try:
@@ -500,6 +529,7 @@
except KeyError:
if not build:
return None
+ _maybe_cleanup_dict()
cell = self._new_jitcell()
jitcell_dict[greenargs] = cell
return cell
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit