[pypy-commit] pypy refactor-signature: merged default in

alex_gaynor noreply at buildbot.pypy.org
Tue Dec 20 22:18:17 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: refactor-signature
Changeset: r50777:f5fa3640940a
Date: 2011-12-20 14:22 -0600
http://bitbucket.org/pypy/pypy/changeset/f5fa3640940a/

Log:	merged default in

diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -425,7 +425,15 @@
                 self.arg_classes.count('L')) == len(args_f or ())
 
     def repr_of_descr(self):
-        return '<CallDescr(%s,%s)>' % (self.arg_classes, self.result_type)
+        res = 'Call%s %d' % (self.result_type, self.result_size)
+        if self.arg_classes:
+            res += ' ' + self.arg_classes
+        if self.extrainfo:
+            res += ' EF=%d' % self.extrainfo.extraeffect
+            oopspecindex = self.extrainfo.oopspecindex
+            if oopspecindex:
+                res += ' OS=%d' % oopspecindex
+        return '<%s>' % res
 
 
 def map_type_to_argclass(ARG, accept_void=False):
diff --git a/pypy/jit/backend/llsupport/test/test_descr.py b/pypy/jit/backend/llsupport/test/test_descr.py
--- a/pypy/jit/backend/llsupport/test/test_descr.py
+++ b/pypy/jit/backend/llsupport/test/test_descr.py
@@ -313,6 +313,10 @@
 
 
 def test_repr_of_descr():
+    def repr_of_descr(descr):
+        s = descr.repr_of_descr()
+        assert ',' not in s  # makes the life easier for pypy.tool.jitlogparser
+        return s
     c0 = GcCache(False)
     T = lltype.GcStruct('T')
     S = lltype.GcStruct('S', ('x', lltype.Char),
@@ -320,34 +324,34 @@
                              ('z', lltype.Ptr(T)))
     descr1 = get_size_descr(c0, S)
     s = symbolic.get_size(S, False)
-    assert descr1.repr_of_descr() == '<SizeDescr %d>' % s
+    assert repr_of_descr(descr1) == '<SizeDescr %d>' % s
     #
     descr2 = get_field_descr(c0, S, 'y')
     o, _ = symbolic.get_field_token(S, 'y', False)
-    assert descr2.repr_of_descr() == '<FieldP S.y %d>' % o
+    assert repr_of_descr(descr2) == '<FieldP S.y %d>' % o
     #
     descr2i = get_field_descr(c0, S, 'x')
     o, _ = symbolic.get_field_token(S, 'x', False)
-    assert descr2i.repr_of_descr() == '<FieldU S.x %d>' % o
+    assert repr_of_descr(descr2i) == '<FieldU S.x %d>' % o
     #
     descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
     o = symbolic.get_size(lltype.Ptr(S), False)
-    assert descr3.repr_of_descr() == '<ArrayP %d>' % o
+    assert repr_of_descr(descr3) == '<ArrayP %d>' % o
     #
     descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char))
-    assert descr3i.repr_of_descr() == '<ArrayU 1>'
+    assert repr_of_descr(descr3i) == '<ArrayU 1>'
     #
     descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S))
-    assert descr4.repr_of_descr() == '<CallDescr(ir,r)>'
+    assert repr_of_descr(descr4) == '<Callr %d ir>' % o
     #
     descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char)
-    assert descr4i.repr_of_descr() == '<CallDescr(ir,i)>'
+    assert repr_of_descr(descr4i) == '<Calli 1 ir>'
     #
     descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float)
-    assert descr4f.repr_of_descr() == '<CallDescr(ir,f)>'
+    assert repr_of_descr(descr4f) == '<Callf 8 ir>'
     #
     descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat)
-    assert descr5f.repr_of_descr() == '<CallDescr(i,S)>'
+    assert repr_of_descr(descr5f) == '<CallS 4 i>'
 
 def test_call_stubs_1():
     c0 = GcCache(False)
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
@@ -1,5 +1,5 @@
 import math
-from pypy.rlib.rarithmetic import r_int64, r_uint
+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
 
@@ -21,7 +21,6 @@
 #
 
 class MemoryManager(object):
-    NO_NEXT_CHECK = r_int64(2 ** 63 - 1)
 
     def __init__(self):
         self.check_frequency = -1
@@ -37,13 +36,12 @@
         # According to my estimates it's about 5e9 years given 1000 loops
         # per second
         self.current_generation = r_int64(1)
-        self.next_check = self.NO_NEXT_CHECK
+        self.next_check = r_int64(-1)
         self.alive_loops = {}
-        self._cleanup_jitcell_dicts = lambda: None
 
     def set_max_age(self, max_age, check_frequency=0):
         if max_age <= 0:
-            self.next_check = self.NO_NEXT_CHECK
+            self.next_check = r_int64(-1)
         else:
             self.max_age = max_age
             if check_frequency <= 0:
@@ -51,11 +49,10 @@
             self.check_frequency = check_frequency
             self.next_check = self.current_generation + 1
 
-    def next_generation(self, do_cleanups_now=True):
+    def next_generation(self):
         self.current_generation += 1
-        if do_cleanups_now and self.current_generation >= self.next_check:
+        if self.current_generation == self.next_check:
             self._kill_old_loops_now()
-            self._cleanup_jitcell_dicts()
             self.next_check = self.current_generation + self.check_frequency
 
     def keep_loop_alive(self, looptoken):
@@ -84,22 +81,3 @@
             # a single one is not enough for all tests :-(
             rgc.collect(); rgc.collect(); rgc.collect()
         debug_stop("jit-mem-collect")
-
-    def get_current_generation_uint(self):
-        """Return the current generation, possibly truncated to a uint.
-        To use only as an approximation for decaying counters."""
-        return r_uint(self.current_generation)
-
-    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."""
-        # note that the various jitcell_dicts have different RPython types,
-        # 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():
-            callback()
-            cleanup_previous()
-        #
-        cleanup_previous = self._cleanup_jitcell_dicts
-        self._cleanup_jitcell_dicts = cleanup_dict
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
@@ -1,3 +1,4 @@
+from __future__ import with_statement
 from pypy.jit.metainterp.optimizeopt.test.test_util import (
     LLtypeMixin, BaseTest, Storage, _sortboxes, FakeDescrWithSnapshot)
 from pypy.jit.metainterp.history import TreeLoop, JitCellToken, TargetToken
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2910,27 +2910,6 @@
         res = self.meta_interp(f, [32])
         assert res == f(32)
 
-    def test_decay_counters(self):
-        myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
-        def f(m, n):
-            while n > 0:
-                myjitdriver.jit_merge_point(m=m, n=n)
-                n += m
-                n -= m
-                n -= 1
-        def main():
-            f(5, 7)      # run 7x with m=5           counter[m=5] = 7
-            f(15, 10)    # compiles one loop         counter[m=5] = 3  (automatic decay)
-            f(5, 5)      # run 5x times with m=5     counter[m=5] = 8
-        #
-        self.meta_interp(main, [], decay_halflife=1,
-                         function_threshold=0, threshold=9, trace_eagerness=99)
-        self.check_trace_count(1)
-        #
-        self.meta_interp(main, [], decay_halflife=1,
-                         function_threshold=0, threshold=8, trace_eagerness=99)
-        self.check_trace_count(2)
-
 
 class TestOOtype(BasicTests, OOJitMixin):
 
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
@@ -1,4 +1,3 @@
-import math
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi
 from pypy.rpython.ootypesystem import ootype
@@ -9,7 +8,7 @@
 from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr
 from pypy.jit.metainterp.history import ConstInt, ConstFloat, ConstPtr
 from pypy.jit.codewriter import longlong
-from pypy.rlib.rarithmetic import r_singlefloat, r_uint
+from pypy.rlib.rarithmetic import r_singlefloat
 
 def boxfloat(x):
     return BoxFloat(longlong.getfloatstorage(x))
@@ -277,76 +276,51 @@
     res = state.can_never_inline(5, 42.5)
     assert res is True
 
-def test_decay_counters():
-    cell = JitCell(r_uint(5))
-    cell.counter = 100
-    cell.adjust_counter(r_uint(5), math.log(0.9))
-    assert cell.counter == 100
-    cell.adjust_counter(r_uint(6), math.log(0.9))
-    assert cell.counter == 90
-    cell.adjust_counter(r_uint(9), math.log(0.9))
-    assert cell.counter == int(90 * (0.9**3))
-
 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/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -64,11 +64,9 @@
 
 def jittify_and_run(interp, graph, args, repeat=1, graph_and_interp_only=False,
                     backendopt=False, trace_limit=sys.maxint,
-                    threshold=3, trace_eagerness=2,
                     inline=False, loop_longevity=0, retrace_limit=5,
-                    function_threshold=4, decay_halflife=0,
-                    enable_opts=ALL_OPTS_NAMES, max_retrace_guards=15,
-                    **kwds):
+                    function_threshold=4,
+                    enable_opts=ALL_OPTS_NAMES, max_retrace_guards=15, **kwds):
     from pypy.config.config import ConfigError
     translator = interp.typer.annotator.translator
     try:
@@ -85,16 +83,15 @@
         pass
     warmrunnerdesc = WarmRunnerDesc(translator, backendopt=backendopt, **kwds)
     for jd in warmrunnerdesc.jitdrivers_sd:
-        jd.warmstate.set_param_threshold(threshold)
+        jd.warmstate.set_param_threshold(3)          # for tests
         jd.warmstate.set_param_function_threshold(function_threshold)
-        jd.warmstate.set_param_trace_eagerness(trace_eagerness)
+        jd.warmstate.set_param_trace_eagerness(2)    # for tests
         jd.warmstate.set_param_trace_limit(trace_limit)
         jd.warmstate.set_param_inlining(inline)
         jd.warmstate.set_param_loop_longevity(loop_longevity)
         jd.warmstate.set_param_retrace_limit(retrace_limit)
         jd.warmstate.set_param_max_retrace_guards(max_retrace_guards)
         jd.warmstate.set_param_enable_opts(enable_opts)
-        jd.warmstate.set_param_decay_halflife(decay_halflife)
     warmrunnerdesc.finish()
     if graph_and_interp_only:
         return interp, graph
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
@@ -1,10 +1,10 @@
-import sys, weakref, math
+import sys, weakref
 from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.annlowlevel import hlstr, cast_base_ptr_to_instance
 from pypy.rpython.annlowlevel import cast_object_to_ptr
 from pypy.rlib.objectmodel import specialize, we_are_translated, r_dict
-from pypy.rlib.rarithmetic import intmask, r_uint
+from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.nonconst import NonConstant
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.jit import PARAMETERS
@@ -151,27 +151,9 @@
     #     counter == -2: tracing is currently going on for this cell
     counter = 0
     dont_trace_here = False
+    extra_delay = chr(0)
     wref_procedure_token = None
 
-    def __init__(self, generation):
-        # The stored 'counter' value follows an exponential decay model.
-        # Conceptually after every generation, it decays by getting
-        # multiplied by a constant <= 1.0.  In practice, decaying occurs
-        # lazily: the following field records the latest seen generation
-        # number, and adjustment is done by adjust_counter() when needed.
-        self.latest_generation_seen = generation
-
-    def adjust_counter(self, generation, log_decay_factor):
-        if generation != self.latest_generation_seen:
-            # The latest_generation_seen is older than the current generation.
-            # Adjust by multiplying self.counter N times by decay_factor, i.e.
-            # by decay_factor ** N, which is equal to exp(log(decay_factor)*N).
-            assert self.counter >= 0
-            N = generation - self.latest_generation_seen
-            factor = math.exp(log_decay_factor * N)
-            self.counter = int(self.counter * factor)
-            self.latest_generation_seen = generation
-
     def get_procedure_token(self):
         if self.wref_procedure_token is not None:
             token = self.wref_procedure_token()
@@ -231,17 +213,6 @@
     def set_param_inlining(self, value):
         self.inlining = value
 
-    def set_param_decay_halflife(self, value):
-        # Use 0 or -1 to mean "no decay".  Initialize the internal variable
-        # 'log_decay_factor'.  It is choosen such that by multiplying the
-        # counter on loops by 'exp(log_decay_factor)' (<= 1.0) every
-        # generation, then the counter will be divided by two after 'value'
-        # generations have passed.
-        if value <= 0:
-            self.log_decay_factor = 0.0    # log(1.0)
-        else:
-            self.log_decay_factor = math.log(0.5) / value
-
     def set_param_enable_opts(self, value):
         from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT, ALL_OPTS_NAMES
 
@@ -311,11 +282,6 @@
         confirm_enter_jit = self.confirm_enter_jit
         range_red_args = unrolling_iterable(
             range(num_green_args, num_green_args + jitdriver_sd.num_red_args))
-        memmgr = self.warmrunnerdesc.memory_manager
-        if memmgr is not None:
-            get_current_generation = memmgr.get_current_generation_uint
-        else:
-            get_current_generation = lambda: r_uint(0)
         # get a new specialized copy of the method
         ARGS = []
         for kind in jitdriver_sd.red_args_types:
@@ -350,6 +316,36 @@
             #
             assert 0, "should have raised"
 
+        def bound_reached(cell, *args):
+            # bound reached, but we do a last check: if it is the first
+            # time we reach the bound, or if another loop or bridge was
+            # compiled since the last time we reached it, then decrease
+            # the counter by a few percents instead.  It should avoid
+            # sudden bursts of JIT-compilation, and also corner cases
+            # where we suddenly compile more than one loop because all
+            # counters reach the bound at the same time, but where
+            # compiling all but the first one is pointless.
+            curgen = warmrunnerdesc.memory_manager.current_generation
+            curgen = chr(intmask(curgen) & 0xFF)    # only use 8 bits
+            if we_are_translated() and curgen != cell.extra_delay:
+                cell.counter = int(self.THRESHOLD_LIMIT * 0.98)
+                cell.extra_delay = curgen
+                return
+            #
+            if not confirm_enter_jit(*args):
+                cell.counter = 0
+                return
+            # start tracing
+            from pypy.jit.metainterp.pyjitpl import MetaInterp
+            metainterp = MetaInterp(metainterp_sd, jitdriver_sd)
+            # set counter to -2, to mean "tracing in effect"
+            cell.counter = -2
+            try:
+                metainterp.compile_and_run_once(jitdriver_sd, *args)
+            finally:
+                if cell.counter == -2:
+                    cell.counter = 0
+
         def maybe_compile_and_run(threshold, *args):
             """Entry point to the JIT.  Called at the point with the
             can_enter_jit() hint.
@@ -360,25 +356,13 @@
 
             if cell.counter >= 0:
                 # update the profiling counter
-                cell.adjust_counter(get_current_generation(),
-                                    self.log_decay_factor)
                 n = cell.counter + threshold
                 if n <= self.THRESHOLD_LIMIT:       # bound not reached
                     cell.counter = n
                     return
-                if not confirm_enter_jit(*args):
-                    cell.counter = 0
+                else:
+                    bound_reached(cell, *args)
                     return
-                # bound reached; start tracing
-                from pypy.jit.metainterp.pyjitpl import MetaInterp
-                metainterp = MetaInterp(metainterp_sd, jitdriver_sd)
-                # set counter to -2, to mean "tracing in effect"
-                cell.counter = -2
-                try:
-                    metainterp.compile_and_run_once(jitdriver_sd, *args)
-                finally:
-                    if cell.counter == -2:
-                        cell.counter = 0
             else:
                 if cell.counter != -1:
                     assert cell.counter == -2
@@ -454,15 +438,6 @@
         #
         return jit_getter
 
-    def _new_jitcell(self):
-        warmrunnerdesc = self.warmrunnerdesc
-        if (warmrunnerdesc is not None and
-                warmrunnerdesc.memory_manager is not None):
-            gen = warmrunnerdesc.memory_manager.get_current_generation_uint()
-        else:
-            gen = r_uint(0)
-        return JitCell(gen)
-
     def _make_jitcell_getter_default(self):
         "NOT_RPYTHON"
         jitdriver_sd = self.jitdriver_sd
@@ -492,44 +467,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:
@@ -538,7 +501,7 @@
                 if not build:
                     return None
                 _maybe_cleanup_dict()
-                cell = self._new_jitcell()
+                cell = JitCell()
                 jitcell_dict[greenargs] = cell
             return cell
         return get_jitcell
@@ -549,7 +512,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.
@@ -574,7 +537,7 @@
             if not build:
                 return cell
             if cell is None:
-                cell = self._new_jitcell()
+                cell = JitCell()
                 # <hacks>
                 if we_are_translated():
                     cellref = cast_object_to_ptr(BASEJITCELL, cell)
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -311,7 +311,7 @@
         # to repeat it every time
         ticker_check = """
             guard_not_invalidated?
-            ticker0 = getfield_raw(ticker_address, descr=<SignedFieldDescr pypysig_long_struct.c_value .*>)
+            ticker0 = getfield_raw(ticker_address, descr=<FieldS pypysig_long_struct.c_value .*>)
             ticker_cond0 = int_lt(ticker0, 0)
             guard_false(ticker_cond0, descr=...)
         """
@@ -320,9 +320,9 @@
         # this is the ticker check generated if we have threads
         thread_ticker_check = """
             guard_not_invalidated?
-            ticker0 = getfield_raw(ticker_address, descr=<SignedFieldDescr pypysig_long_struct.c_value .*>)
+            ticker0 = getfield_raw(ticker_address, descr=<FieldS pypysig_long_struct.c_value .*>)
             ticker1 = int_sub(ticker0, _)
-            setfield_raw(ticker_address, ticker1, descr=<SignedFieldDescr pypysig_long_struct.c_value .*>)
+            setfield_raw(ticker_address, ticker1, descr=<FieldS pypysig_long_struct.c_value .*>)
             ticker_cond0 = int_lt(ticker1, 0)
             guard_false(ticker_cond0, descr=...)
         """
@@ -330,7 +330,7 @@
         #
         # this is the ticker check generated in PyFrame.handle_operation_error
         exc_ticker_check = """
-            ticker2 = getfield_raw(ticker_address, descr=<SignedFieldDescr pypysig_long_struct.c_value .*>)
+            ticker2 = getfield_raw(ticker_address, descr=<FieldS pypysig_long_struct.c_value .*>)
             ticker_cond1 = int_lt(ticker2, 0)
             guard_false(ticker_cond1, descr=...)
         """
