Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit