[pypy-commit] pypy stmgc-c7: Trying to remove the conflicts on 'alive_loops'.
arigo
noreply at buildbot.pypy.org
Wed Jan 28 16:13:27 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r75562:b42c25c45a1c
Date: 2015-01-28 16:13 +0100
http://bitbucket.org/pypy/pypy/changeset/b42c25c45a1c/
Log: Trying to remove the conflicts on 'alive_loops'.
diff --git a/rpython/jit/metainterp/memmgr.py b/rpython/jit/metainterp/memmgr.py
--- a/rpython/jit/metainterp/memmgr.py
+++ b/rpython/jit/metainterp/memmgr.py
@@ -1,7 +1,10 @@
import math
from rpython.rlib.rarithmetic import r_int64
from rpython.rlib.debug import debug_start, debug_print, debug_stop
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, stm_ignored
+from rpython.rlib.rgc import stm_is_enabled
+from rpython.rtyper import annlowlevel
+from rpython.rlib import rstm
#
# Logic to decide which loops are old and not used any more.
@@ -37,7 +40,13 @@
# per second
self.current_generation = r_int64(1)
self.next_check = r_int64(-1)
- self.alive_loops = {}
+ if not stm_is_enabled():
+ self.alive_loops = {}
+ else:
+ # hash table mapping integers to looptokens
+ self.stm_alive_loops = rstm.ll_hashtable_create()
+ # lowest integer key used in stm_alive_loops
+ self.stm_lowest_key = 0
def set_max_age(self, max_age, check_frequency=0):
if max_age <= 0:
@@ -57,21 +66,61 @@
def keep_loop_alive(self, looptoken):
if looptoken.generation != self.current_generation:
- looptoken.generation = self.current_generation
- self.alive_loops[looptoken] = None
+ # STM: never produce conflicts from this function.
+ with stm_ignored:
+ looptoken.generation = self.current_generation
+ if not stm_is_enabled():
+ self.alive_loops[looptoken] = None
+ else:
+ next_key = rstm.stm_count()
+ gcref = annlowlevel.cast_instance_to_gcref(looptoken)
+ rstm.ll_hashtable_set(self.stm_alive_loops, next_key, gcref)
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)
+ max_generation = self.current_generation - (self.max_age-1)
+ #
+ if not stm_is_enabled():
+ oldtotal = len(self.alive_loops)
+ for looptoken in self.alive_loops.keys():
+ if not self._must_keep_loop(looptoken, max_generation):
+ del self.alive_loops[looptoken]
+ newtotal = len(self.alive_loops)
+ else:
+ # this logic assumes that we are more or less the only running
+ # thread. Even if there are possible corner cases, they should
+ # not have worse results than a possibly early or late freeing
+ # of one loop, and only in corner cases.
+ from rpython.jit.metainterp.history import JitCellToken
+ stm_alive_loops = self.stm_alive_loops
+ keep_loops = set()
+ #
+ # all keys in 'stm_alive_loops' should be in the following range
+ old_count = self.stm_lowest_key
+ new_count = rstm.stm_count()
+ for key in range(old_count, new_count):
+ gcref = rstm.ll_hashtable_get(stm_alive_loops, key)
+ if not gcref:
+ continue
+ # make 'stm_alive_loops' empty, and add the loops that we
+ # must keep in the set 'keep_loops'
+ rstm.ll_hashtable_set(stm_alive_loops, key, rstm.NULL_GCREF)
+ looptoken = annlowlevel.cast_gcref_to_instance(JitCellToken,
+ gcref)
+ if self._must_keep_loop(looptoken):
+ keep_loops.add(looptoken)
+ newtotal = len(keep_loops)
+ #
+ # now re-add loops with key numbers that *end* at 'new_count'
+ for looptoken in keep_loops:
+ gcref = annlowlevel.cast_instance_to_gcref(looptoken)
+ rstm.ll_hashtable_set(stm_alive_loops, new_count, gcref)
+ new_count -= 1
+ self.stm_lowest_key = new_count + 1 # lowest used key number
+ #
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 or
- looptoken.invalidated):
- 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()
@@ -81,3 +130,7 @@
# a single one is not enough for all tests :-(
rgc.collect(); rgc.collect(); rgc.collect()
debug_stop("jit-mem-collect")
+
+ def _must_keep_loop(self, looptoken, max_generation):
+ return not (0 <= looptoken.generation < max_generation or
+ looptoken.invalidated)
More information about the pypy-commit
mailing list