@@ -451,7 +451,6 @@
         try:
             self.match_loop(expected_ops, ignore_ops)
         except InvalidMatch, e:
-            #raise # uncomment this and use py.test --pdb for better debugging
             print '@' * 40
             print "Loops don't match"
             print "================="
@@ -464,7 +463,7 @@
             print
             print "Expected:"
             print format(expected_src)
-            return False
+            raise     # always propagate the exception in case of mismatch
         else:
             return True
 
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -7,8 +7,9 @@
 from pypy.tool.udir import udir
 from pypy.tool import logparser
 from pypy.jit.tool.jitoutput import parse_prof
-from pypy.module.pypyjit.test_pypy_c.model import Log, find_ids_range, find_ids, \
-    TraceWithIds, OpMatcher
+from pypy.module.pypyjit.test_pypy_c.model import (Log, find_ids_range,
+                                                   find_ids, TraceWithIds,
+                                                   OpMatcher, InvalidMatch)
 
 class BaseTestPyPyC(object):
     def setup_class(cls):
@@ -115,13 +116,18 @@
         assert opcodes_names == ['LOAD_FAST', 'LOAD_CONST', 'BINARY_ADD', 'STORE_FAST']
 
 
-class TestOpMatcher(object):
+class TestOpMatcher_(object):
 
     def match(self, src1, src2, **kwds):
         from pypy.tool.jitlogparser.parser import SimpleParser
         loop = SimpleParser.parse_from_input(src1)
         matcher = OpMatcher(loop.operations)
-        return matcher.match(src2, **kwds)
+        try:
+            res = matcher.match(src2, **kwds)
+            assert res is True
+            return True
+        except InvalidMatch:
+            return False
 
     def test_match_var(self):
         match_var = OpMatcher([]).match_var
@@ -447,7 +453,7 @@
             jump(p0, p1, p2, p3, i8, descr=...)
         """)
         #
-        assert not loop.match("""
+        py.test.raises(InvalidMatch, loop.match, """
             i6 = int_lt(i4, 1003)
             guard_true(i6)
             i8 = int_add(i5, 1) # variable mismatch
@@ -492,9 +498,8 @@
             guard_no_exception(descr=...)
         """)
         #
-        assert not loop.match_by_id('ntohs', """
+        py.test.raises(InvalidMatch, loop.match_by_id, 'ntohs', """
             guard_not_invalidated(descr=...)
             p12 = call(ConstClass(foobar), 1, descr=...)
             guard_no_exception(descr=...)
         """)
-        
diff --git a/pypy/module/pypyjit/test_pypy_c/test__ffi.py b/pypy/module/pypyjit/test_pypy_c/test__ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test__ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test__ffi.py
@@ -35,7 +35,7 @@
             guard_not_invalidated(descr=...)
             i17 = force_token()
             setfield_gc(p0, i17, descr=<.* .*PyFrame.vable_token .*>)
-            f21 = call_release_gil(%s, 2.000000, 3.000000, descr=<FloatCallDescr>)
+            f21 = call_release_gil(%s, 2.000000, 3.000000, descr=<Callf 8 ff EF=6>)
             guard_not_forced(descr=...)
             guard_no_exception(descr=...)
         """ % pow_addr)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_array.py b/pypy/module/pypyjit/test_pypy_c/test_array.py
--- a/pypy/module/pypyjit/test_pypy_c/test_array.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_array.py
@@ -42,7 +42,7 @@
             guard_not_invalidated(descr=...)
             i13 = int_lt(i7, i9)
             guard_true(i13, descr=...)
-            i15 = getarrayitem_raw(i10, i7, descr=<.*ArrayNoLengthDescr>)
+            i15 = getarrayitem_raw(i10, i7, descr=<ArrayS .>)
             i16 = int_add_ovf(i8, i15)
             guard_no_overflow(descr=...)
             i18 = int_add(i7, 1)
@@ -72,17 +72,17 @@
             guard_true(i13, descr=...)
             guard_not_invalidated(descr=...)
         # the bound check guard on img has been killed (thanks to the asserts)
-            i14 = getarrayitem_raw(i10, i8, descr=<.*ArrayNoLengthDescr>)
+            i14 = getarrayitem_raw(i10, i8, descr=<ArrayS .>)
             i15 = int_add_ovf(i9, i14)
             guard_no_overflow(descr=...)
             i17 = int_sub(i8, 640)
         # the bound check guard on intimg has been killed (thanks to the asserts)
-            i18 = getarrayitem_raw(i11, i17, descr=<.*ArrayNoLengthDescr>)
+            i18 = getarrayitem_raw(i11, i17, descr=<ArrayS .>)
             i19 = int_add_ovf(i18, i15)
             guard_no_overflow(descr=...)
         # on 64bit, there is a guard checking that i19 actually fits into 32bit
             ...
-            setarrayitem_raw(i11, i8, _, descr=<.*ArrayNoLengthDescr>)
+            setarrayitem_raw(i11, i8, _, descr=<ArrayS .>)
             i28 = int_add(i8, 1)
             --TICK--
             jump(p0, p1, p2, p3, p4, p5, p6, i28, i15, p9, i10, i11, descr=...)
@@ -107,10 +107,10 @@
             guard_true(i10, descr=...)
             i11 = int_lt(i6, i7)
             guard_true(i11, descr=...)
-            f13 = getarrayitem_raw(i8, i6, descr=<FloatArrayNoLengthDescr>)
+            f13 = getarrayitem_raw(i8, i6, descr=<ArrayF 8>)
             f15 = float_add(f13, 20.500000)
-            setarrayitem_raw(i8, i6, f15, descr=<FloatArrayNoLengthDescr>)
-            f16 = getarrayitem_raw(i8, i6, descr=<FloatArrayNoLengthDescr>)
+            setarrayitem_raw(i8, i6, f15, descr=<ArrayF 8>)
+            f16 = getarrayitem_raw(i8, i6, descr=<ArrayF 8>)
             i18 = float_eq(f16, 42.000000)
             guard_true(i18, descr=...)
             i20 = int_add(i6, 1)
@@ -132,28 +132,24 @@
         log = self.run(main, [])
         assert log.result == 321
         loop, = log.loops_by_filename(self.filepath)
-        if sys.maxint == 2147483647:
-            arraydescr = 'UnsignedArrayNoLengthDescr'
-        else:
-            arraydescr = 'UINTArrayNoLengthDescr'
         assert loop.match("""
             i10 = int_lt(i6, 1000)
             guard_true(i10, descr=...)
             i11 = int_lt(i6, i7)
             guard_true(i11, descr=...)
-            i13 = getarrayitem_raw(i8, i6, descr=<%s>)
+            i13 = getarrayitem_raw(i8, i6, descr=<Array. 4>)
             f14 = cast_singlefloat_to_float(i13)
             f16 = float_add(f14, 20.500000)
             i17 = cast_float_to_singlefloat(f16)
-            setarrayitem_raw(i8, i6,i17, descr=<%s>)
-            i18 = getarrayitem_raw(i8, i6, descr=<%s>)
+            setarrayitem_raw(i8, i6,i17, descr=<Array. 4>)
+            i18 = getarrayitem_raw(i8, i6, descr=<Array. 4>)
             f19 = cast_singlefloat_to_float(i18)
             i21 = float_eq(f19, 42.000000)
             guard_true(i21, descr=...)
             i23 = int_add(i6, 1)
             --TICK--
             jump(..., descr=...)
-        """ % (arraydescr, arraydescr, arraydescr))
+        """)
 
 
     def test_zeropadded(self):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -75,12 +75,12 @@
         assert log.opnames(ops) == []
         #
         assert entry_bridge.match_by_id('call', """
-            p38 = call(ConstClass(getexecutioncontext), descr=<GcPtrCallDescr>)
-            p39 = getfield_gc(p38, descr=<GcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
+            p38 = call(ConstClass(getexecutioncontext), descr=<Callr . EF=1>)
+            p39 = getfield_gc(p38, descr=<FieldP pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
             i40 = force_token()
-            p41 = getfield_gc(p38, descr=<GcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
+            p41 = getfield_gc(p38, descr=<FieldP pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
             guard_isnull(p41, descr=...)
-            i42 = getfield_gc(p38, descr=<NonGcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
+            i42 = getfield_gc(p38, descr=<FieldU pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
             i43 = int_is_zero(i42)
             guard_true(i43, descr=...)
             i50 = force_token()
@@ -192,7 +192,7 @@
         assert log.result == 1000
         loop, = log.loops_by_id('call')
         assert loop.match_by_id('call', """
-            p14 = getarrayitem_gc_pure(p8, i9, descr=<GcPtrArrayDescr>)
+            p14 = getarrayitem_gc_pure(p8, i9, descr=<ArrayP .>)
             i14 = force_token()
             i16 = force_token()
         """)
@@ -336,15 +336,15 @@
         loop, = log.loops_by_filename(self.filepath)
         # the int strategy is used here
         assert loop.match_by_id('append', """
-            i13 = getfield_gc(p8, descr=<SignedFieldDescr list.length .*>)
+            i13 = getfield_gc(p8, descr=<FieldS list.length .*>)
             i15 = int_add(i13, 1)
             # Will be killed by the backend
-            p15 = getfield_gc(p8, descr=<GcPtrFieldDescr list.items .*>)
-            i17 = arraylen_gc(p15, descr=<SignedArrayDescr>)
-            call(_, p8, i15, descr=<VoidCallDescr>) # this is a call to _ll_list_resize_ge_trampoline__...
+            p15 = getfield_gc(p8, descr=<FieldP list.items .*>)
+            i17 = arraylen_gc(p15, descr=<ArrayS .>)
+            call(_, p8, i15, descr=<Callv 0 ri EF=4>) # this is a call to _ll_list_resize_ge_trampoline__...
             guard_no_exception(descr=...)
-            p17 = getfield_gc(p8, descr=<GcPtrFieldDescr list.items .*>)
-            setarrayitem_gc(p17, i13, i12, descr=<SignedArrayDescr>)
+            p17 = getfield_gc(p8, descr=<FieldP list.items .*>)
+            setarrayitem_gc(p17, i13, i12, descr=<ArrayS .>)
         """)
 
     def test_blockstack_virtualizable(self):
@@ -368,13 +368,13 @@
             ...
             i20 = force_token()
             p22 = new_with_vtable(19511408)
-            p24 = new_array(1, descr=<GcPtrArrayDescr>)
+            p24 = new_array(1, descr=<ArrayP .>)
             p26 = new_with_vtable(ConstClass(W_ListObject))
-            setfield_gc(p0, i20, descr=<SignedFieldDescr .*PyFrame.vable_token .*>)
-            setfield_gc(p26, ConstPtr(ptr22), descr=<GcPtrFieldDescr pypy.objspace.std.listobject.W_ListObject.inst_strategy .*>)
-            setarrayitem_gc(p24, 0, p26, descr=<GcPtrArrayDescr>)
-            setfield_gc(p22, p24, descr=<GcPtrFieldDescr .*Arguments.inst_arguments_w .*>)
-            p32 = call_may_force(11376960, p18, p22, descr=<GcPtrCallDescr>)
+            setfield_gc(p0, i20, descr=<FieldS .*PyFrame.vable_token .*>)
+            setfield_gc(p26, ConstPtr(ptr22), descr=<FieldP pypy.objspace.std.listobject.W_ListObject.inst_strategy .*>)
+            setarrayitem_gc(p24, 0, p26, descr=<ArrayP .>)
+            setfield_gc(p22, p24, descr=<FieldP .*Arguments.inst_arguments_w .*>)
+            p32 = call_may_force(11376960, p18, p22, descr=<Callr . rr EF=6>)
             ...
         """)
 
@@ -415,26 +415,26 @@
             guard_nonnull_class(p8, ConstClass(W_IntObject), descr=...)
             guard_value(i4, 0, descr=...)
             guard_value(p3, ConstPtr(ptr14), descr=...)
-            i15 = getfield_gc_pure(p8, descr=<SignedFieldDescr pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
+            i15 = getfield_gc_pure(p8, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
             i17 = int_lt(i15, 5000)
             guard_true(i17, descr=...)
-            p18 = getfield_gc(p0, descr=<GcPtrFieldDescr pypy.interpreter.eval.Frame.inst_w_globals .*>)
+            p18 = getfield_gc(p0, descr=<FieldP pypy.interpreter.eval.Frame.inst_w_globals .*>)
             guard_value(p18, ConstPtr(ptr19), descr=...)
-            p20 = getfield_gc(p18, descr=<GcPtrFieldDescr pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy .*>)
+            p20 = getfield_gc(p18, descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy .*>)
             guard_value(p20, ConstPtr(ptr21), descr=...)
             guard_not_invalidated(descr=...)
             # most importantly, there is no getarrayitem_gc here
-            p23 = call(ConstClass(getexecutioncontext), descr=<GcPtrCallDescr>)
-            p24 = getfield_gc(p23, descr=<GcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
+            p23 = call(ConstClass(getexecutioncontext), descr=<Callr . EF=1>)
+            p24 = getfield_gc(p23, descr=<FieldP pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
             i25 = force_token()
-            p26 = getfield_gc(p23, descr=<GcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
+            p26 = getfield_gc(p23, descr=<FieldP pypy.interpreter.executioncontext.ExecutionContext.inst_w_tracefunc .*>)
             guard_isnull(p26, descr=...)
-            i27 = getfield_gc(p23, descr=<NonGcPtrFieldDescr pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
+            i27 = getfield_gc(p23, descr=<FieldU pypy.interpreter.executioncontext.ExecutionContext.inst_profilefunc .*>)
             i28 = int_is_zero(i27)
             guard_true(i28, descr=...)
-            p30 = getfield_gc(ConstPtr(ptr29), descr=<GcPtrFieldDescr pypy.interpreter.nestedscope.Cell.inst_w_value .*>)
+            p30 = getfield_gc(ConstPtr(ptr29), descr=<FieldP pypy.interpreter.nestedscope.Cell.inst_w_value .*>)
             guard_nonnull_class(p30, ConstClass(W_IntObject), descr=...)
-            i32 = getfield_gc_pure(p30, descr=<SignedFieldDescr pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
+            i32 = getfield_gc_pure(p30, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
             i33 = int_add_ovf(i15, i32)
             guard_no_overflow(descr=...)
             --TICK--
@@ -452,15 +452,15 @@
             """, [])
         loop, = log.loops_by_id('call')
         assert loop.match("""
-            i8 = getfield_gc_pure(p6, descr=<SignedFieldDescr pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
+            i8 = getfield_gc_pure(p6, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
             i10 = int_lt(i8, 5000)
             guard_true(i10, descr=...)
             i11 = force_token()
             i13 = int_add(i8, 1)
             --TICK--
             p22 = new_with_vtable(ConstClass(W_IntObject))
-            setfield_gc(p22, i13, descr=<SignedFieldDescr pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
-            setfield_gc(p4, p22, descr=<GcPtrFieldDescr pypy.interpreter.nestedscope.Cell.inst_w_value .*>)
+            setfield_gc(p22, i13, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
+            setfield_gc(p4, p22, descr=<FieldP pypy.interpreter.nestedscope.Cell.inst_w_value .*>)
             jump(p0, p1, p2, p3, p4, p7, p22, p7, descr=...)
         """)
 
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -46,7 +46,7 @@
         assert loop.match_by_id("getitem", """
             i26 = call(ConstClass(ll_dict_lookup), p18, p6, i25, descr=...)
             ...
-            p33 = getinteriorfield_gc(p31, i26, descr=<InteriorFieldDescr <GcPtrFieldDescr dictentry.value .*>>)
+            p33 = getinteriorfield_gc(p31, i26, descr=<InteriorFieldDescr <FieldP dictentry.value .*>>)
             ...
         """)
 
@@ -86,28 +86,28 @@
             i8 = int_lt(i5, i7)
             guard_true(i8, descr=...)
             guard_not_invalidated(descr=...)
-            p10 = call(ConstClass(ll_int_str), i5, descr=<GcPtrCallDescr>)
+            p10 = call(ConstClass(ll_int_str), i5, descr=<Callr . i EF=3>)
             guard_no_exception(descr=...)
-            i12 = call(ConstClass(ll_strhash), p10, descr=<SignedCallDescr>)
+            i12 = call(ConstClass(ll_strhash), p10, descr=<Calli . r EF=0>)
             p13 = new(descr=...)
-            p15 = new_array(8, descr=<dictentryArrayDescr>)
-            setfield_gc(p13, p15, descr=<GcPtrFieldDescr dicttable.entries .*>)
-            i17 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, descr=<SignedCallDescr>)
-            setfield_gc(p13, 16, descr=<SignedFieldDescr dicttable.resize_counter .*>)
+            p15 = new_array(8, descr=<ArrayX .*>)
+            setfield_gc(p13, p15, descr=<FieldP dicttable.entries .*>)
+            i17 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, descr=<Calli . rri EF=4>)
+            setfield_gc(p13, 16, descr=<FieldS dicttable.resize_counter .*>)
             guard_no_exception(descr=...)
             p20 = new_with_vtable(ConstClass(W_IntObject))
-            call(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13, p10, p20, i12, i17, descr=<VoidCallDescr>)
-            setfield_gc(p20, i5, descr=<SignedFieldDescr .*W_IntObject.inst_intval .*>)
+            call(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13, p10, p20, i12, i17, descr=<Callv 0 rrrii EF=4>)
+            setfield_gc(p20, i5, descr=<FieldS .*W_IntObject.inst_intval .*>)
             guard_no_exception(descr=...)
-            i23 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, descr=<SignedCallDescr>)
+            i23 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, descr=<Calli . rri EF=4>)
             guard_no_exception(descr=...)
             i26 = int_and(i23, .*)
             i27 = int_is_true(i26)
             guard_false(i27, descr=...)
-            p28 = getfield_gc(p13, descr=<GcPtrFieldDescr dicttable.entries .*>)
-            p29 = getinteriorfield_gc(p28, i23, descr=<InteriorFieldDescr <GcPtrFieldDescr dictentry.value .*>>)
+            p28 = getfield_gc(p13, descr=<FieldP dicttable.entries .*>)
+            p29 = getinteriorfield_gc(p28, i23, descr=<InteriorFieldDescr <FieldP dictentry.value .*>>)
             guard_nonnull_class(p29, ConstClass(W_IntObject), descr=...)
-            i31 = getfield_gc_pure(p29, descr=<SignedFieldDescr .*W_IntObject.inst_intval .*>)
+            i31 = getfield_gc_pure(p29, descr=<FieldS .*W_IntObject.inst_intval .*>)
             i32 = int_sub_ovf(i31, i5)
             guard_no_overflow(descr=...)
             i34 = int_add_ovf(i32, 1)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_generators.py b/pypy/module/pypyjit/test_pypy_c/test_generators.py
--- a/pypy/module/pypyjit/test_pypy_c/test_generators.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_generators.py
@@ -21,9 +21,9 @@
         assert loop.match_by_id("generator", """
             i16 = force_token()
             p45 = new_with_vtable(ConstClass(W_IntObject))
-            setfield_gc(p45, i29, descr=<SignedFieldDescr .*>)
-            setarrayitem_gc(p8, 0, p45, descr=<GcPtrArrayDescr>)
-            i47 = arraylen_gc(p8, descr=<GcPtrArrayDescr>) # Should be removed by backend
+            setfield_gc(p45, i29, descr=<FieldS .*>)
+            setarrayitem_gc(p8, 0, p45, descr=<ArrayP .>)
+            i47 = arraylen_gc(p8, descr=<ArrayP .>) # Should be removed by backend
             jump(..., descr=...)
             """)
         assert loop.match_by_id("subtract", """
diff --git a/pypy/module/pypyjit/test_pypy_c/test_globals.py b/pypy/module/pypyjit/test_pypy_c/test_globals.py
--- a/pypy/module/pypyjit/test_pypy_c/test_globals.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_globals.py
@@ -16,11 +16,11 @@
         assert log.result == 500
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match_by_id("loadglobal", """
-            p10 = getfield_gc(p0, descr=<GcPtrFieldDescr .*Frame.inst_w_globals .*>)
+            p10 = getfield_gc(p0, descr=<FieldP .*Frame.inst_w_globals .*>)
             guard_value(p10, ConstPtr(ptr11), descr=...)
-            p12 = getfield_gc(p10, descr=<GcPtrFieldDescr .*W_DictMultiObject.inst_strategy .*>)
+            p12 = getfield_gc(p10, descr=<FieldP .*W_DictMultiObject.inst_strategy .*>)
             guard_value(p12, ConstPtr(ptr13), descr=...)
             guard_not_invalidated(descr=...)
-            p19 = getfield_gc(ConstPtr(p17), descr=<GcPtrFieldDescr .*W_DictMultiObject.inst_strategy .*>)
+            p19 = getfield_gc(ConstPtr(p17), descr=<FieldP .*W_DictMultiObject.inst_strategy .*>)
             guard_value(p19, ConstPtr(ptr20), descr=...)
-        """)
\ No newline at end of file
+        """)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -125,8 +125,8 @@
             i12 = force_token()
             --TICK--
             p20 = new_with_vtable(ConstClass(W_IntObject))
-            setfield_gc(p20, i11, descr=<SignedFieldDescr.*W_IntObject.inst_intval .*>)
-            setfield_gc(ConstPtr(ptr21), p20, descr=<GcPtrFieldDescr .*TypeCell.inst_w_value .*>)
+            setfield_gc(p20, i11, descr=<FieldS.*W_IntObject.inst_intval .*>)
+            setfield_gc(ConstPtr(ptr21), p20, descr=<FieldP .*TypeCell.inst_w_value .*>)
             jump(p0, p1, p2, p3, p4, p20, p6, i7, p20, descr=...)
         """)
 
diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py b/pypy/module/pypyjit/test_pypy_c/test_math.py
--- a/pypy/module/pypyjit/test_pypy_c/test_math.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_math.py
@@ -23,8 +23,8 @@
             f1 = cast_int_to_float(i0)
             i3 = float_le(f1, 0)
             guard_false(i3, descr=...)
-            f2 = call(ConstClass(log), f1, descr=<FloatCallDescr>)
-            f3 = call(ConstClass(log10), f1, descr=<FloatCallDescr>)
+            f2 = call(ConstClass(log), f1, descr=<Callf . f EF=2>)
+            f3 = call(ConstClass(log10), f1, descr=<Callf . f EF=2>)
             f4 = float_sub(f2, f3)
             f5 = float_add(f0, f4)
             i4 = int_add(i0, 1)
@@ -52,8 +52,8 @@
             f1 = cast_int_to_float(i0)
             i6 = --ISINF--(f1)
             guard_false(i6, descr=...)
-            f2 = call(ConstClass(sin), f1, descr=<FloatCallDescr>)
-            f3 = call(ConstClass(cos), f1, descr=<FloatCallDescr>)
+            f2 = call(ConstClass(sin), f1, descr=<Callf . f EF=2>)
+            f3 = call(ConstClass(cos), f1, descr=<Callf . f EF=2>)
             f4 = float_sub(f2, f3)
             f5 = float_add(f0, f4)
             i7 = int_add(i0, f1)
@@ -84,7 +84,7 @@
             i4 = int_or(i2, i3)
             i5 = int_is_true(i4)
             guard_false(i5, descr=...)
-            f2 = call(ConstClass(fmod), f1, 2.0, descr=<FloatCallDescr>)
+            f2 = call(ConstClass(fmod), f1, 2.0, descr=<Callf . ff EF=2>)
             f3 = float_add(f0, f2)
             i6 = int_sub(i0, 1)
             --TICK--
diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py
--- a/pypy/module/pypyjit/test_pypy_c/test_misc.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py
@@ -46,7 +46,7 @@
                 r *= n
                 n -= 1
             return r
-        log = self.run(fact, [7], threshold=5)
+        log = self.run(fact, [7], threshold=4)
         assert log.result == 5040
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match("""
@@ -204,18 +204,18 @@
         assert log.result == 1000000
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match("""
-            i14 = getfield_gc(p12, descr=<SignedFieldDescr list.length .*>)
+            i14 = getfield_gc(p12, descr=<FieldS list.length .*>)
             i16 = uint_ge(i12, i14)
             guard_false(i16, descr=...)
-            p16 = getfield_gc(p12, descr=<GcPtrFieldDescr list.items .*>)
-            p17 = getarrayitem_gc(p16, i12, descr=<GcPtrArrayDescr>)
+            p16 = getfield_gc(p12, descr=<FieldP list.items .*>)
+            p17 = getarrayitem_gc(p16, i12, descr=<ArrayP .>)
             i19 = int_add(i12, 1)
-            setfield_gc(p9, i19, descr=<SignedFieldDescr .*W_AbstractSeqIterObject.inst_index .*>)
+            setfield_gc(p9, i19, descr=<FieldS .*W_AbstractSeqIterObject.inst_index .*>)
             guard_nonnull_class(p17, 146982464, descr=...)
-            i21 = getfield_gc(p17, descr=<SignedFieldDescr .*W_ArrayTypei.inst_len .*>)
+            i21 = getfield_gc(p17, descr=<FieldS .*W_ArrayTypei.inst_len .*>)
             i23 = int_lt(0, i21)
             guard_true(i23, descr=...)
-            i24 = getfield_gc(p17, descr=<NonGcPtrFieldDescr .*W_ArrayTypei.inst_buffer .*>)
+            i24 = getfield_gc(p17, descr=<FieldU .*W_ArrayTypei.inst_buffer .*>)
             i25 = getarrayitem_raw(i24, 0, descr=<.*>)
             i27 = int_lt(1, i21)
             guard_false(i27, descr=...)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py
--- a/pypy/module/pypyjit/test_pypy_c/test_string.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_string.py
@@ -1,6 +1,9 @@
 from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
 
 
+# XXX review the <Call> descrs to replace some EF=4 with EF=3 (elidable)
+
+
 class TestString(BaseTestPyPyC):
     def test_lookup_default_encoding(self):
         def main(n):
@@ -52,8 +55,8 @@
                 i += int(long(string.digits[i % len(string.digits)], 16))
             return i
 
-        log = self.run(main, [1000])
-        assert log.result == main(1000)
+        log = self.run(main, [1100])
+        assert log.result == main(1100)
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match("""
             i11 = int_lt(i6, i7)
@@ -72,7 +75,7 @@
             i23 = strgetitem(p10, i19)
             p25 = newstr(1)
             strsetitem(p25, 0, i23)
-            p28 = call(ConstClass(strip_spaces), p25, descr=<GcPtrCallDescr>)
+            p28 = call(ConstClass(strip_spaces), p25, descr=<Callr . r EF=4>)
             guard_no_exception(descr=...)
             i29 = strlen(p28)
             i30 = int_is_true(i29)
@@ -88,9 +91,9 @@
             guard_false(i41, descr=...)
             i43 = int_eq(i39, 43)
             guard_false(i43, descr=...)
-            i43 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr42), descr=<BoolCallDescr>)
+            i43 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr42), descr=<Calli 1 rr EF=0>)
             guard_false(i43, descr=...)
-            i46 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr45), descr=<BoolCallDescr>)
+            i46 = call(ConstClass(ll_startswith__rpy_stringPtr_rpy_stringPtr), p28, ConstPtr(ptr45), descr=<Calli 1 rr EF=0>)
             guard_false(i46, descr=...)
             p51 = new_with_vtable(21136408)
             setfield_gc(p51, _, descr=...)    # 7 setfields, but the order is dict-order-dependent
@@ -100,9 +103,9 @@
             setfield_gc(p51, _, descr=...)
             setfield_gc(p51, _, descr=...)
             setfield_gc(p51, _, descr=...)
-            p55 = call(ConstClass(parse_digit_string), p51, descr=<GcPtrCallDescr>)
+            p55 = call(ConstClass(parse_digit_string), p51, descr=<Callr . r EF=4>)
             guard_no_exception(descr=...)
-            i57 = call(ConstClass(rbigint.toint), p55, descr=<SignedCallDescr>)
+            i57 = call(ConstClass(rbigint.toint), p55, descr=<Calli . r EF=3>)
             guard_no_exception(descr=...)
             i58 = int_add_ovf(i6, i57)
             guard_no_overflow(descr=...)
@@ -125,7 +128,7 @@
             i7 = int_gt(i4, 0)
             guard_true(i7, descr=...)
             guard_not_invalidated(descr=...)
-            p9 = call(ConstClass(ll_int2dec__Signed), i4, descr=<GcPtrCallDescr>)
+            p9 = call(ConstClass(ll_int2dec__Signed), i4, descr=<Callr . i EF=3>)
             guard_no_exception(descr=...)
             i10 = strlen(p9)
             i11 = int_is_true(i10)
@@ -149,7 +152,7 @@
             copystrcontent(p9, p21, 0, i25, i10)
             i33 = int_lt(i30, 23)
             guard_true(i33, descr=...)
-            p35 = call(ConstClass(ll_shrink_array__rpy_stringPtr_Signed), p21, i30, descr=<GcPtrCallDescr>)
+            p35 = call(ConstClass(ll_shrink_array__rpy_stringPtr_Signed), p21, i30, descr=<Callr . ri EF=4>)
             guard_no_exception(descr=...)
             i37 = strlen(p35)
             i38 = int_add_ovf(i5, i37)
@@ -192,6 +195,6 @@
             strsetitem(p35, 3, 104)
             strsetitem(p35, 4, 95)
             copystrcontent(p31, p35, 0, 5, i32)
-            i49 = call(ConstClass(_ll_2_str_eq_nonnull__rpy_stringPtr_rpy_stringPtr), p35, ConstPtr(ptr48), descr=<SignedCallDescr>)
-            guard_value(i49, 1, descr=<Guard8>)
+            i49 = call(ConstClass(_ll_2_str_eq_nonnull__rpy_stringPtr_rpy_stringPtr), p35, ConstPtr(ptr48), descr=<Calli [48] rr EF=0 OS=28>)
+            guard_value(i49, 1, descr=...)
             ''')
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -395,7 +395,6 @@
               'retrace_limit': 5,
               'max_retrace_guards': 15,
               'enable_opts': 'all',
-              'decay_halflife': 40,
               }
 unroll_parameters = unrolling_iterable(PARAMETERS.items())
 DEFAULT = object()


More information about the pypy-commit mailing list