[pypy-commit] pypy int-tag-untag-as-operations: merge default

cfbolz noreply at buildbot.pypy.org
Wed Nov 30 15:29:25 CET 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: int-tag-untag-as-operations
Changeset: r50013:2c073a10379f
Date: 2011-11-30 15:29 +0100
http://bitbucket.org/pypy/pypy/changeset/2c073a10379f/

Log:	merge default

diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -252,7 +252,26 @@
     # unsignedness is considered a rare and contagious disease
 
     def union((int1, int2)):
-        knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+        if int1.unsigned == int2.unsigned:
+            knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+        else:
+            t1 = int1.knowntype
+            if t1 is bool:
+                t1 = int
+            t2 = int2.knowntype
+            if t2 is bool:
+                t2 = int
+
+            if t2 is int:
+                if int2.nonneg == False:
+                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t1
+                knowntype = t1
+            elif t1 is int:
+                if int1.nonneg == False:
+                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t2
+                knowntype = t2
+            else:
+                raise UnionError, "Merging these types (%s, %s) is not supported" % (t1, t2)
         return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
                            knowntype=knowntype)
 
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -591,13 +591,11 @@
     immutable = True
     def __init__(self, method):
         self.method = method
-        
-NUMBER = object()
+
 annotation_to_ll_map = [
     (SomeSingleFloat(), lltype.SingleFloat),
     (s_None, lltype.Void),   # also matches SomeImpossibleValue()
     (s_Bool, lltype.Bool),
-    (SomeInteger(knowntype=r_ulonglong), NUMBER),    
     (SomeFloat(), lltype.Float),
     (SomeLongFloat(), lltype.LongFloat),
     (SomeChar(), lltype.Char),
@@ -623,10 +621,11 @@
             return lltype.Ptr(p.PARENTTYPE)
     if isinstance(s_val, SomePtr):
         return s_val.ll_ptrtype
+    if type(s_val) is SomeInteger:
+        return lltype.build_number(None, s_val.knowntype)
+
     for witness, T in annotation_to_ll_map:
         if witness.contains(s_val):
-            if T is NUMBER:
-                return lltype.build_number(None, s_val.knowntype)
             return T
     if info is None:
         info = ''
@@ -635,7 +634,7 @@
     raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
         info, s_val))
 
-ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map if ll is not NUMBER])
+ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
 
 def lltype_to_annotation(T):
     try:
diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py
--- a/pypy/annotation/specialize.py
+++ b/pypy/annotation/specialize.py
@@ -36,9 +36,7 @@
             newtup = SpaceOperation('newtuple', starargs, argscopy[-1])
             newstartblock.operations.append(newtup)
             newstartblock.closeblock(Link(argscopy, graph.startblock))
-            graph.startblock.isstartblock = False
             graph.startblock = newstartblock
-            newstartblock.isstartblock = True
             argnames = argnames + ['.star%d' % i for i in range(nb_extra_args)]
             graph.signature = Signature(argnames)
             # note that we can mostly ignore defaults: if nb_extra_args > 0, 
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -856,6 +856,46 @@
         py.test.raises(Exception, a.build_types, f, [])
         # if you want to get a r_uint, you have to be explicit about it
 
+    def test_add_different_ints(self):
+        def f(a, b):
+            return a + b
+        a = self.RPythonAnnotator()
+        py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+    def test_merge_different_ints(self):
+        def f(a, b):
+            if a:
+                c = a
+            else:
+                c = b
+            return c
+        a = self.RPythonAnnotator()
+        py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+    def test_merge_ruint_zero(self):
+        def f(a):
+            if a:
+                c = a
+            else:
+                c = 0
+            return c
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [r_uint])
+        assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+    def test_merge_ruint_nonneg_signed(self):
+        def f(a, b):
+            if a:
+                c = a
+            else:
+                assert b >= 0
+                c = b
+            return c
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [r_uint, int])
+        assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+
     def test_prebuilt_long_that_is_not_too_long(self):
         small_constant = 12L
         def f():
@@ -3029,7 +3069,7 @@
             if g(x, y):
                 g(x, r_uint(y))
         a = self.RPythonAnnotator()
-        a.build_types(f, [int, int])
+        py.test.raises(Exception, a.build_types, f, [int, int])
 
     def test_compare_with_zero(self):
         def g():
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -69,8 +69,8 @@
                      "statistics": [("translation.gctransformer", "framework")],
                      "generation": [("translation.gctransformer", "framework")],
                      "hybrid": [("translation.gctransformer", "framework")],
-                     "boehm": [("translation.gctransformer", "boehm"),
-                               ("translation.continuation", False)],  # breaks
+                     "boehm": [("translation.continuation", False),  # breaks
+                               ("translation.gctransformer", "boehm")],
                      "markcompact": [("translation.gctransformer", "framework")],
                      "minimark": [("translation.gctransformer", "framework")],
                      },
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -304,5 +304,14 @@
   never a dictionary as it sometimes is in CPython. Assigning to
   ``__builtins__`` has no effect.
 
+* directly calling the internal magic methods of a few built-in types
+  with invalid arguments may have a slightly different result.  For
+  example, ``[].__add__(None)`` and ``(2).__add__(None)`` both return
+  ``NotImplemented`` on PyPy; on CPython, only the later does, and the
+  former raises ``TypeError``.  (Of course, ``[]+None`` and ``2+None``
+  both raise ``TypeError`` everywhere.)  This difference is an
+  implementation detail that shows up because of internal C-level slots
+  that PyPy does not have.
+
 
 .. include:: _ref.txt
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -191,7 +191,7 @@
     def is_w(self, space, w_other):
         return self is w_other
 
-    def id(self, space):
+    def unique_id(self, space):
         return space.wrap(compute_unique_id(self))
 
     def str_w(self, space):
@@ -697,7 +697,7 @@
         return w_two.is_w(self, w_one)
 
     def id(self, w_obj):
-        return w_obj.id(self)
+        return w_obj.unique_id(self)
 
     def hash_w(self, w_obj):
         """shortcut for space.int_w(space.hash(w_obj))"""
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -10,7 +10,7 @@
 from pypy.rlib.objectmodel import we_are_translated, instantiate
 from pypy.rlib.jit import hint
 from pypy.rlib.debug import make_sure_not_resized, check_nonneg
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, r_uint
 from pypy.rlib import jit
 from pypy.tool import stdlib_opcode
 from pypy.tool.stdlib_opcode import host_bytecode_spec
@@ -167,7 +167,7 @@
                 # Execution starts just after the last_instr.  Initially,
                 # last_instr is -1.  After a generator suspends it points to
                 # the YIELD_VALUE instruction.
-                next_instr = self.last_instr + 1
+                next_instr = r_uint(self.last_instr + 1)
                 if next_instr != 0:
                     self.pushvalue(w_inputvalue)
             #
@@ -691,6 +691,7 @@
     handlerposition = space.int_w(w_handlerposition)
     valuestackdepth = space.int_w(w_valuestackdepth)
     assert valuestackdepth >= 0
+    assert handlerposition >= 0
     blk = instantiate(get_block_class(opname))
     blk.handlerposition = handlerposition
     blk.valuestackdepth = valuestackdepth
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -837,6 +837,7 @@
         raise Yield
 
     def jump_absolute(self, jumpto, next_instr, ec):
+        check_nonneg(jumpto)
         return jumpto
 
     def JUMP_FORWARD(self, jumpby, next_instr):
@@ -1278,7 +1279,7 @@
 
     def handle(self, frame, unroller):
         next_instr = self.really_handle(frame, unroller)   # JIT hack
-        return next_instr
+        return r_uint(next_instr)
 
     def really_handle(self, frame, unroller):
         """ Purely abstract method
diff --git a/pypy/jit/backend/llsupport/asmmemmgr.py b/pypy/jit/backend/llsupport/asmmemmgr.py
--- a/pypy/jit/backend/llsupport/asmmemmgr.py
+++ b/pypy/jit/backend/llsupport/asmmemmgr.py
@@ -37,25 +37,25 @@
             self._add_free_block(smaller_stop, stop)
             stop = smaller_stop
             result = (start, stop)
-        self.total_mallocs += stop - start
+        self.total_mallocs += r_uint(stop - start)
         return result   # pair (start, stop)
 
     def free(self, start, stop):
         """Free a block (start, stop) returned by a previous malloc()."""
-        self.total_mallocs -= (stop - start)
+        self.total_mallocs -= r_uint(stop - start)
         self._add_free_block(start, stop)
 
     def open_malloc(self, minsize):
         """Allocate at least minsize bytes.  Returns (start, stop)."""
         result = self._allocate_block(minsize)
         (start, stop) = result
-        self.total_mallocs += stop - start
+        self.total_mallocs += r_uint(stop - start)
         return result
 
     def open_free(self, middle, stop):
         """Used for freeing the end of an open-allocated block of memory."""
         if stop - middle >= self.min_fragment:
-            self.total_mallocs -= (stop - middle)
+            self.total_mallocs -= r_uint(stop - middle)
             self._add_free_block(middle, stop)
             return True
         else:
@@ -77,7 +77,7 @@
                 # Hack to make sure that mcs are not within 32-bits of one
                 # another for testing purposes
                 rmmap.hint.pos += 0x80000000 - size
-        self.total_memory_allocated += size
+        self.total_memory_allocated += r_uint(size)
         data = rffi.cast(lltype.Signed, data)
         return self._add_free_block(data, data + size)
 
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -648,14 +648,10 @@
         # make a malloc function, with two arguments
         def malloc_basic(size, tid):
             type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
-            has_finalizer = bool(tid & (1<<llgroup.HALFSHIFT))
-            has_light_finalizer = bool(tid & (1<<(llgroup.HALFSHIFT + 1)))
             check_typeid(type_id)
             res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
                                                   type_id, size,
-                                                  has_finalizer,
-                                                  has_light_finalizer,
-                                                  False)
+                                                  False, False, False)
             # In case the operation above failed, we are returning NULL
             # from this function to assembler.  There is also an RPython
             # exception set, typically MemoryError; but it's easier and
@@ -749,11 +745,8 @@
     def init_size_descr(self, S, descr):
         type_id = self.layoutbuilder.get_type_id(S)
         assert not self.layoutbuilder.is_weakref_type(S)
-        has_finalizer = bool(self.layoutbuilder.has_finalizer(S))
-        has_light_finalizer = bool(self.layoutbuilder.has_light_finalizer(S))
-        flags = (int(has_finalizer) << llgroup.HALFSHIFT |
-                 int(has_light_finalizer) << (llgroup.HALFSHIFT + 1))
-        descr.tid = llop.combine_ushort(lltype.Signed, type_id, flags)
+        assert not self.layoutbuilder.has_finalizer(S)
+        descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
 
     def init_array_descr(self, A, descr):
         type_id = self.layoutbuilder.get_type_id(A)
diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -241,12 +241,15 @@
         return op.opname == 'jit_force_quasi_immutable'
 
 class RandomEffectsAnalyzer(BoolGraphAnalyzer):
-    def analyze_direct_call(self, graph, seen=None):
-        if hasattr(graph, "func") and hasattr(graph.func, "_ptr"):
-            if graph.func._ptr._obj.random_effects_on_gcobjs:
+    def analyze_external_call(self, op, seen=None):
+        try:
+            funcobj = op.args[0].value._obj
+            if funcobj.random_effects_on_gcobjs:
                 return True
-        return super(RandomEffectsAnalyzer, self).analyze_direct_call(graph,
-                                                                      seen)
+        except (AttributeError, lltype.DelayedPointer):
+            pass
+        return super(RandomEffectsAnalyzer, self).analyze_external_call(
+            op, seen)
 
     def analyze_simple_operation(self, op, graphinfo):
         return False
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -1057,35 +1057,20 @@
     # jit.codewriter.support.
 
     for _op, _oopspec in [('llong_invert',  'INVERT'),
-                          ('ullong_invert', 'INVERT'),
                           ('llong_lt',      'LT'),
                           ('llong_le',      'LE'),
                           ('llong_eq',      'EQ'),
                           ('llong_ne',      'NE'),
                           ('llong_gt',      'GT'),
                           ('llong_ge',      'GE'),
-                          ('ullong_lt',     'ULT'),
-                          ('ullong_le',     'ULE'),
-                          ('ullong_eq',     'EQ'),
-                          ('ullong_ne',     'NE'),
-                          ('ullong_gt',     'UGT'),
-                          ('ullong_ge',     'UGE'),
                           ('llong_add',     'ADD'),
                           ('llong_sub',     'SUB'),
                           ('llong_mul',     'MUL'),
                           ('llong_and',     'AND'),
                           ('llong_or',      'OR'),
                           ('llong_xor',     'XOR'),
-                          ('ullong_add',    'ADD'),
-                          ('ullong_sub',    'SUB'),
-                          ('ullong_mul',    'MUL'),
-                          ('ullong_and',    'AND'),
-                          ('ullong_or',     'OR'),
-                          ('ullong_xor',    'XOR'),
                           ('llong_lshift',  'LSHIFT'),
                           ('llong_rshift',  'RSHIFT'),
-                          ('ullong_lshift', 'LSHIFT'),
-                          ('ullong_rshift', 'URSHIFT'),
                           ('cast_int_to_longlong',     'FROM_INT'),
                           ('truncate_longlong_to_int', 'TO_INT'),
                           ('cast_float_to_longlong',   'FROM_FLOAT'),
@@ -1108,6 +1093,21 @@
                           ('cast_uint_to_ulonglong',    'FROM_UINT'),
                           ('cast_float_to_ulonglong',   'FROM_FLOAT'),
                           ('cast_ulonglong_to_float',   'U_TO_FLOAT'),
+                          ('ullong_invert', 'INVERT'),
+                          ('ullong_lt',     'ULT'),
+                          ('ullong_le',     'ULE'),
+                          ('ullong_eq',     'EQ'),
+                          ('ullong_ne',     'NE'),
+                          ('ullong_gt',     'UGT'),
+                          ('ullong_ge',     'UGE'),
+                          ('ullong_add',    'ADD'),
+                          ('ullong_sub',    'SUB'),
+                          ('ullong_mul',    'MUL'),
+                          ('ullong_and',    'AND'),
+                          ('ullong_or',     'OR'),
+                          ('ullong_xor',    'XOR'),
+                          ('ullong_lshift', 'LSHIFT'),
+                          ('ullong_rshift', 'URSHIFT'),
                          ]:
         exec py.code.Source('''
             def rewrite_op_%s(self, op):
@@ -1138,7 +1138,7 @@
 
     def rewrite_op_llong_is_true(self, op):
         v = varoftype(op.args[0].concretetype)
-        op0 = SpaceOperation('cast_int_to_longlong',
+        op0 = SpaceOperation('cast_primitive',
                              [Constant(0, lltype.Signed)],
                              v)
         args = [op.args[0], v]
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -258,6 +258,9 @@
     y = ~r_ulonglong(xll)
     return u_to_longlong(y)
 
+def _ll_1_ullong_invert(xull):
+    return ~xull
+
 def _ll_2_llong_lt(xll, yll):
     return xll < yll
 
@@ -276,16 +279,22 @@
 def _ll_2_llong_ge(xll, yll):
     return xll >= yll
 
-def _ll_2_llong_ult(xull, yull):
+def _ll_2_ullong_eq(xull, yull):
+    return xull == yull
+
+def _ll_2_ullong_ne(xull, yull):
+    return xull != yull
+
+def _ll_2_ullong_ult(xull, yull):
     return xull < yull
 
-def _ll_2_llong_ule(xull, yull):
+def _ll_2_ullong_ule(xull, yull):
     return xull <= yull
 
-def _ll_2_llong_ugt(xull, yull):
+def _ll_2_ullong_ugt(xull, yull):
     return xull > yull
 
-def _ll_2_llong_uge(xull, yull):
+def _ll_2_ullong_uge(xull, yull):
     return xull >= yull
 
 def _ll_2_llong_add(xll, yll):
@@ -312,14 +321,41 @@
     z = r_ulonglong(xll) ^ r_ulonglong(yll)
     return u_to_longlong(z)
 
+def _ll_2_ullong_add(xull, yull):
+    z = (xull) + (yull)
+    return (z)
+
+def _ll_2_ullong_sub(xull, yull):
+    z = (xull) - (yull)
+    return (z)
+
+def _ll_2_ullong_mul(xull, yull):
+    z = (xull) * (yull)
+    return (z)
+
+def _ll_2_ullong_and(xull, yull):
+    z = (xull) & (yull)
+    return (z)
+
+def _ll_2_ullong_or(xull, yull):
+    z = (xull) | (yull)
+    return (z)
+
+def _ll_2_ullong_xor(xull, yull):
+    z = (xull) ^ (yull)
+    return (z)
+
 def _ll_2_llong_lshift(xll, y):
     z = r_ulonglong(xll) << y
     return u_to_longlong(z)
 
+def _ll_2_ullong_lshift(xull, y):
+    return xull << y
+
 def _ll_2_llong_rshift(xll, y):
     return xll >> y
 
-def _ll_2_llong_urshift(xull, y):
+def _ll_2_ullong_urshift(xull, y):
     return xull >> y
 
 def _ll_1_llong_from_int(x):
diff --git a/pypy/jit/codewriter/test/test_call.py b/pypy/jit/codewriter/test/test_call.py
--- a/pypy/jit/codewriter/test/test_call.py
+++ b/pypy/jit/codewriter/test/test_call.py
@@ -192,3 +192,21 @@
     [op] = block.operations
     call_descr = cc.getcalldescr(op)
     assert call_descr.extrainfo.has_random_effects()
+
+def test_random_effects_on_stacklet_switch():
+    from pypy.jit.backend.llgraph.runner import LLtypeCPU
+    from pypy.rlib._rffi_stacklet import switch, thread_handle, handle
+    @jit.dont_look_inside
+    def f():
+        switch(rffi.cast(thread_handle, 0), rffi.cast(handle, 0))
+
+    rtyper = support.annotate(f, [])
+    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
+    cc = CallControl(LLtypeCPU(rtyper), jitdrivers_sd=[jitdriver_sd])
+    res = cc.find_all_graphs(FakePolicy())
+
+    [f_graph] = [x for x in res if x.func is f]
+    [block, _] = list(f_graph.iterblocks())
+    op = block.operations[-1]
+    call_descr = cc.getcalldescr(op)
+    assert call_descr.extrainfo.has_random_effects()
diff --git a/pypy/jit/codewriter/test/test_longlong.py b/pypy/jit/codewriter/test/test_longlong.py
--- a/pypy/jit/codewriter/test/test_longlong.py
+++ b/pypy/jit/codewriter/test/test_longlong.py
@@ -78,7 +78,7 @@
             oplist = tr.rewrite_operation(op)
             assert len(oplist) == 2
             assert oplist[0].opname == 'residual_call_irf_f'
-            assert oplist[0].args[0].value == 'llong_from_int'
+            assert oplist[0].args[0].value == opname.split('_')[0]+'_from_int'
             assert oplist[0].args[1] == 'calldescr-84'
             assert list(oplist[0].args[2]) == [const(0)]
             assert list(oplist[0].args[3]) == []
diff --git a/pypy/jit/metainterp/gc.py b/pypy/jit/metainterp/gc.py
--- a/pypy/jit/metainterp/gc.py
+++ b/pypy/jit/metainterp/gc.py
@@ -7,6 +7,9 @@
         self.config = config
 
 
+class GC_none(GcDescription):
+    malloc_zero_filled = True
+
 class GC_boehm(GcDescription):
     malloc_zero_filled = True
 
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -999,13 +999,13 @@
                 "found %d %r, expected %d" % (found, insn, expected_count))
         return insns
 
-    def check_loops(self, expected=None, everywhere=False, **check):
+    def check_resops(self, expected=None, **check):
         insns = {}
         for loop in self.loops:
-            if not everywhere:
-                if getattr(loop, '_ignore_during_counting', False):
-                    continue
             insns = loop.summary(adding_insns=insns)
+        return self._check_insns(insns, expected, check)
+
+    def _check_insns(self, insns, expected, check):
         if expected is not None:
             insns.pop('debug_merge_point', None)
             assert insns == expected
@@ -1016,6 +1016,25 @@
                 "found %d %r, expected %d" % (found, insn, expected_count))
         return insns
 
+    def check_simple_loop(self, expected=None, **check):
+        # Usefull in the simplest case when we have only one trace ending with
+        # a jump back to itself and possibly a few bridges ending with finnish.
+        # Only the operations within the loop formed by that single jump will
+        # be counted.
+
+        # XXX hacked version, ignore and remove me when jit-targets is merged.
+        loops = self.get_all_loops()
+        loops = [loop for loop in loops if 'Preamble' not in repr(loop)] #XXX
+        assert len(loops) == 1
+        loop, = loops
+        jumpop = loop.operations[-1]
+        assert jumpop.getopnum() == rop.JUMP
+        insns = {}
+        for op in loop.operations:
+            opname = op.getopname()
+            insns[opname] = insns.get(opname, 0) + 1
+        return self._check_insns(insns, expected, check)
+        
     def check_consistency(self):
         "NOT_RPYTHON"
         for loop in self.loops:
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -7,7 +7,7 @@
 from pypy.rlib.libffi import Func
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import llmemory, rffi
 
 
 class FuncInfo(object):
@@ -237,7 +237,7 @@
         else:
             assert False, "unsupported ffitype or kind"
         #
-        fieldsize = ffitype.c_size
+        fieldsize = rffi.getintfield(ffitype, 'c_size')
         return self.optimizer.cpu.interiorfielddescrof_dynamic(
             offset, width, fieldsize, is_pointer, is_float, is_signed
         )
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -564,9 +564,12 @@
         descr = op.getdescr()
         assert isinstance(descr, compile.ResumeGuardDescr)
         modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
-        newboxes = modifier.finish(self.values, self.pendingfields)
-        if len(newboxes) > self.metainterp_sd.options.failargs_limit: # XXX be careful here
-            compile.giveup()
+        try:
+            newboxes = modifier.finish(self.values, self.pendingfields)
+            if len(newboxes) > self.metainterp_sd.options.failargs_limit:
+                raise resume.TagOverflow
+        except resume.TagOverflow:
+            raise compile.giveup()
         descr.store_final_boxes(op, newboxes)
         #
         if op.getopnum() == rop.GUARD_VALUE:
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -93,12 +93,14 @@
 
 TAGMASK = 3
 
+class TagOverflow(Exception):
+    pass
+
 def tag(value, tagbits):
-    if tagbits >> 2:
-        raise ValueError
+    assert 0 <= tagbits <= 3
     sx = value >> 13
     if sx != 0 and sx != -1:
-        raise ValueError
+        raise TagOverflow
     return rffi.r_short(value<<2|tagbits)
 
 def untag(value):
@@ -153,7 +155,7 @@
                 return self._newconst(const)
             try:
                 return tag(val, TAGINT)
-            except ValueError:
+            except TagOverflow:
                 pass
             tagged = self.large_ints.get(val, UNASSIGNED)
             if not tagged_eq(tagged, UNASSIGNED):
@@ -429,8 +431,7 @@
                 fieldnum = self._gettagged(fieldbox)
                 # the index is limited to 2147483647 (64-bit machines only)
                 if itemindex > 2147483647:
-                    from pypy.jit.metainterp import compile
-                    compile.giveup()
+                    raise TagOverflow
                 itemindex = rffi.cast(rffi.INT, itemindex)
                 #
                 rd_pendingfields[i].lldescr  = lldescr
diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py
--- a/pypy/jit/metainterp/test/support.py
+++ b/pypy/jit/metainterp/test/support.py
@@ -155,9 +155,11 @@
 
 class JitMixin:
     basic = True
-    def check_loops(self, expected=None, everywhere=False, **check):
-        get_stats().check_loops(expected=expected, everywhere=everywhere,
-                                **check)
+    def check_resops(self, expected=None, **check):
+        get_stats().check_resops(expected=expected, **check)
+    def check_simple_loop(self, expected=None, **check):
+        get_stats().check_simple_loop(expected=expected, **check)
+
     def check_loop_count(self, count):
         """NB. This is a hack; use check_tree_loop_count() or
         check_enter_count() for the real thing.
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
@@ -79,9 +79,8 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 42
         self.check_loop_count(1)
-        self.check_loops({'guard_true': 1,
-                          'int_add': 1, 'int_sub': 1, 'int_gt': 1,
-                          'jump': 1})
+        self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2, 'guard_true': 2, 'int_sub': 2})
+
         if self.basic:
             found = 0
             for op in get_stats().loops[0]._all_operations():
@@ -108,7 +107,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 1323
         self.check_loop_count(1)
-        self.check_loops(int_mul=1)
+        self.check_simple_loop(int_mul=1)
 
     def test_loop_variant_mul_ovf(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -125,7 +124,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 1323
         self.check_loop_count(1)
-        self.check_loops(int_mul_ovf=1)
+        self.check_simple_loop(int_mul_ovf=1)
 
     def test_loop_invariant_mul1(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -140,9 +139,10 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 252
         self.check_loop_count(1)
-        self.check_loops({'guard_true': 1,
-                          'int_add': 1, 'int_sub': 1, 'int_gt': 1,
-                          'jump': 1})
+        self.check_simple_loop(int_mul=0)
+        self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2,
+                           'int_mul': 1, 'guard_true': 2, 'int_sub': 2})
+
 
     def test_loop_invariant_mul_ovf(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -158,10 +158,11 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 308
         self.check_loop_count(1)
-        self.check_loops({'guard_true': 1,
-                          'int_add': 2, 'int_sub': 1, 'int_gt': 1,
-                          'int_lshift': 1,
-                          'jump': 1})
+        self.check_simple_loop(int_mul_ovf=0)
+        self.check_resops({'jump': 2, 'int_lshift': 2, 'int_gt': 2,
+                           'int_mul_ovf': 1, 'int_add': 4,
+                           'guard_true': 2, 'guard_no_overflow': 1,
+                           'int_sub': 2})
 
     def test_loop_invariant_mul_bridge1(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -194,11 +195,9 @@
         res = self.meta_interp(f, [6, 32])
         assert res == 1167
         self.check_loop_count(3)
-        self.check_loops({'int_add': 3, 'int_lt': 2,
-                          'int_sub': 2, 'guard_false': 1,
-                          'jump': 2,
-                          'int_gt': 1, 'guard_true': 2})
-
+        self.check_resops({'int_lt': 3, 'int_gt': 2, 'int_add': 5,
+                           'guard_true': 3, 'int_sub': 4, 'jump': 4,
+                           'int_mul': 2, 'guard_false': 2})
 
     def test_loop_invariant_mul_bridge_maintaining2(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -216,10 +215,9 @@
         res = self.meta_interp(f, [6, 32])
         assert res == 1692
         self.check_loop_count(3)
-        self.check_loops({'int_add': 3, 'int_lt': 2,
-                          'int_sub': 2, 'guard_false': 1,
-                          'jump': 2,
-                          'int_gt': 1, 'guard_true': 2})
+        self.check_resops({'int_lt': 3, 'int_gt': 2, 'int_add': 5,
+                           'guard_true': 3, 'int_sub': 4, 'jump': 4,
+                           'int_mul': 2, 'guard_false': 2})
 
     def test_loop_invariant_mul_bridge_maintaining3(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'm'])
@@ -237,10 +235,9 @@
         res = self.meta_interp(f, [6, 32, 16])
         assert res == 1692
         self.check_loop_count(3)
-        self.check_loops({'int_add': 2, 'int_lt': 1,
-                          'int_sub': 2, 'guard_false': 1,
-                          'jump': 2, 'int_mul': 1,
-                          'int_gt': 2, 'guard_true': 2})
+        self.check_resops({'int_lt': 2, 'int_gt': 4, 'guard_false': 2,
+                           'guard_true': 4, 'int_sub': 4, 'jump': 4,
+                           'int_mul': 3, 'int_add': 4})
 
     def test_loop_invariant_intbox(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
@@ -261,9 +258,9 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 252
         self.check_loop_count(1)
-        self.check_loops({'guard_true': 1,
-                          'int_add': 1, 'int_sub': 1, 'int_gt': 1,
-                          'jump': 1})
+        self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2,
+                           'getfield_gc_pure': 1, 'int_mul': 1,
+                           'guard_true': 2, 'int_sub': 2})
 
     def test_loops_are_transient(self):
         import gc, weakref
@@ -381,7 +378,7 @@
         assert res == 0
         # CALL_PURE is recorded in the history, but turned into a CALL
         # by optimizeopt.py
-        self.check_loops(int_sub=0, call=1, call_pure=0)
+        self.check_resops(call_pure=0, call=2, int_sub=0)
 
     def test_constfold_call_elidable(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
@@ -397,7 +394,7 @@
         res = self.meta_interp(f, [21, 5])
         assert res == -1
         # the CALL_PURE is constant-folded away by optimizeopt.py
-        self.check_loops(int_sub=1, call=0, call_pure=0)
+        self.check_resops(call_pure=0, call=0, int_sub=2)
 
     def test_constfold_call_elidable_2(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
@@ -417,7 +414,7 @@
         res = self.meta_interp(f, [21, 5])
         assert res == -1
         # the CALL_PURE is constant-folded away by optimizeopt.py
-        self.check_loops(int_sub=1, call=0, call_pure=0)
+        self.check_resops(call_pure=0, call=0, int_sub=2)
 
     def test_elidable_function_returning_object(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
@@ -442,7 +439,7 @@
         res = self.meta_interp(f, [21, 5])
         assert res == -1
         # the CALL_PURE is constant-folded away by optimizeopt.py
-        self.check_loops(int_sub=1, call=0, call_pure=0, getfield_gc=0)
+        self.check_resops(call_pure=0, call=0, getfield_gc=1, int_sub=2)
 
     def test_elidable_raising(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
@@ -463,12 +460,12 @@
         res = self.meta_interp(f, [22, 6])
         assert res == -3
         # the CALL_PURE is constant-folded away during tracing
-        self.check_loops(int_sub=1, call=0, call_pure=0)
+        self.check_resops(call_pure=0, call=0, int_sub=2)
         #
         res = self.meta_interp(f, [22, -5])
         assert res == 0
         # raises: becomes CALL and is not constant-folded away
-        self.check_loops(int_sub=1, call=1, call_pure=0)
+        self.check_resops(call_pure=0, call=2, int_sub=2)
 
     def test_elidable_raising_2(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
@@ -489,12 +486,12 @@
         res = self.meta_interp(f, [22, 6])
         assert res == -3
         # the CALL_PURE is constant-folded away by optimizeopt.py
-        self.check_loops(int_sub=1, call=0, call_pure=0)
+        self.check_resops(call_pure=0, call=0, int_sub=2)
         #
         res = self.meta_interp(f, [22, -5])
         assert res == 0
         # raises: becomes CALL and is not constant-folded away
-        self.check_loops(int_sub=1, call=1, call_pure=0)
+        self.check_resops(call_pure=0, call=2, int_sub=2)
 
     def test_constant_across_mp(self):
         myjitdriver = JitDriver(greens = [], reds = ['n'])
@@ -533,7 +530,7 @@
         policy = StopAtXPolicy(externfn)
         res = self.meta_interp(f, [31], policy=policy)
         assert res == 42
-        self.check_loops(int_mul=1, int_mod=0)
+        self.check_resops(int_mul=2, int_mod=0)
 
     def test_we_are_jitted(self):
         myjitdriver = JitDriver(greens = [], reds = ['y'])
@@ -835,7 +832,7 @@
             return n
         res = self.meta_interp(f, [20, 1, 2])
         assert res == 0
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_abs(self):
         myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
@@ -865,9 +862,8 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 42.0
         self.check_loop_count(1)
-        self.check_loops({'guard_true': 1,
-                          'float_add': 1, 'float_sub': 1, 'float_gt': 1,
-                          'jump': 1})
+        self.check_resops({'jump': 2, 'float_gt': 2, 'float_add': 2,
+                           'float_sub': 2, 'guard_true': 2})
 
     def test_print(self):
         myjitdriver = JitDriver(greens = [], reds = ['n'])
@@ -1038,7 +1034,7 @@
             return x
         res = self.meta_interp(f, [20], enable_opts='')
         assert res == f(20)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_zerodivisionerror(self):
         # test the case of exception-raising operation that is not delegated
@@ -1351,7 +1347,7 @@
         res = self.meta_interp(f, [6, 7])
         assert res == 42
         self.check_loop_count(1)
-        self.check_loops(call=1)
+        self.check_resops(call=2)
 
     def test_merge_guardclass_guardvalue(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1378,8 +1374,7 @@
             return x
         res = self.meta_interp(f, [299], listops=True)
         assert res == f(299)
-        self.check_loops(guard_class=0, guard_value=3)
-        self.check_loops(guard_class=0, guard_value=6, everywhere=True)
+        self.check_resops(guard_class=0, guard_value=6)
 
     def test_merge_guardnonnull_guardclass(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1407,11 +1402,9 @@
             return x
         res = self.meta_interp(f, [299], listops=True)
         assert res == f(299)
-        self.check_loops(guard_class=0, guard_nonnull=2,
-                         guard_nonnull_class=2, guard_isnull=1)
-        self.check_loops(guard_class=0, guard_nonnull=4,
-                         guard_nonnull_class=4, guard_isnull=2,
-                         everywhere=True)
+        self.check_resops(guard_class=0, guard_nonnull=4,
+                          guard_nonnull_class=4, guard_isnull=2)
+        
 
     def test_merge_guardnonnull_guardvalue(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1438,11 +1431,9 @@
             return x
         res = self.meta_interp(f, [299], listops=True)
         assert res == f(299)
-        self.check_loops(guard_class=0, guard_nonnull=2, guard_value=2,
-                         guard_nonnull_class=0, guard_isnull=1)
-        self.check_loops(guard_class=0, guard_nonnull=4, guard_value=4,
-                         guard_nonnull_class=0, guard_isnull=2,
-                         everywhere=True)
+        self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
+                          guard_nonnull_class=0, guard_isnull=2)
+        
 
     def test_merge_guardnonnull_guardvalue_2(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1469,11 +1460,9 @@
             return x
         res = self.meta_interp(f, [299], listops=True)
         assert res == f(299)
-        self.check_loops(guard_class=0, guard_nonnull=2, guard_value=2,
-                         guard_nonnull_class=0, guard_isnull=1)
-        self.check_loops(guard_class=0, guard_nonnull=4, guard_value=4,
-                         guard_nonnull_class=0, guard_isnull=2,
-                         everywhere=True)
+        self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
+                          guard_nonnull_class=0, guard_isnull=2)
+        
 
     def test_merge_guardnonnull_guardclass_guardvalue(self):
         from pypy.rlib.objectmodel import instantiate
@@ -1503,11 +1492,9 @@
             return x
         res = self.meta_interp(f, [399], listops=True)
         assert res == f(399)
-        self.check_loops(guard_class=0, guard_nonnull=3, guard_value=3,
-                         guard_nonnull_class=0, guard_isnull=1)
-        self.check_loops(guard_class=0, guard_nonnull=6, guard_value=6,
-                         guard_nonnull_class=0, guard_isnull=2,
-                         everywhere=True)
+        self.check_resops(guard_class=0, guard_nonnull=6, guard_value=6,
+                          guard_nonnull_class=0, guard_isnull=2)
+
 
     def test_residual_call_doesnt_lose_info(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'l'])
@@ -1533,8 +1520,7 @@
                 y.v = g(y.v) - y.v/y.v + lc/l[0] - 1
             return y.v
         res = self.meta_interp(f, [20], listops=True)
-        self.check_loops(getfield_gc=0, getarrayitem_gc=0)
-        self.check_loops(getfield_gc=1, getarrayitem_gc=0, everywhere=True)
+        self.check_resops(getarrayitem_gc=0, getfield_gc=1)
 
     def test_guard_isnull_nonnull(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
@@ -1562,7 +1548,7 @@
             return res
         res = self.meta_interp(f, [21])
         assert res == 42
-        self.check_loops(guard_nonnull=1, guard_isnull=1)
+        self.check_resops(guard_nonnull=2, guard_isnull=2)
 
     def test_loop_invariant1(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
@@ -1589,8 +1575,7 @@
             return res
         res = self.meta_interp(g, [21])
         assert res == 3 * 21
-        self.check_loops(call=0)
-        self.check_loops(call=1, everywhere=True)
+        self.check_resops(call=1)
 
     def test_bug_optimizeopt_mutates_ops(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'const', 'a'])
@@ -1710,7 +1695,7 @@
             return x
         res = self.meta_interp(f, [8])
         assert res == 0
-        self.check_loops(jit_debug=2)
+        self.check_resops(jit_debug=4)
 
     def test_assert_green(self):
         def f(x, promote_flag):
@@ -1752,9 +1737,10 @@
         res = self.meta_interp(g, [6, 7])
         assert res == 6*8 + 6**8
         self.check_loop_count(5)
-        self.check_loops({'guard_true': 2,
-                          'int_add': 1, 'int_mul': 1, 'int_sub': 2,
-                          'int_gt': 2, 'jump': 2})
+        self.check_resops({'guard_class': 2, 'int_gt': 4,
+                           'getfield_gc': 4, 'guard_true': 4,
+                           'int_sub': 4, 'jump': 4, 'int_mul': 2,
+                           'int_add': 2})
 
     def test_multiple_specialied_versions_array(self):
         myjitdriver = JitDriver(greens = [], reds = ['idx', 'y', 'x', 'res',
@@ -1795,7 +1781,7 @@
         res = self.meta_interp(g, [6, 14])
         assert res == g(6, 14)
         self.check_loop_count(9)
-        self.check_loops(getarrayitem_gc=8, everywhere=True)
+        self.check_resops(getarrayitem_gc=8)
 
     def test_multiple_specialied_versions_bridge(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
@@ -1983,8 +1969,8 @@
         res = self.meta_interp(g, [3, 23])
         assert res == 7068153
         self.check_loop_count(7)
-        self.check_loops(guard_true=4, guard_class=0, int_add=2, int_mul=2,
-                         guard_false=2)
+        self.check_resops(guard_true=6, guard_class=2, int_mul=3,
+                          int_add=3, guard_false=3)
 
     def test_dont_trace_every_iteration(self):
         myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'i', 'sa'])
@@ -2228,27 +2214,27 @@
             return sa
 
         assert self.meta_interp(f1, [5, 5]) == 50
-        self.check_loops(int_rshift=0, everywhere=True)
+        self.check_resops(int_rshift=0)
 
         for f in (f1, f2):
             assert self.meta_interp(f, [5, 6]) == 50
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [10, 5]) == 100
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [10, 6]) == 100
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [5, 31]) == 0
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             bigval = 1
             while (bigval << 3).__class__ is int:
                 bigval = bigval << 1
 
             assert self.meta_interp(f, [bigval, 5]) == 0
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
     def test_overflowing_shift_neg(self):
         myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'n', 'sa'])
@@ -2273,27 +2259,27 @@
             return sa
 
         assert self.meta_interp(f1, [-5, 5]) == -50
-        self.check_loops(int_rshift=0, everywhere=True)
+        self.check_resops(int_rshift=0)
 
         for f in (f1, f2):
             assert self.meta_interp(f, [-5, 6]) == -50
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [-10, 5]) == -100
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [-10, 6]) == -100
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             assert self.meta_interp(f, [-5, 31]) == 0
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
             bigval = 1
             while (bigval << 3).__class__ is int:
                 bigval = bigval << 1
 
             assert self.meta_interp(f, [bigval, 5]) == 0
-            self.check_loops(int_rshift=3, everywhere=True)
+            self.check_resops(int_rshift=3)
 
     def test_pure_op_not_to_be_propagated(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'sa'])
@@ -2433,8 +2419,7 @@
                 if counter > 10:
                     return 7
         assert self.meta_interp(build, []) == 7
-        self.check_loops(getfield_gc_pure=0)
-        self.check_loops(getfield_gc_pure=2, everywhere=True)
+        self.check_resops(getfield_gc_pure=2)
 
     def test_args_becomming_equal(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'b'])
@@ -2567,7 +2552,7 @@
                 i += 1
             return sa
         assert self.meta_interp(f, [20]) == f(20)
-        self.check_loops(int_gt=1, int_lt=2, int_ge=0, int_le=0)
+        self.check_resops(int_lt=4, int_le=0, int_ge=0, int_gt=2)
 
     def test_intbounds_not_generalized1(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa'])
@@ -2584,7 +2569,8 @@
                 i += 1
             return sa
         assert self.meta_interp(f, [20]) == f(20)
-        self.check_loops(int_gt=1, int_lt=3, int_ge=2, int_le=1)
+        self.check_resops(int_lt=6, int_le=2, int_ge=4, int_gt=3)
+        
 
     def test_intbounds_not_generalized2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'node'])
@@ -2604,7 +2590,7 @@
                 i += 1
             return sa
         assert self.meta_interp(f, [20]) == f(20)
-        self.check_loops(int_gt=1, int_lt=2, int_ge=1, int_le=1)
+        self.check_resops(int_lt=4, int_le=3, int_ge=3, int_gt=2)
 
     def test_retrace_limit1(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
@@ -2858,7 +2844,7 @@
             return a[0].intvalue
         res = self.meta_interp(f, [100])
         assert res == -2
-        #self.check_loops(getarrayitem_gc=0, setarrayitem_gc=0) -- xxx?
+        self.check_resops(setarrayitem_gc=2, getarrayitem_gc=1)
 
     def test_retrace_ending_up_retracing_another_loop(self):
 
@@ -2958,7 +2944,7 @@
                 i += 1
         res = self.meta_interp(f, [32])
         assert res == f(32)
-        self.check_loops(arraylen_gc=2)
+        self.check_resops(arraylen_gc=3)
 
     def test_ulonglong_mod(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'i'])
@@ -3145,9 +3131,9 @@
                 a = A(a.i + 1)
 
         self.meta_interp(f, [])
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
         self.meta_interp(f, [], enable_opts='')
-        self.check_loops(new_with_vtable=1)
+        self.check_resops(new_with_vtable=1)
 
     def test_two_loopinvariant_arrays1(self):
         from pypy.rpython.lltypesystem import lltype, llmemory, rffi
@@ -3239,7 +3225,7 @@
             return sa
         res = self.meta_interp(f, [32])
         assert res == f(32)
-        self.check_loops(arraylen_gc=2, everywhere=True)
+        self.check_resops(arraylen_gc=2)
 
     def test_release_gil_flush_heap_cache(self):
         if sys.platform == "win32":
@@ -3276,7 +3262,7 @@
                 lock.release()
             return n
         res = self.meta_interp(f, [10, 1])
-        self.check_loops(getfield_gc=2)
+        self.check_resops(getfield_gc=4)
         assert res == f(10, 1)
 
     def test_jit_merge_point_with_raw_pointer(self):
@@ -3340,10 +3326,10 @@
 
         res = self.meta_interp(main, [0, 10, 2], enable_opts='')
         assert res == main(0, 10, 2)
-        self.check_loops(call=1)
+        self.check_resops(call=1)
         res = self.meta_interp(main, [1, 10, 2], enable_opts='')
         assert res == main(1, 10, 2)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_look_inside_iff_virtual(self):
         # There's no good reason for this to be look_inside_iff, but it's a test!
@@ -3368,10 +3354,10 @@
                     i += f(A(2), n)
         res = self.meta_interp(main, [0], enable_opts='')
         assert res == main(0)
-        self.check_loops(call=1, getfield_gc=0)
+        self.check_resops(call=1, getfield_gc=0)
         res = self.meta_interp(main, [1], enable_opts='')
         assert res == main(1)
-        self.check_loops(call=0, getfield_gc=0)
+        self.check_resops(call=0, getfield_gc=0)
 
     def test_reuse_elidable_result(self):
         driver = JitDriver(reds=['n', 's'], greens = [])
@@ -3384,10 +3370,9 @@
             return s
         res = self.meta_interp(main, [10])
         assert res == main(10)
-        self.check_loops({
-            'call': 1, 'guard_no_exception': 1, 'guard_true': 1, 'int_add': 2,
-            'int_gt': 1, 'int_sub': 1, 'strlen': 1, 'jump': 1,
-        })
+        self.check_resops({'int_gt': 2, 'strlen': 2, 'guard_true': 2,
+                           'int_sub': 2, 'jump': 2, 'call': 2,
+                           'guard_no_exception': 2, 'int_add': 4})
 
     def test_look_inside_iff_const_getarrayitem_gc_pure(self):
         driver = JitDriver(greens=['unroll'], reds=['s', 'n'])
@@ -3419,10 +3404,10 @@
         res = self.meta_interp(main, [0, 10])
         assert res == main(0, 10)
         # 2 calls, one for f() and one for char_mul
-        self.check_loops(call=2)
+        self.check_resops(call=4)
         res = self.meta_interp(main, [1, 10])
         assert res == main(1, 10)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_setarrayitem_followed_by_arraycopy(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'x', 'y'])
@@ -3523,7 +3508,8 @@
 
         res = self.meta_interp(f, [10])
         assert res == 0
-        self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
+        self.check_resops({'jump': 2, 'guard_true': 2, 'int_gt': 2,
+                           'int_sub': 2})
 
     def test_virtual_opaque_ptr(self):
         myjitdriver = JitDriver(greens = [], reds = ["n"])
@@ -3542,7 +3528,9 @@
             return n
         res = self.meta_interp(f, [10])
         assert res == 0
-        self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
+        self.check_resops({'jump': 2, 'guard_true': 2, 'int_gt': 2,
+                           'int_sub': 2})
+
 
     def test_virtual_opaque_dict(self):
         myjitdriver = JitDriver(greens = [], reds = ["n"])
@@ -3562,7 +3550,10 @@
             return n
         res = self.meta_interp(f, [10])
         assert res == 0
-        self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
+        self.check_resops({'int_gt': 2, 'getfield_gc': 1, 'int_eq': 1,
+                           'guard_true': 2, 'int_sub': 2, 'jump': 2,
+                           'guard_false': 1})
+
 
     def test_convert_from_SmallFunctionSetPBCRepr_to_FunctionsPBCRepr(self):
         f1 = lambda n: n+1
diff --git a/pypy/jit/metainterp/test/test_del.py b/pypy/jit/metainterp/test/test_del.py
--- a/pypy/jit/metainterp/test/test_del.py
+++ b/pypy/jit/metainterp/test/test_del.py
@@ -20,12 +20,12 @@
                 n -= 1
             return 42
         self.meta_interp(f, [20])
-        self.check_loops({'call': 2,      # calls to a helper function
-                          'guard_no_exception': 2,    # follows the calls
-                          'int_sub': 1,
-                          'int_gt': 1,
-                          'guard_true': 1,
-                          'jump': 1})
+        self.check_resops({'call': 4,      # calls to a helper function
+                           'guard_no_exception': 4,    # follows the calls
+                           'int_sub': 2,
+                           'int_gt': 2,
+                           'guard_true': 2,
+                           'jump': 2})
 
     def test_class_of_allocated(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
@@ -78,7 +78,7 @@
             return 1
         res = self.meta_interp(f, [20], enable_opts='')
         assert res == 1
-        self.check_loops(call=1)   # for the case B(), but not for the case A()
+        self.check_resops(call=1)   # for the case B(), but not for the case A()
 
 
 class TestLLtype(DelTests, LLJitMixin):
@@ -103,7 +103,7 @@
                     break
             return 42
         self.meta_interp(f, [20])
-        self.check_loops(getfield_raw=1, setfield_raw=1, call=0, call_pure=0)
+        self.check_resops(call_pure=0, setfield_raw=2, call=0, getfield_raw=2)
 
 class TestOOtype(DelTests, OOJitMixin):
     def setup_class(cls):
diff --git a/pypy/jit/metainterp/test/test_dict.py b/pypy/jit/metainterp/test/test_dict.py
--- a/pypy/jit/metainterp/test/test_dict.py
+++ b/pypy/jit/metainterp/test/test_dict.py
@@ -91,7 +91,7 @@
         res1 = f(100)
         res2 = self.meta_interp(f, [100], listops=True)
         assert res1 == res2
-        self.check_loops(int_mod=1) # the hash was traced and eq, but cached
+        self.check_resops(int_mod=2) # the hash was traced and eq, but cached
 
     def test_dict_setdefault(self):
         myjitdriver = JitDriver(greens = [], reds = ['total', 'dct'])
@@ -107,7 +107,7 @@
         assert f(100) == 50
         res = self.meta_interp(f, [100], listops=True)
         assert res == 50
-        self.check_loops(new=0, new_with_vtable=0)
+        self.check_resops(new=0, new_with_vtable=0)
 
     def test_dict_as_counter(self):
         myjitdriver = JitDriver(greens = [], reds = ['total', 'dct'])
@@ -128,7 +128,7 @@
         assert f(100) == 50
         res = self.meta_interp(f, [100], listops=True)
         assert res == 50
-        self.check_loops(int_mod=1) # key + eq, but cached
+        self.check_resops(int_mod=2) # key + eq, but cached
 
     def test_repeated_lookup(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'd'])
@@ -153,12 +153,13 @@
 
         res = self.meta_interp(f, [100], listops=True)
         assert res == f(50)
-        self.check_loops({"call": 5, "getfield_gc": 1, "getinteriorfield_gc": 1,
-                          "guard_false": 1, "guard_no_exception": 4,
-                          "guard_true": 1, "int_and": 1, "int_gt": 1,
-                          "int_is_true": 1, "int_sub": 1, "jump": 1,
-                          "new_with_vtable": 1, "new": 1, "new_array": 1,
-                          "setfield_gc": 3, })
+        self.check_resops({'new_array': 2, 'getfield_gc': 2,
+                           'guard_true': 2, 'jump': 2,
+                           'new_with_vtable': 2, 'getinteriorfield_gc': 2,
+                           'setfield_gc': 6, 'int_gt': 2, 'int_sub': 2,
+                           'call': 10, 'int_and': 2,
+                           'guard_no_exception': 8, 'new': 2,
+                           'guard_false': 2, 'int_is_true': 2})
 
 
 class TestOOtype(DictTests, OOJitMixin):
diff --git a/pypy/jit/metainterp/test/test_exception.py b/pypy/jit/metainterp/test/test_exception.py
--- a/pypy/jit/metainterp/test/test_exception.py
+++ b/pypy/jit/metainterp/test/test_exception.py
@@ -35,10 +35,8 @@
             return n
         res = self.meta_interp(f, [10])
         assert res == 0
-        self.check_loops({'jump': 1,
-                          'int_gt': 1, 'guard_true': 1,
-                          'int_sub': 1})
-
+        self.check_resops({'jump': 2, 'guard_true': 2,
+                           'int_gt': 2, 'int_sub': 2})
 
     def test_bridge_from_guard_exception(self):
         myjitdriver = JitDriver(greens = [], reds = ['n'])
diff --git a/pypy/jit/metainterp/test/test_fficall.py b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -67,23 +67,23 @@
              'byval': False}
         supported = all(d[check] for check in jitif)
         if supported:
-            self.check_loops(
-                call_release_gil=1,   # a CALL_RELEASE_GIL, and no other CALLs
+            self.check_resops(
+                call_release_gil=2,   # a CALL_RELEASE_GIL, and no other CALLs
                 call=0,
                 call_may_force=0,
-                guard_no_exception=1,
-                guard_not_forced=1,
-                int_add=1,
-                int_lt=1,
-                guard_true=1,
-                jump=1)
+                guard_no_exception=2,
+                guard_not_forced=2,
+                int_add=2,
+                int_lt=2,
+                guard_true=2,
+                jump=2)
         else:
-            self.check_loops(
+            self.check_resops(
                 call_release_gil=0,   # no CALL_RELEASE_GIL
-                int_add=1,
-                int_lt=1,
-                guard_true=1,
-                jump=1)
+                int_add=2,
+                int_lt=2,
+                guard_true=2,
+                jump=2)
         return res
 
     def test_byval_result(self):
@@ -144,10 +144,8 @@
                     return result_point[0].x * result_point[0].y
 
         assert self.meta_interp(main, [10]) == main(10) == 9000
-        self.check_loops({"int_add": 3, "jump": 1, "int_lt": 1, "guard_true": 1,
-                          "getinteriorfield_raw": 4, "setinteriorfield_raw": 2
-        })
-
+        self.check_resops({'jump': 2, 'int_lt': 2, 'setinteriorfield_raw': 4,
+                           'getinteriorfield_raw': 8, 'int_add': 6, 'guard_true': 2})
 
 class TestFfiCall(FfiCallTests, LLJitMixin):
     supports_all = False
@@ -156,4 +154,4 @@
     supports_all = True     # supports_{floats,longlong,singlefloats}
 
 class TestFfiLookup(FfiLookupTests, LLJitMixin):
-    pass
\ No newline at end of file
+    pass
diff --git a/pypy/jit/metainterp/test/test_greenfield.py b/pypy/jit/metainterp/test/test_greenfield.py
--- a/pypy/jit/metainterp/test/test_greenfield.py
+++ b/pypy/jit/metainterp/test/test_greenfield.py
@@ -25,7 +25,7 @@
         res = self.meta_interp(g, [7])
         assert res == -2
         self.check_loop_count(2)
-        self.check_loops(guard_value=0)
+        self.check_resops(guard_value=0)
 
     def test_green_field_2(self):
         myjitdriver = JitDriver(greens=['ctx.x'], reds=['ctx'])
@@ -50,7 +50,7 @@
         res = self.meta_interp(g, [7])
         assert res == -22
         self.check_loop_count(6)
-        self.check_loops(guard_value=0)
+        self.check_resops(guard_value=0)
 
 
 class TestLLtypeGreenFieldsTests(GreenFieldsTests, LLJitMixin):
diff --git a/pypy/jit/metainterp/test/test_jitdriver.py b/pypy/jit/metainterp/test/test_jitdriver.py
--- a/pypy/jit/metainterp/test/test_jitdriver.py
+++ b/pypy/jit/metainterp/test/test_jitdriver.py
@@ -88,7 +88,7 @@
         assert res == loop2(4, 40)
         # we expect only one int_sub, corresponding to the single
         # compiled instance of loop1()
-        self.check_loops(int_sub=1)
+        self.check_resops(int_sub=2)
         # the following numbers are not really expectations of the test
         # itself, but just the numbers that we got after looking carefully
         # at the generated machine code
@@ -154,7 +154,7 @@
         res = self.meta_interp(loop2, [4, 40], repeat=7, inline=True)
         assert res == loop2(4, 40)
         # we expect no int_sub, but a residual call
-        self.check_loops(int_sub=0, call=1)
+        self.check_resops(call=2, int_sub=0)
 
     def test_multiple_jits_trace_too_long(self):
         myjitdriver1 = JitDriver(greens=["n"], reds=["i", "box"])
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -6,8 +6,8 @@
 class ListTests:
 
     def check_all_virtualized(self):
-        self.check_loops(new_array=0, setarrayitem_gc=0, getarrayitem_gc=0,
-                         arraylen_gc=0)
+        self.check_resops(setarrayitem_gc=0, new_array=0, arraylen_gc=0,
+                          getarrayitem_gc=0)
 
     def test_simple_array(self):
         jitdriver = JitDriver(greens = [], reds = ['n'])
@@ -20,7 +20,7 @@
             return n
         res = self.meta_interp(f, [10], listops=True)
         assert res == 0
-        self.check_loops(int_sub=1)
+        self.check_resops(int_sub=2)
         self.check_all_virtualized()
 
     def test_list_pass_around(self):
@@ -56,7 +56,8 @@
         res = self.meta_interp(f, [10], listops=True)
         assert res == f(10)
         # one setitem should be gone by now
-        self.check_loops(call=1, setarrayitem_gc=2, getarrayitem_gc=1)
+        self.check_resops(setarrayitem_gc=4, getarrayitem_gc=2, call=2)
+
 
     def test_ll_fixed_setitem_fast(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 'l'])
@@ -93,7 +94,7 @@
 
         res = self.meta_interp(f, [10], listops=True)
         assert res == f(10)
-        self.check_loops(setarrayitem_gc=0, getarrayitem_gc=0, call=0)
+        self.check_resops(setarrayitem_gc=0, call=0, getarrayitem_gc=0)
 
     def test_vlist_alloc_and_set(self):
         # the check_loops fails, because [non-null] * n is not supported yet
@@ -141,7 +142,7 @@
 
         res = self.meta_interp(f, [5], listops=True)
         assert res == 7
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_fold_getitem_1(self):
         jitdriver = JitDriver(greens = ['pc', 'n', 'l'], reds = ['total'])
@@ -161,7 +162,7 @@
 
         res = self.meta_interp(f, [4], listops=True)
         assert res == f(4)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_fold_getitem_2(self):
         jitdriver = JitDriver(greens = ['pc', 'n', 'l'], reds = ['total', 'x'])
@@ -186,7 +187,7 @@
 
         res = self.meta_interp(f, [4], listops=True)
         assert res == f(4)
-        self.check_loops(call=0, getfield_gc=0)
+        self.check_resops(call=0, getfield_gc=0)
 
     def test_fold_indexerror(self):
         jitdriver = JitDriver(greens = [], reds = ['total', 'n', 'lst'])
@@ -206,7 +207,7 @@
 
         res = self.meta_interp(f, [15], listops=True)
         assert res == f(15)
-        self.check_loops(guard_exception=0)
+        self.check_resops(guard_exception=0)
 
     def test_virtual_resize(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 's'])
@@ -224,9 +225,8 @@
             return s
         res = self.meta_interp(f, [15], listops=True)
         assert res == f(15)
-        self.check_loops({"int_add": 1, "int_sub": 1, "int_gt": 1,
-                          "guard_true": 1, "jump": 1})
-
+        self.check_resops({'jump': 2, 'int_gt': 2, 'int_add': 2,
+                           'guard_true': 2, 'int_sub': 2})
 
 class TestOOtype(ListTests, OOJitMixin):
     pass
@@ -258,4 +258,4 @@
         assert res == f(37)
         # There is the one actual field on a, plus several fields on the list
         # itself
-        self.check_loops(getfield_gc=10, everywhere=True)
+        self.check_resops(getfield_gc=10)
diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py
--- a/pypy/jit/metainterp/test/test_loop.py
+++ b/pypy/jit/metainterp/test/test_loop.py
@@ -60,7 +60,8 @@
         assert res == f(6, 13)
         self.check_loop_count(1)
         if self.enable_opts:
-            self.check_loops(getfield_gc = 0, setfield_gc = 1)
+            self.check_resops(setfield_gc=2, getfield_gc=0)
+
 
     def test_loop_with_two_paths(self):
         from pypy.rpython.lltypesystem import lltype
@@ -180,7 +181,10 @@
         assert res == 42
         self.check_loop_count(1)
         # the 'int_eq' and following 'guard' should be constant-folded
-        self.check_loops(int_eq=0, guard_true=1, guard_false=0)
+        if 'unroll' in self.enable_opts:
+            self.check_resops(int_eq=0, guard_true=2, guard_false=0)
+        else:
+            self.check_resops(int_eq=0, guard_true=1, guard_false=0)
         if self.basic:
             found = 0
             for op in get_stats().loops[0]._all_operations():
@@ -643,8 +647,12 @@
         res = self.meta_interp(main_interpreter_loop, [1])
         assert res == 102
         self.check_loop_count(1)
-        self.check_loops({'int_add' : 3, 'int_gt' : 1,
-                          'guard_false' : 1, 'jump' : 1})
+        if 'unroll' in self.enable_opts:
+            self.check_resops({'int_add' : 6, 'int_gt' : 2,
+                               'guard_false' : 2, 'jump' : 2})
+        else:
+            self.check_resops({'int_add' : 3, 'int_gt' : 1,
+                               'guard_false' : 1, 'jump' : 1})
 
     def test_automatic_promotion(self):
         myjitdriver = JitDriver(greens = ['i'],
@@ -686,7 +694,7 @@
         self.check_loop_count(1)
         # These loops do different numbers of ops based on which optimizer we
         # are testing with.
-        self.check_loops(self.automatic_promotion_result)
+        self.check_resops(self.automatic_promotion_result)
 
     def test_can_enter_jit_outside_main_loop(self):
         myjitdriver = JitDriver(greens=[], reds=['i', 'j', 'a'])
diff --git a/pypy/jit/metainterp/test/test_loop_unroll.py b/pypy/jit/metainterp/test/test_loop_unroll.py
--- a/pypy/jit/metainterp/test/test_loop_unroll.py
+++ b/pypy/jit/metainterp/test/test_loop_unroll.py
@@ -8,7 +8,8 @@
     enable_opts = ALL_OPTS_NAMES
     
     automatic_promotion_result = {
-        'int_add' : 3, 'int_gt' : 1, 'guard_false' : 1, 'jump' : 1, 
+        'int_gt': 2, 'guard_false': 2, 'jump': 2, 'int_add': 6,
+        'guard_value': 1        
     }
 
     # ====> test_loop.py
diff --git a/pypy/jit/metainterp/test/test_quasiimmut.py b/pypy/jit/metainterp/test/test_quasiimmut.py
--- a/pypy/jit/metainterp/test/test_quasiimmut.py
+++ b/pypy/jit/metainterp/test/test_quasiimmut.py
@@ -73,8 +73,7 @@
         #
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0,
-                         everywhere=True)
+        self.check_resops(guard_not_invalidated=2, getfield_gc=0)
         #
         from pypy.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -103,7 +102,7 @@
         assert f(100, 7) == 721
         res = self.meta_interp(f, [100, 7])
         assert res == 721
-        self.check_loops(guard_not_invalidated=0, getfield_gc=1)
+        self.check_resops(guard_not_invalidated=0, getfield_gc=3)
         #
         from pypy.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -134,8 +133,7 @@
         #
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0,
-                         everywhere=True)
+        self.check_resops(guard_not_invalidated=2, getfield_gc=0)
 
     def test_change_during_tracing_1(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -160,7 +158,7 @@
         assert f(100, 7) == 721
         res = self.meta_interp(f, [100, 7])
         assert res == 721
-        self.check_loops(guard_not_invalidated=0, getfield_gc=1)
+        self.check_resops(guard_not_invalidated=0, getfield_gc=2)
 
     def test_change_during_tracing_2(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -186,7 +184,7 @@
         assert f(100, 7) == 700
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_loops(guard_not_invalidated=0, getfield_gc=1)
+        self.check_resops(guard_not_invalidated=0, getfield_gc=2)
 
     def test_change_invalidate_reentering(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -212,7 +210,7 @@
         assert g(100, 7) == 700707
         res = self.meta_interp(g, [100, 7])
         assert res == 700707
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0)
+        self.check_resops(guard_not_invalidated=4, getfield_gc=0)
 
     def test_invalidate_while_running(self):
         jitdriver = JitDriver(greens=['foo'], reds=['i', 'total'])
@@ -324,8 +322,8 @@
         assert f(100, 15) == 3009
         res = self.meta_interp(f, [100, 15])
         assert res == 3009
-        self.check_loops(guard_not_invalidated=4, getfield_gc=0,
-                         call_may_force=0, guard_not_forced=0)
+        self.check_resops(guard_not_invalidated=8, guard_not_forced=0,
+                          call_may_force=0, getfield_gc=0)
 
     def test_list_simple_1(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -347,9 +345,8 @@
         #
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0,
-                         getarrayitem_gc=0, getarrayitem_gc_pure=0,
-                         everywhere=True)
+        self.check_resops(getarrayitem_gc_pure=0, guard_not_invalidated=2,
+                          getarrayitem_gc=0, getfield_gc=0)
         #
         from pypy.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -385,9 +382,8 @@
         #
         res = self.meta_interp(f, [100, 7])
         assert res == 714
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0,
-                         getarrayitem_gc=0, getarrayitem_gc_pure=0,
-                         arraylen_gc=0, everywhere=True)
+        self.check_resops(getarrayitem_gc_pure=0, guard_not_invalidated=2,
+                          arraylen_gc=0, getarrayitem_gc=0, getfield_gc=0)
         #
         from pypy.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -421,9 +417,8 @@
         #
         res = self.meta_interp(f, [100, 7])
         assert res == 700
-        self.check_loops(guard_not_invalidated=2, getfield_gc=0,
-                         getarrayitem_gc=0, getarrayitem_gc_pure=0,
-                         everywhere=True)
+        self.check_resops(guard_not_invalidated=2, getfield_gc=0,
+                          getarrayitem_gc=0, getarrayitem_gc_pure=0)
         #
         from pypy.jit.metainterp.warmspot import get_stats
         loops = get_stats().loops
@@ -460,9 +455,9 @@
         assert f(100, 15) == 3009
         res = self.meta_interp(f, [100, 15])
         assert res == 3009
-        self.check_loops(guard_not_invalidated=4, getfield_gc=0,
-                         getarrayitem_gc=0, getarrayitem_gc_pure=0,
-                         call_may_force=0, guard_not_forced=0)
+        self.check_resops(call_may_force=0, getfield_gc=0,
+                          getarrayitem_gc_pure=0, guard_not_forced=0,
+                          getarrayitem_gc=0, guard_not_invalidated=8)
 
     def test_invalidated_loop_is_not_used_any_more_as_target(self):
         myjitdriver = JitDriver(greens=['foo'], reds=['x'])
diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py
--- a/pypy/jit/metainterp/test/test_recursive.py
+++ b/pypy/jit/metainterp/test/test_recursive.py
@@ -143,11 +143,11 @@
         f = self.get_interpreter(codes)
 
         assert self.meta_interp(f, [0, 0, 0], enable_opts='') == 42
-        self.check_loops(int_add = 1, call_may_force = 1, call = 0)
+        self.check_resops(call_may_force=1, int_add=1, call=0)
         assert self.meta_interp(f, [0, 0, 0], enable_opts='',
                                 inline=True) == 42
-        self.check_loops(int_add = 2, call_may_force = 0, call = 0,
-                         guard_no_exception = 0)
+        self.check_resops(call=0, int_add=2, call_may_force=0,
+                          guard_no_exception=0)
 
     def test_inline_jitdriver_check(self):
         code = "021"
@@ -160,7 +160,7 @@
                                 inline=True) == 42
         # the call is fully inlined, because we jump to subcode[1], thus
         # skipping completely the JUMP_BACK in subcode[0]
-        self.check_loops(call_may_force = 0, call_assembler = 0, call = 0)
+        self.check_resops(call=0, call_may_force=0, call_assembler=0)
 
     def test_guard_failure_in_inlined_function(self):
         def p(pc, code):
@@ -491,10 +491,10 @@
             return loop(100)
 
         res = self.meta_interp(main, [0], enable_opts='', trace_limit=TRACE_LIMIT)
-        self.check_loops(call_may_force=1, call=0)
+        self.check_resops(call=0, call_may_force=1)
 
         res = self.meta_interp(main, [1], enable_opts='', trace_limit=TRACE_LIMIT)
-        self.check_loops(call_may_force=0, call=0)
+        self.check_resops(call=0, call_may_force=0)
 
     def test_trace_from_start(self):
         def p(pc, code):
@@ -576,7 +576,7 @@
                 result += f('-c-----------l-', i+100)
         self.meta_interp(g, [10], backendopt=True)
         self.check_aborted_count(1)
-        self.check_loops(call_assembler=1, call=0)
+        self.check_resops(call=0, call_assembler=2)        
         self.check_tree_loop_count(3)
 
     def test_directly_call_assembler(self):
@@ -625,8 +625,7 @@
         try:
             compile.compile_tmp_callback = my_ctc
             self.meta_interp(portal, [2, 5], inline=True)
-            self.check_loops(call_assembler=2, call_may_force=0,
-                             everywhere=True)
+            self.check_resops(call_may_force=0, call_assembler=2)
         finally:
             compile.compile_tmp_callback = original_ctc
         # check that we made a temporary callback
@@ -681,8 +680,7 @@
         try:
             compile.compile_tmp_callback = my_ctc
             self.meta_interp(main, [2, 5], inline=True)
-            self.check_loops(call_assembler=2, call_may_force=0,
-                             everywhere=True)
+            self.check_resops(call_may_force=0, call_assembler=2)
         finally:
             compile.compile_tmp_callback = original_ctc
         # check that we made a temporary callback
@@ -1021,7 +1019,7 @@
         res = self.meta_interp(portal, [2, 0], inline=True,
                                policy=StopAtXPolicy(residual))
         assert res == portal(2, 0)
-        self.check_loops(call_assembler=4, everywhere=True)
+        self.check_resops(call_assembler=4)
 
     def test_inline_without_hitting_the_loop(self):
         driver = JitDriver(greens = ['codeno'], reds = ['i'],
@@ -1045,7 +1043,7 @@
         assert portal(0) == 70
         res = self.meta_interp(portal, [0], inline=True)
         assert res == 70
-        self.check_loops(call_assembler=0)
+        self.check_resops(call_assembler=0)
 
     def test_inline_with_hitting_the_loop_sometimes(self):
         driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'],
@@ -1071,7 +1069,7 @@
         assert portal(0, 1) == 2095
         res = self.meta_interp(portal, [0, 1], inline=True)
         assert res == 2095
-        self.check_loops(call_assembler=12, everywhere=True)
+        self.check_resops(call_assembler=12)
 
     def test_inline_with_hitting_the_loop_sometimes_exc(self):
         driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'],
@@ -1109,7 +1107,7 @@
         assert main(0, 1) == 2095
         res = self.meta_interp(main, [0, 1], inline=True)
         assert res == 2095
-        self.check_loops(call_assembler=12, everywhere=True)
+        self.check_resops(call_assembler=12)
 
     def test_handle_jitexception_in_portal(self):
         # a test for _handle_jitexception_in_portal in blackhole.py
@@ -1238,7 +1236,7 @@
                 i += 1
 
         self.meta_interp(portal, [0, 0, 0], inline=True)
-        self.check_loops(call=0, call_may_force=0)
+        self.check_resops(call_may_force=0, call=0)
 
 class TestLLtype(RecursiveTests, LLJitMixin):
     pass
diff --git a/pypy/jit/metainterp/test/test_resume.py b/pypy/jit/metainterp/test/test_resume.py
--- a/pypy/jit/metainterp/test/test_resume.py
+++ b/pypy/jit/metainterp/test/test_resume.py
@@ -23,11 +23,11 @@
     assert tag(-3, 2) == rffi.r_short(-3<<2|2)
     assert tag((1<<13)-1, 3) == rffi.r_short(((1<<15)-1)|3)
     assert tag(-1<<13, 3) == rffi.r_short((-1<<15)|3)
-    py.test.raises(ValueError, tag, 3, 5)
-    py.test.raises(ValueError, tag, 1<<13, 0)
-    py.test.raises(ValueError, tag, (1<<13)+1, 0)
-    py.test.raises(ValueError, tag, (-1<<13)-1, 0)
-    py.test.raises(ValueError, tag, (-1<<13)-5, 0)
+    py.test.raises(AssertionError, tag, 3, 5)
+    py.test.raises(TagOverflow, tag, 1<<13, 0)
+    py.test.raises(TagOverflow, tag, (1<<13)+1, 0)
+    py.test.raises(TagOverflow, tag, (-1<<13)-1, 0)
+    py.test.raises(TagOverflow, tag, (-1<<13)-5, 0)
 
 def test_untag():
     assert untag(tag(3, 1)) == (3, 1)
@@ -1318,8 +1318,7 @@
     assert rffi.cast(lltype.Signed, pf[1].fieldnum) == 1062
     assert rffi.cast(lltype.Signed, pf[1].itemindex) == 2147483647
     #
-    from pypy.jit.metainterp.pyjitpl import SwitchToBlackhole
-    py.test.raises(SwitchToBlackhole, modifier._add_pending_fields,
+    py.test.raises(TagOverflow, modifier._add_pending_fields,
                    [(array_a, 42, 63, 2147483648)])
 
 def test_resume_reader_fields_and_arrayitems():
diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py
--- a/pypy/jit/metainterp/test/test_send.py
+++ b/pypy/jit/metainterp/test/test_send.py
@@ -20,9 +20,8 @@
             return c
         res = self.meta_interp(f, [1])
         assert res == 2
-        self.check_loops({'jump': 1,
-                          'int_sub': 1, 'int_gt' : 1,
-                          'guard_true': 1})    # all folded away
+        self.check_resops({'jump': 2, 'guard_true': 2, 'int_gt': 2,
+                           'int_sub': 2}) # all folded away
 
     def test_red_builtin_send(self):
         myjitdriver = JitDriver(greens = [], reds = ['i', 'counter'])
@@ -41,12 +40,9 @@
             return res
         res = self.meta_interp(f, [1], policy=StopAtXPolicy(externfn))
         assert res == 2
-        if self.type_system == 'ootype':
-            self.check_loops(call=1, oosend=1) # 'len' remains
-        else:
-            # 'len' becomes a getfield('num_items') for now in lltype,
-            # which is itself encoded as a 'getfield_gc'
-            self.check_loops(call=1, getfield_gc=1)
+        # 'len' becomes a getfield('num_items') for now in lltype,
+        # which is itself encoded as a 'getfield_gc'
+        self.check_resops(call=2, getfield_gc=2)
 
     def test_send_to_single_target_method(self):
         myjitdriver = JitDriver(greens = [], reds = ['i', 'counter'])
@@ -70,11 +66,10 @@
         res = self.meta_interp(f, [1], policy=StopAtXPolicy(externfn),
                                backendopt=True)
         assert res == 43
-        self.check_loops({'call': 1, 'guard_no_exception': 1,
-                          'getfield_gc': 1,
-                          'int_add': 1,
-                          'jump': 1, 'int_gt' : 1, 'guard_true' : 1,
-                          'int_sub' : 1})
+        self.check_resops({'int_gt': 2, 'getfield_gc': 2,
+                           'guard_true': 2, 'int_sub': 2, 'jump': 2,
+                           'call': 2, 'guard_no_exception': 2,
+                           'int_add': 2})
 
     def test_red_send_to_green_receiver(self):
         myjitdriver = JitDriver(greens = ['i'], reds = ['counter', 'j'])
@@ -97,7 +92,7 @@
             return res
         res = self.meta_interp(f, [4, -1])
         assert res == 145
-        self.check_loops(int_add = 1, everywhere=True)
+        self.check_resops(int_add=1)
 
     def test_oosend_base(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'w'])
@@ -132,7 +127,7 @@
         assert res == 17
         res = self.meta_interp(f, [4, 14])
         assert res == 1404
-        self.check_loops(guard_class=0, new_with_vtable=0, new=0)
+        self.check_resops(guard_class=1, new=0, new_with_vtable=0)
 
     def test_three_receivers(self):
         myjitdriver = JitDriver(greens = [], reds = ['y'])
@@ -205,8 +200,7 @@
         # of the body in a single bigger loop with no failing guard except
         # the final one.
         self.check_loop_count(1)
-        self.check_loops(guard_class=0,
-                                int_add=2, int_sub=2)
+        self.check_resops(guard_class=1, int_add=4, int_sub=4)
         self.check_jumps(14)
 
     def test_oosend_guard_failure_2(self):
@@ -247,8 +241,7 @@
         res = self.meta_interp(f, [4, 28])
         assert res == f(4, 28)
         self.check_loop_count(1)
-        self.check_loops(guard_class=0,
-                                int_add=2, int_sub=2)
+        self.check_resops(guard_class=1, int_add=4, int_sub=4)
         self.check_jumps(14)
 
     def test_oosend_different_initial_class(self):
@@ -285,8 +278,8 @@
         # However, this doesn't match the initial value of 'w'.
         # XXX This not completely easy to check...
         self.check_loop_count(1)
-        self.check_loops(int_add=0, int_lshift=1, guard_class=0,
-                         new_with_vtable=0, new=0)
+        self.check_resops(guard_class=1, new_with_vtable=0, int_lshift=2,
+                          int_add=0, new=0)
 
     def test_indirect_call_unknown_object_1(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'y'])
@@ -566,10 +559,7 @@
         policy = StopAtXPolicy(new, A.foo.im_func, B.foo.im_func)
         res = self.meta_interp(fn, [0, 20], policy=policy)
         assert res == 42
-        if self.type_system == 'ootype':
-            self.check_loops(oosend=1)
-        else:
-            self.check_loops(call=1)
+        self.check_resops(call=2)
 
 
     def test_residual_oosend_with_void(self):
@@ -597,10 +587,7 @@
         policy = StopAtXPolicy(new, A.foo.im_func)
         res = self.meta_interp(fn, [1, 20], policy=policy)
         assert res == 41
-        if self.type_system == 'ootype':
-            self.check_loops(oosend=1)
-        else:
-            self.check_loops(call=1)
+        self.check_resops(call=2)
 
     def test_constfold_pure_oosend(self):
         myjitdriver = JitDriver(greens=[], reds = ['i', 'obj'])
@@ -621,10 +608,7 @@
         policy = StopAtXPolicy(A.foo.im_func)
         res = self.meta_interp(fn, [1, 20], policy=policy)
         assert res == 42
-        if self.type_system == 'ootype':
-            self.check_loops(oosend=0)
-        else:
-            self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_generalize_loop(self):
         myjitdriver = JitDriver(greens=[], reds = ['i', 'obj'])
diff --git a/pypy/jit/metainterp/test/test_slist.py b/pypy/jit/metainterp/test/test_slist.py
--- a/pypy/jit/metainterp/test/test_slist.py
+++ b/pypy/jit/metainterp/test/test_slist.py
@@ -76,7 +76,7 @@
             return lst[i]
         res = self.meta_interp(f, [21], listops=True)
         assert res == f(21)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_getitem_neg(self):
         myjitdriver = JitDriver(greens = [], reds = ['i', 'n'])
@@ -92,7 +92,7 @@
             return x
         res = self.meta_interp(f, [-2], listops=True)
         assert res == 41
-        self.check_loops(call=0, guard_value=0)
+        self.check_resops(call=0, guard_value=0)
 
 # we don't support resizable lists on ootype
 #class TestOOtype(ListTests, OOJitMixin):
diff --git a/pypy/jit/metainterp/test/test_string.py b/pypy/jit/metainterp/test/test_string.py
--- a/pypy/jit/metainterp/test/test_string.py
+++ b/pypy/jit/metainterp/test/test_string.py
@@ -30,7 +30,7 @@
             return i
         res = self.meta_interp(f, [10, True, _str('h')], listops=True)
         assert res == 5
-        self.check_loops(**{self.CALL: 1, self.CALL_PURE: 0, 'everywhere': True})
+        self.check_resops(**{self.CALL: 1, self.CALL_PURE: 0})
 
     def test_eq_folded(self):
         _str = self._str
@@ -50,7 +50,7 @@
             return i
         res = self.meta_interp(f, [10, True, _str('h')], listops=True)
         assert res == 5
-        self.check_loops(**{self.CALL: 0, self.CALL_PURE: 0})
+        self.check_resops(**{self.CALL: 0, self.CALL_PURE: 0})
 
     def test_newstr(self):
         _str, _chr = self._str, self._chr
@@ -85,7 +85,7 @@
                 n -= 1
             return 42
         self.meta_interp(f, [6])
-        self.check_loops(newstr=0, strsetitem=0, strlen=0,
+        self.check_resops(newstr=0, strsetitem=0, strlen=0,
                          newunicode=0, unicodesetitem=0, unicodelen=0)
 
     def test_char2string_escape(self):
@@ -126,7 +126,7 @@
             return total
         res = self.meta_interp(f, [6])
         assert res == 21
-        self.check_loops(newstr=0, strgetitem=0, strsetitem=0, strlen=0,
+        self.check_resops(newstr=0, strgetitem=0, strsetitem=0, strlen=0,
                          newunicode=0, unicodegetitem=0, unicodesetitem=0,
                          unicodelen=0)
 
@@ -147,7 +147,7 @@
                 m -= 1
             return 42
         self.meta_interp(f, [6, 7])
-        self.check_loops(newstr=0, strsetitem=0,
+        self.check_resops(newstr=0, strsetitem=0,
                          newunicode=0, unicodesetitem=0,
                          call=0, call_pure=0)
 
@@ -168,12 +168,11 @@
             return 42
         self.meta_interp(f, [6, 7])
         if _str is str:
-            self.check_loops(newstr=1, strsetitem=0, copystrcontent=2,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, copystrcontent=4,
+                              strsetitem=0, call=2, newstr=2)
         else:
-            self.check_loops(newunicode=1, unicodesetitem=0,
-                             copyunicodecontent=2,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, unicodesetitem=0, call=2,
+                              copyunicodecontent=4, newunicode=2)
 
     def test_strconcat_escape_str_char(self):
         _str, _chr = self._str, self._chr
@@ -192,12 +191,11 @@
             return 42
         self.meta_interp(f, [6, 7])
         if _str is str:
-            self.check_loops(newstr=1, strsetitem=1, copystrcontent=1,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, copystrcontent=2, strsetitem=2,
+                              call=2, newstr=2)
         else:
-            self.check_loops(newunicode=1, unicodesetitem=1,
-                             copyunicodecontent=1,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, unicodesetitem=2, call=2,
+                              copyunicodecontent=2, newunicode=2)
 
     def test_strconcat_escape_char_str(self):
         _str, _chr = self._str, self._chr
@@ -216,12 +214,11 @@
             return 42
         self.meta_interp(f, [6, 7])
         if _str is str:
-            self.check_loops(newstr=1, strsetitem=1, copystrcontent=1,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, copystrcontent=2,
+                              strsetitem=2, call=2, newstr=2)
         else:
-            self.check_loops(newunicode=1, unicodesetitem=1,
-                             copyunicodecontent=1,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, unicodesetitem=2, call=2,
+                              copyunicodecontent=2, newunicode=2)
 
     def test_strconcat_escape_char_char(self):
         _str, _chr = self._str, self._chr
@@ -239,12 +236,11 @@
             return 42
         self.meta_interp(f, [6, 7])
         if _str is str:
-            self.check_loops(newstr=1, strsetitem=2, copystrcontent=0,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, copystrcontent=0,
+                              strsetitem=4, call=2, newstr=2)
         else:
-            self.check_loops(newunicode=1, unicodesetitem=2,
-                             copyunicodecontent=0,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, unicodesetitem=4, call=2,
+                              copyunicodecontent=0, newunicode=2)
 
     def test_strconcat_escape_str_char_str(self):
         _str, _chr = self._str, self._chr
@@ -263,12 +259,11 @@
             return 42
         self.meta_interp(f, [6, 7])
         if _str is str:
-            self.check_loops(newstr=1, strsetitem=1, copystrcontent=2,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, copystrcontent=4, strsetitem=2,
+                              call=2, newstr=2)
         else:
-            self.check_loops(newunicode=1, unicodesetitem=1,
-                             copyunicodecontent=2,
-                             call=1, call_pure=0)   # escape
+            self.check_resops(call_pure=0, unicodesetitem=2, call=2,
+                              copyunicodecontent=4, newunicode=2)
 
     def test_strconcat_guard_fail(self):
         _str = self._str
@@ -325,7 +320,7 @@
                 m -= 1
             return 42
         self.meta_interp(f, [6, 7])
-        self.check_loops(newstr=0, newunicode=0)
+        self.check_resops(newunicode=0, newstr=0)
 
     def test_str_slice_len_surviving(self):
         _str = self._str
@@ -504,9 +499,9 @@
             sys.defaultencoding = _str('utf-8')
             return sa
         assert self.meta_interp(f, [8]) == f(8)
-        self.check_loops({'int_add': 1, 'guard_true': 1, 'int_sub': 1,
-                          'jump': 1, 'int_is_true': 1,
-                          'guard_not_invalidated': 1})
+        self.check_resops({'jump': 2, 'int_is_true': 2, 'int_add': 2,
+                           'guard_true': 2, 'guard_not_invalidated': 2,
+                           'int_sub': 2})
 
     def test_promote_string(self):
         driver = JitDriver(greens = [], reds = ['n'])
@@ -519,7 +514,7 @@
             return 0
 
         self.meta_interp(f, [0])
-        self.check_loops(call=3 + 1) # one for int2str
+        self.check_resops(call=7)
 
 #class TestOOtype(StringTests, OOJitMixin):
 #    CALL = "oosend"
@@ -552,9 +547,8 @@
                 m -= 1
             return 42
         self.meta_interp(f, [6, 7])
-        self.check_loops(call=1,    # escape()
-                         newunicode=1, unicodegetitem=0,
-                         unicodesetitem=1, copyunicodecontent=1)
+        self.check_resops(unicodesetitem=2, newunicode=2, call=4,
+                          copyunicodecontent=2, unicodegetitem=0)
 
     def test_str2unicode_fold(self):
         _str = self._str
@@ -572,9 +566,9 @@
                 m -= 1
             return 42
         self.meta_interp(f, [6, 7])
-        self.check_loops(call_pure=0, call=1,
-                         newunicode=0, unicodegetitem=0,
-                         unicodesetitem=0, copyunicodecontent=0)
+        self.check_resops(call_pure=0, unicodesetitem=0, call=2,
+                          newunicode=0, unicodegetitem=0,
+                          copyunicodecontent=0)
 
     def test_join_chars(self):
         jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
@@ -596,9 +590,8 @@
         # The "".join should be unrolled, since the length of x is known since
         # it is virtual, ensure there are no calls to ll_join_chars, or
         # allocations.
-        self.check_loops({
-            "guard_true": 5, "int_is_true": 3, "int_lt": 2, "int_add": 2, "jump": 2,
-        }, everywhere=True)
+        self.check_resops({'jump': 2, 'guard_true': 5, 'int_lt': 2,
+                           'int_add': 2, 'int_is_true': 3})
 
     def test_virtual_copystringcontent(self):
         jitdriver = JitDriver(reds=['n', 'result'], greens=[])
diff --git a/pypy/jit/metainterp/test/test_tl.py b/pypy/jit/metainterp/test/test_tl.py
--- a/pypy/jit/metainterp/test/test_tl.py
+++ b/pypy/jit/metainterp/test/test_tl.py
@@ -72,16 +72,16 @@
         res = self.meta_interp(main, [0, 6], listops=True,
                                backendopt=True)
         assert res == 5040
-        self.check_loops({'int_mul':1, 'jump':1,
-                          'int_sub':1, 'int_le':1, 'guard_false':1})
+        self.check_resops({'jump': 2, 'int_le': 2, 'guard_value': 1,
+                           'int_mul': 2, 'guard_false': 2, 'int_sub': 2})
 
     def test_tl_2(self):
         main = self._get_main()
         res = self.meta_interp(main, [1, 10], listops=True,
                                backendopt=True)
         assert res == main(1, 10)
-        self.check_loops({'int_sub':1, 'int_le':1,
-                          'guard_false':1, 'jump':1})
+        self.check_resops({'int_le': 2, 'int_sub': 2, 'jump': 2,
+                           'guard_false': 2, 'guard_value': 1})
 
     def test_tl_call(self, listops=True, policy=None):
         from pypy.jit.tl.tl import interp
diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py
--- a/pypy/jit/metainterp/test/test_virtual.py
+++ b/pypy/jit/metainterp/test/test_virtual.py
@@ -31,8 +31,9 @@
         res = self.meta_interp(f, [10])
         assert res == 55 * 10
         self.check_loop_count(1)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0,
+                          getfield_gc=2, new=0)
+
 
     def test_virtualized2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node1', 'node2'])
@@ -53,8 +54,8 @@
                 n -= 1
             return node1.value * node2.value
         assert f(10) == self.meta_interp(f, [10])
-        self.check_loops(new=0, new_with_vtable=0,
-                         getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0, getfield_gc=2,
+                          new=0)
 
     def test_virtualized_circular1(self):
         class MyNode():
@@ -79,8 +80,8 @@
         res = self.meta_interp(f, [10])
         assert res == 55 * 10
         self.check_loop_count(1)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0,
+                          getfield_gc=3, new=0)
 
     def test_virtualized_float(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -97,7 +98,7 @@
         res = self.meta_interp(f, [10])
         assert res == f(10)
         self.check_loop_count(1)
-        self.check_loops(new=0, float_add=0)
+        self.check_resops(new=0, float_add=1)
 
     def test_virtualized_float2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -115,7 +116,8 @@
         res = self.meta_interp(f, [10])
         assert res == f(10)
         self.check_loop_count(1)
-        self.check_loops(new=0, float_add=1)
+        self.check_resops(new=0, float_add=2)
+
 
     def test_virtualized_2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -139,8 +141,8 @@
         res = self.meta_interp(f, [10])
         assert res == 55 * 30
         self.check_loop_count(1)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0, getfield_gc=2,
+                          new=0)
 
     def test_nonvirtual_obj_delays_loop(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -160,8 +162,8 @@
         res = self.meta_interp(f, [500])
         assert res == 640
         self.check_loop_count(1)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0,
+                          getfield_gc=1, new=0)
 
     def test_two_loops_with_virtual(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -184,8 +186,9 @@
         res = self.meta_interp(f, [18])
         assert res == f(18)
         self.check_loop_count(2)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
+        self.check_resops(new_with_vtable=0, setfield_gc=0,
+                          getfield_gc=2, new=0)
+
         
     def test_two_loops_with_escaping_virtual(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
@@ -212,8 +215,8 @@
         res = self.meta_interp(f, [20], policy=StopAtXPolicy(externfn))
         assert res == f(20)
         self.check_loop_count(3)
-        self.check_loops(**{self._new_op: 1})
-        self.check_loops(int_mul=0, call=1)
+        self.check_resops(**{self._new_op: 1})
+        self.check_resops(int_mul=0, call=1)
 
     def test_two_virtuals(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'prev'])
@@ -236,7 +239,7 @@
 
         res = self.meta_interp(f, [12])
         assert res == 78
-        self.check_loops(new_with_vtable=0, new=0)
+        self.check_resops(new_with_vtable=0, new=0)
 
     def test_specialied_bridge(self):
         myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
@@ -281,7 +284,7 @@
 
         res = self.meta_interp(f, [20])
         assert res == 9
-        self.check_loops(new_with_vtable=0, new=0)
+        self.check_resops(new_with_vtable=0, new=0)
 
     def test_immutable_constant_getfield(self):
         myjitdriver = JitDriver(greens = ['stufflist'], reds = ['n', 'i'])
@@ -307,7 +310,7 @@
 
         res = self.meta_interp(f, [10, 1, 0], listops=True)
         assert res == 0
-        self.check_loops(getfield_gc=0)
+        self.check_resops(getfield_gc=0)
 
     def test_escapes(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'parent'])
@@ -336,7 +339,7 @@
 
         res = self.meta_interp(f, [10], policy=StopAtXPolicy(g))
         assert res == 3
-        self.check_loops(**{self._new_op: 1}) 
+        self.check_resops(**{self._new_op: 1}) 
 
     def test_virtual_on_virtual(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'parent'])
@@ -366,7 +369,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 2
-        self.check_loops(new=0, new_with_vtable=0) 
+        self.check_resops(new=0, new_with_vtable=0)
 
     def test_bridge_from_interpreter(self):
         mydriver = JitDriver(reds = ['n', 'f'], greens = [])
@@ -841,7 +844,7 @@
                 del t2
             return i
         assert self.meta_interp(f, []) == 10
-        self.check_loops(new_array=0)
+        self.check_resops(new_array=0)
 
     def test_virtual_streq_bug(self):
         mydriver = JitDriver(reds = ['i', 's', 'a'], greens = [])
@@ -942,8 +945,8 @@
 
         res = self.meta_interp(f, [16])
         assert res == f(16)
-        self.check_loops(getfield_gc=2)
-        
+        self.check_resops(getfield_gc=7)
+     
 
 # ____________________________________________________________
 # Run 1: all the tests instantiate a real RPython class
@@ -985,10 +988,8 @@
         res = self.meta_interp(f, [10])
         assert res == 20
         self.check_loop_count(1)
-        self.check_loops(new=0, new_with_vtable=0,
-                                getfield_gc=0, setfield_gc=0)
-
-
+        self.check_resops(new_with_vtable=0, setfield_gc=0, getfield_gc=0,
+                          new=0)
 
 class TestOOtype_Instance(VirtualTests, OOJitMixin):
     _new_op = 'new_with_vtable'
diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -77,7 +77,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [20])
         assert res == 30
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_preexisting_access_2(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -102,7 +102,7 @@
         assert f(5) == 185
         res = self.meta_interp(f, [5])
         assert res == 185
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_two_paths_access(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -124,7 +124,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [18])
         assert res == 10118
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_synchronize_in_return(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy'],
@@ -146,7 +146,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [18])
         assert res == 10180
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_virtualizable_and_greens(self):
         myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'xy'],
@@ -174,7 +174,7 @@
             return res
         res = self.meta_interp(f, [40])
         assert res == 50 * 4
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_double_frame(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy', 'other'],
@@ -197,8 +197,7 @@
             return xy.inst_x
         res = self.meta_interp(f, [20])
         assert res == 134
-        self.check_loops(getfield_gc=0, setfield_gc=1)
-        self.check_loops(getfield_gc=1, setfield_gc=2, everywhere=True)
+        self.check_resops(setfield_gc=2, getfield_gc=1)
 
     # ------------------------------
 
@@ -248,8 +247,8 @@
             return xy2.inst_l1[2]
         res = self.meta_interp(f, [16])
         assert res == 3001 + 16 * 80
-        self.check_loops(getfield_gc=0, setfield_gc=0,
-                         getarrayitem_gc=0, setarrayitem_gc=0)
+        self.check_resops(setarrayitem_gc=0, setfield_gc=0,
+                          getarrayitem_gc=0, getfield_gc=0)
 
     def test_synchronize_arrays_in_return(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -279,8 +278,7 @@
         assert f(18) == 10360
         res = self.meta_interp(f, [18])
         assert res == 10360
-        self.check_loops(getfield_gc=0, setfield_gc=0,
-                         getarrayitem_gc=0)
+        self.check_resops(setfield_gc=0, getarrayitem_gc=0, getfield_gc=0)
 
     def test_array_length(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -306,8 +304,8 @@
             return xy2.inst_l1[1]
         res = self.meta_interp(f, [18])
         assert res == 2941309 + 18
-        self.check_loops(getfield_gc=0, setfield_gc=0,
-                         getarrayitem_gc=0, arraylen_gc=0)
+        self.check_resops(setfield_gc=0, getarrayitem_gc=0,
+                          arraylen_gc=0, getfield_gc=0)
 
     def test_residual_function(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
@@ -340,8 +338,8 @@
             return xy2.inst_l1[1]
         res = self.meta_interp(f, [18])
         assert res == 2941309 + 18
-        self.check_loops(getfield_gc=0, setfield_gc=0,
-                         getarrayitem_gc=0, arraylen_gc=1, call=1)
+        self.check_resops(call=2, setfield_gc=0, getarrayitem_gc=0,
+                          arraylen_gc=2, getfield_gc=0)
 
     def test_double_frame_array(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2', 'other'],
@@ -377,8 +375,8 @@
         expected = f(20)
         res = self.meta_interp(f, [20], enable_opts='')
         assert res == expected
-        self.check_loops(getfield_gc=1, setfield_gc=0,
-                         arraylen_gc=1, getarrayitem_gc=1, setarrayitem_gc=1)
+        self.check_resops(setarrayitem_gc=1, setfield_gc=0,
+                          getarrayitem_gc=1, arraylen_gc=1, getfield_gc=1)
 
     # ------------------------------
 
@@ -425,8 +423,7 @@
         assert f(18) == 10360
         res = self.meta_interp(f, [18])
         assert res == 10360
-        self.check_loops(getfield_gc=0, setfield_gc=0,
-                         getarrayitem_gc=0)
+        self.check_resops(setfield_gc=0, getarrayitem_gc=0, getfield_gc=0)
 
     # ------------------------------
 
@@ -460,8 +457,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_loops(getfield_gc=0, setfield_gc=0)
-
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_virtualizable_with_array(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'frame'],
@@ -495,8 +491,7 @@
 
         res = self.meta_interp(f, [10, 1], listops=True)
         assert res == f(10, 1)
-        self.check_loops(getarrayitem_gc=0)
-
+        self.check_resops(getarrayitem_gc=0)
 
     def test_subclass_of_virtualizable(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -524,8 +519,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_loops(getfield_gc=0, setfield_gc=0)
-
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_external_pass(self):
         jitdriver = JitDriver(greens = [], reds = ['n', 'z', 'frame'],
@@ -1011,8 +1005,8 @@
 
         res = self.meta_interp(f, [70], listops=True)
         assert res == intmask(42 ** 70)
-        self.check_loops(int_add=0,
-                         int_sub=1)   # for 'n -= 1' only
+        self.check_resops(int_add=0,
+                          int_sub=2)   # for 'n -= 1' only
 
     def test_simple_access_directly(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -1043,7 +1037,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
         from pypy.jit.backend.test.support import BaseCompiledMixin
         if isinstance(self, BaseCompiledMixin):
@@ -1098,42 +1092,42 @@
 
         res = self.meta_interp(f, [10])
         assert res == 55
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
 
     def test_check_for_nonstandardness_only_once(self):
-         myjitdriver = JitDriver(greens = [], reds = ['frame'],
-                                 virtualizables = ['frame'])
+        myjitdriver = JitDriver(greens = [], reds = ['frame'],
+                                virtualizables = ['frame'])
 
-         class Frame(object):
-             _virtualizable2_ = ['x', 'y', 'z']
+        class Frame(object):
+            _virtualizable2_ = ['x', 'y', 'z']
 
-             def __init__(self, x, y, z=1):
-                 self = hint(self, access_directly=True)
-                 self.x = x
-                 self.y = y
-                 self.z = z
+            def __init__(self, x, y, z=1):
+                self = hint(self, access_directly=True)
+                self.x = x
+                self.y = y
+                self.z = z
 
-         class SomewhereElse:
-             pass
-         somewhere_else = SomewhereElse()
+        class SomewhereElse:
+            pass
+        somewhere_else = SomewhereElse()
 
-         def f(n):
-             frame = Frame(n, 0)
-             somewhere_else.top_frame = frame        # escapes
-             frame = hint(frame, access_directly=True)
-             while frame.x > 0:
-                 myjitdriver.can_enter_jit(frame=frame)
-                 myjitdriver.jit_merge_point(frame=frame)
-                 top_frame = somewhere_else.top_frame
-                 child_frame = Frame(frame.x, top_frame.z, 17)
-                 frame.y += child_frame.x
-                 frame.x -= top_frame.z
-             return somewhere_else.top_frame.y
- 
-         res = self.meta_interp(f, [10])
-         assert res == 55
-         self.check_loops(new_with_vtable=0, ptr_eq=1, everywhere=True)
-         self.check_history(ptr_eq=2)
+        def f(n):
+            frame = Frame(n, 0)
+            somewhere_else.top_frame = frame        # escapes
+            frame = hint(frame, access_directly=True)
+            while frame.x > 0:
+                myjitdriver.can_enter_jit(frame=frame)
+                myjitdriver.jit_merge_point(frame=frame)
+                top_frame = somewhere_else.top_frame
+                child_frame = Frame(frame.x, top_frame.z, 17)
+                frame.y += child_frame.x
+                frame.x -= top_frame.z
+            return somewhere_else.top_frame.y
+
+        res = self.meta_interp(f, [10])
+        assert res == 55
+        self.check_resops(new_with_vtable=0, ptr_eq=1)
+        self.check_history(ptr_eq=2)
 
     def test_virtual_child_frame_with_arrays(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -1165,7 +1159,7 @@
 
         res = self.meta_interp(f, [10], listops=True)
         assert res == 55
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
 
     def test_blackhole_should_not_pay_attention(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -1203,7 +1197,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 155
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_blackhole_should_synchronize(self):
         myjitdriver = JitDriver(greens = [], reds = ['frame'],
@@ -1239,7 +1233,7 @@
 
         res = self.meta_interp(f, [10])
         assert res == 155
-        self.check_loops(getfield_gc=0, setfield_gc=0)
+        self.check_resops(setfield_gc=0, getfield_gc=0)
 
     def test_blackhole_should_not_reenter(self):
         if not self.basic:
diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py
--- a/pypy/jit/metainterp/test/test_virtualref.py
+++ b/pypy/jit/metainterp/test/test_virtualref.py
@@ -171,7 +171,7 @@
             return 1
         #
         self.meta_interp(f, [10])
-        self.check_loops(new_with_vtable=1)   # the vref
+        self.check_resops(new_with_vtable=2) # the vref
         self.check_aborted_count(0)
 
     def test_simple_all_removed(self):
@@ -205,8 +205,7 @@
                 virtual_ref_finish(vref, xy)
         #
         self.meta_interp(f, [15])
-        self.check_loops(new_with_vtable=0,     # all virtualized
-                         new_array=0)
+        self.check_resops(new_with_vtable=0, new_array=0)
         self.check_aborted_count(0)
 
     def test_simple_no_access(self):
@@ -242,7 +241,7 @@
                 virtual_ref_finish(vref, xy)
         #
         self.meta_interp(f, [15])
-        self.check_loops(new_with_vtable=1,     # the vref: xy doesn't need to be forced
+        self.check_resops(new_with_vtable=2,     # the vref: xy doesn't need to be forced
                          new_array=0)           # and neither xy.next1/2/3
         self.check_aborted_count(0)
 
@@ -280,8 +279,8 @@
                 exctx.topframeref = vref_None
         #
         self.meta_interp(f, [15])
-        self.check_loops(new_with_vtable=2,   # XY(), the vref
-                         new_array=3)         # next1/2/3
+        self.check_resops(new_with_vtable=4,   # XY(), the vref
+                          new_array=6)         # next1/2/3
         self.check_aborted_count(0)
 
     def test_simple_force_sometimes(self):
@@ -320,8 +319,8 @@
         #
         res = self.meta_interp(f, [30])
         assert res == 13
-        self.check_loops(new_with_vtable=1,   # the vref, but not XY()
-                         new_array=0)         # and neither next1/2/3
+        self.check_resops(new_with_vtable=2,   # the vref, but not XY()
+                          new_array=0)         # and neither next1/2/3
         self.check_loop_count(1)
         self.check_aborted_count(0)
 
@@ -362,7 +361,7 @@
         #
         res = self.meta_interp(f, [30])
         assert res == 13
-        self.check_loops(new_with_vtable=0, # all virtualized in the n!=13 loop
+        self.check_resops(new_with_vtable=0, # all virtualized in the n!=13 loop
                          new_array=0)
         self.check_loop_count(1)
         self.check_aborted_count(0)
@@ -412,7 +411,7 @@
         res = self.meta_interp(f, [72])
         assert res == 6
         self.check_loop_count(2)     # the loop and the bridge
-        self.check_loops(new_with_vtable=2,  # loop: nothing; bridge: vref, xy
+        self.check_resops(new_with_vtable=2,  # loop: nothing; bridge: vref, xy
                          new_array=2)        # bridge: next4, next5
         self.check_aborted_count(0)
 
@@ -442,8 +441,8 @@
         #
         res = self.meta_interp(f, [15])
         assert res == 1
-        self.check_loops(new_with_vtable=2,     # vref, xy
-                         new_array=1)           # next1
+        self.check_resops(new_with_vtable=4,     # vref, xy
+                          new_array=2)           # next1
         self.check_aborted_count(0)
 
     def test_recursive_call_1(self):
@@ -543,7 +542,7 @@
         #
         res = self.meta_interp(f, [15])
         assert res == 1
-        self.check_loops(new_with_vtable=2)     # vref, xy
+        self.check_resops(new_with_vtable=4)     # vref, xy
 
     def test_cannot_use_invalid_virtualref(self):
         myjitdriver = JitDriver(greens = [], reds = ['n'])
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -100,12 +100,12 @@
         # check that the set_param will override the default
         res = self.meta_interp(f, [10, llstr('')])
         assert res == 0
-        self.check_loops(new_with_vtable=1)
+        self.check_resops(new_with_vtable=1)
 
         res = self.meta_interp(f, [10, llstr(ALL_OPTS_NAMES)],
                                enable_opts='')
         assert res == 0
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
 
     def test_unwanted_loops(self):
         mydriver = JitDriver(reds = ['n', 'total', 'm'], greens = [])
@@ -160,7 +160,7 @@
             return n
         self.meta_interp(f, [50], backendopt=True)
         self.check_enter_count_at_most(2)
-        self.check_loops(call=0)
+        self.check_resops(call=0)
 
     def test_loop_header(self):
         # artificial test: we enter into the JIT only when can_enter_jit()
@@ -184,7 +184,7 @@
         assert f(15) == 1
         res = self.meta_interp(f, [15], backendopt=True)
         assert res == 1
-        self.check_loops(int_add=1)   # I get 13 without the loop_header()
+        self.check_resops(int_add=2)   # I get 13 without the loop_header()
 
     def test_omit_can_enter_jit(self):
         # Simple test comparing the effects of always giving a can_enter_jit(),
@@ -246,8 +246,8 @@
                 m = m - 1
         self.meta_interp(f1, [8])
         self.check_loop_count(1)
-        self.check_loops({'int_sub': 1, 'int_gt': 1, 'guard_true': 1,
-                          'jump': 1})
+        self.check_resops({'jump': 2, 'guard_true': 2, 'int_gt': 2,
+                           'int_sub': 2})
 
     def test_void_red_variable(self):
         mydriver = JitDriver(greens=[], reds=['a', 'm'])
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
@@ -255,10 +255,8 @@
         s_binding = self.translator.annotator.binding
         jd._portal_args_s = [s_binding(v) for v in args]
         graph = copygraph(graph)
-        graph.startblock.isstartblock = False
         [jmpp] = find_jit_merge_points([graph])
         graph.startblock = support.split_before_jit_merge_point(*jmpp)
-        graph.startblock.isstartblock = True
         # a crash in the following checkgraph() means that you forgot
         # to list some variable in greens=[] or reds=[] in JitDriver,
         # or that a jit_merge_point() takes a constant as an argument.
diff --git a/pypy/jit/tl/spli/test/test_jit.py b/pypy/jit/tl/spli/test/test_jit.py
--- a/pypy/jit/tl/spli/test/test_jit.py
+++ b/pypy/jit/tl/spli/test/test_jit.py
@@ -36,7 +36,7 @@
                 i = i + 1
             return i
         self.interpret(f, [])
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
 
     def test_bridge(self):
         py.test.skip('We currently cant virtualize across bridges')
@@ -52,7 +52,7 @@
             return total
 
         self.interpret(f, [1, 10])
-        self.check_loops(new_with_vtable=0)
+        self.check_resops(new_with_vtable=0)
 
     def test_bridge_bad_case(self):
         py.test.skip('We currently cant virtualize across bridges')
@@ -67,7 +67,7 @@
             return a + b
 
         self.interpret(f, [1, 10])
-        self.check_loops(new_with_vtable=1) # XXX should eventually be 0?
+        self.check_resops(new_with_vtable=1) # XXX should eventually be 0?
         # I think it should be either 0 or 2, 1 makes little sense
         # If the loop after entering goes first time to the bridge, a
         # is rewrapped again, without preserving the identity. I'm not
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -1,7 +1,7 @@
 import py
 from pypy.interpreter.baseobjspace import Wrappable, W_Root
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app, ObjSpace, NoneNotWrapped
+from pypy.interpreter.gateway import interp2app, ObjSpace
 from pypy.interpreter.typedef import TypeDef
 from pypy.rlib import jit
 import weakref
@@ -294,11 +294,11 @@
     lifeline = getlifelinewithcallbacks(space, w_obj)
     return lifeline.make_proxy_with_callback(w_obj, w_callable)
 
-def proxy(space, w_obj, w_callable=NoneNotWrapped):
+def proxy(space, w_obj, w_callable=None):
     """Create a proxy object that weakly references 'obj'.
 'callback', if given, is called with the proxy as an argument when 'obj'
 is about to be finalized."""
-    if w_callable is None:
+    if space.is_w(w_callable, space.w_None):
         return get_or_make_proxy(space, w_obj)
     else:
         return make_proxy_with_callback(space, w_obj, w_callable)
diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -324,6 +324,7 @@
         class A(object): pass
         a = A()
         assert _weakref.proxy(a) is _weakref.proxy(a)
+        assert _weakref.proxy(a) is _weakref.proxy(a, None)
 
     def test_callable_proxy(self):
         import _weakref, gc
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -12,7 +12,9 @@
         'zeros': 'interp_numarray.zeros',
         'empty': 'interp_numarray.zeros',
         'ones': 'interp_numarray.ones',
+        'dot': 'interp_numarray.dot',
         'fromstring': 'interp_support.fromstring',
+        'flatiter': 'interp_numarray.W_FlatIterator',
 
         'True_': 'space.w_True',
         'False_': 'space.w_False',
@@ -48,6 +50,7 @@
         ("sign", "sign"),
         ("sin", "sin"),
         ("subtract", "subtract"),
+        ('sqrt', 'sqrt'),
         ("tan", "tan"),
     ]:
         interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
@@ -57,4 +60,5 @@
         'mean': 'app_numpy.mean',
         'inf': 'app_numpy.inf',
         'e': 'app_numpy.e',
+        'arange': 'app_numpy.arange',
     }
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -6,12 +6,33 @@
 inf = float("inf")
 e = math.e
 
+
 def average(a):
     # This implements a weighted average, for now we don't implement the
     # weighting, just the average part!
     return mean(a)
 
+
 def mean(a):
     if not hasattr(a, "mean"):
         a = numpypy.array(a)
     return a.mean()
+
+
+def arange(start, stop=None, step=1, dtype=None):
+    '''arange([start], stop[, step], dtype=None)
+    Generate values in the half-interval [start, stop).
+    '''
+    if stop is None:
+        stop = start
+        start = 0
+    if dtype is None:
+        test = numpypy.array([start, stop, step, 0])
+        dtype = test.dtype
+    arr = numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype)
+    i = start
+    for j in range(arr.size):
+        arr[j] = i
+        j += 1
+        i += step
+    return arr
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -69,8 +69,12 @@
             if start < 0:
                 start += size
             if stop < 0:
-                stop += size
-            return (start, stop, step, size//step)
+                stop += size + 1
+            if step < 0:
+                lgt = (stop - start + 1) / step + 1
+            else:
+                lgt = (stop - start - 1) / step + 1
+            return (start, stop, step, lgt)
 
     @specialize.argtype(1)
     def wrap(self, obj):
@@ -97,7 +101,7 @@
         return w_obj
 
     def float_w(self, w_obj):
-        assert isinstance(w_obj, FloatObject)        
+        assert isinstance(w_obj, FloatObject)
         return w_obj.floatval
 
     def int_w(self, w_obj):
@@ -208,11 +212,12 @@
 
     def execute(self, interp):
         arr = interp.variables[self.name]
-        w_index = self.index.execute(interp).eval(arr.start_iter()).wrap(interp.space)
+        w_index = self.index.execute(interp)
         # cast to int
         if isinstance(w_index, FloatObject):
             w_index = IntObject(int(w_index.floatval))
-        w_val = self.expr.execute(interp).eval(arr.start_iter()).wrap(interp.space)
+        w_val = self.expr.execute(interp)
+        assert isinstance(arr, BaseArray)
         arr.descr_setitem(interp.space, w_index, w_val)
 
     def __repr__(self):
@@ -240,18 +245,22 @@
             w_rhs = self.rhs.wrap(interp.space)
         else:
             w_rhs = self.rhs.execute(interp)
+        if not isinstance(w_lhs, BaseArray):
+            # scalar
+            dtype = interp.space.fromcache(W_Float64Dtype)
+            w_lhs = scalar_w(interp.space, dtype, w_lhs)
         assert isinstance(w_lhs, BaseArray)
         if self.name == '+':
             w_res = w_lhs.descr_add(interp.space, w_rhs)
         elif self.name == '*':
             w_res = w_lhs.descr_mul(interp.space, w_rhs)
         elif self.name == '-':
-            w_res = w_lhs.descr_sub(interp.space, w_rhs)            
+            w_res = w_lhs.descr_sub(interp.space, w_rhs)
         elif self.name == '->':
-            if isinstance(w_rhs, Scalar):
-                w_rhs = w_rhs.eval(w_rhs.start_iter()).wrap(interp.space)
-                assert isinstance(w_rhs, FloatObject)
+            assert not isinstance(w_rhs, Scalar)
+            if isinstance(w_rhs, FloatObject):
                 w_rhs = IntObject(int(w_rhs.floatval))
+            assert isinstance(w_lhs, BaseArray)
             w_res = w_lhs.descr_getitem(interp.space, w_rhs)
         else:
             raise NotImplementedError
@@ -274,9 +283,7 @@
         return space.wrap(self.v)
 
     def execute(self, interp):
-        dtype = interp.space.fromcache(W_Float64Dtype)
-        assert isinstance(dtype, W_Float64Dtype)
-        return Scalar(dtype, dtype.box(self.v))
+        return FloatObject(self.v)
 
 class RangeConstant(Node):
     def __init__(self, v):
@@ -325,6 +332,9 @@
     def wrap(self, space):
         return SliceObject(self.start, self.stop, self.step)
 
+    def execute(self, interp):
+        return SliceObject(self.start, self.stop, self.step)
+
     def __repr__(self):
         return 'slice(%s,%s,%s)' % (self.start, self.stop, self.step)
 
@@ -477,8 +487,8 @@
                 else:
                     step = 1
         return SliceConstant(start, stop, step)
-            
-        
+
+
     def parse_expression(self, tokens):
         stack = []
         while tokens.remaining():
@@ -532,7 +542,7 @@
             if token.name == 'array_right':
                 return elems
             assert token.name == 'coma'
-        
+
     def parse_statement(self, tokens):
         if (tokens.get(0).name == 'identifier' and
             tokens.get(1).name == 'assign'):
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -131,6 +131,7 @@
 
 
 def binop(func):
+    specialize.argtype(1, 2)(func)
     @functools.wraps(func)
     def impl(self, v1, v2):
         return self.adapt_val(func(self,
@@ -140,6 +141,7 @@
     return impl
 
 def raw_binop(func):
+    specialize.argtype(1, 2)(func)
     # Returns the result unwrapped.
     @functools.wraps(func)
     def impl(self, v1, v2):
@@ -150,6 +152,7 @@
     return impl
 
 def unaryop(func):
+    specialize.argtype(1)(func)
     @functools.wraps(func)
     def impl(self, v):
         return self.adapt_val(func(self, self.for_computation(self.unbox(v))))
@@ -221,6 +224,7 @@
 
     @binop
     def div(self, v1, v2):
+        # XXX this won't work after translation, probably requires ovfcheck
         try:
             return v1 / v2
         except ZeroDivisionError:
@@ -292,6 +296,12 @@
         if not -1.0 < v < 1.0:
             return rfloat.NAN
         return math.atanh(v)
+    @unaryop
+    def sqrt(self, v):
+        try:
+            return math.sqrt(v)
+        except ValueError:
+            return rfloat.NAN
 
 class IntegerArithmeticDtype(ArithmeticTypeMixin):
     _mixin_ = True
@@ -313,6 +323,18 @@
     @binop
     def mod(self, v1, v2):
         return v1 % v2
+    @binop
+    def pow(self, v1, v2):
+        res = 1
+        while v2 > 0:
+            if v2 & 1:
+                res *= v1
+            v2 >>= 1
+            if v2 == 0:
+                break
+            v1 *= v1
+        return res
+
 
 class SignedIntegerArithmeticDtype(IntegerArithmeticDtype):
     _mixin_ = True
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -4,7 +4,7 @@
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
 from pypy.rlib import jit
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.rstring import StringBuilder
 from pypy.rlib.objectmodel import instantiate
@@ -102,11 +102,12 @@
                     w_order=NoneNotWrapped):
     # find scalar
     if not space.issequence_w(w_item_or_iterable):
-        w_dtype = interp_ufuncs.find_dtype_for_scalar(space,
-                                                      w_item_or_iterable,
-                                                      w_dtype)
+        if space.is_w(w_dtype, space.w_None):
+            w_dtype = interp_ufuncs.find_dtype_for_scalar(space,
+                                                          w_item_or_iterable)
         dtype = space.interp_w(interp_dtype.W_Dtype,
-           space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
+            space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)
+        )
         return scalar_w(space, dtype, w_item_or_iterable)
     if w_order is None:
         order = 'C'
@@ -178,6 +179,25 @@
     def get_offset(self):
         return self.offset
 
+class OneDimIterator(BaseIterator):
+    def __init__(self, start, step, stop):
+        self.offset = start
+        self.step = step
+        self.size = stop * step + start
+
+    def next(self, shapelen):
+        arr = instantiate(OneDimIterator)
+        arr.size = self.size
+        arr.step = self.step
+        arr.offset = self.offset + self.step
+        return arr
+
+    def done(self):
+        return self.offset == self.size
+
+    def get_offset(self):
+        return self.offset
+
 class ViewIterator(BaseIterator):
     def __init__(self, arr):
         self.indices = [0] * len(arr.shape)
@@ -227,7 +247,7 @@
         self.strides = []
         self.backstrides = []
         for i in range(len(arr.shape)):
-            if arr.shape[i]==1:
+            if arr.shape[i] == 1:
                 self.strides.append(0)
                 self.backstrides.append(0)
             else:
@@ -312,12 +332,12 @@
     def get_offset(self):
         return 0
 
+
 class BaseArray(Wrappable):
     _attrs_ = ["invalidates", "signature", "shape", "strides", "backstrides",
                "start", 'order']
 
-    _immutable_fields_ = ['shape[*]', "strides[*]", "backstrides[*]", 'start',
-                          "order"]
+    _immutable_fields_ = ['start', "order"]
 
     strides = None
     start = 0
@@ -327,21 +347,24 @@
         self.shape = shape
         self.order = order
         if self.strides is None:
-            strides = []
-            backstrides = []
-            s = 1
-            shape_rev = shape[:]
-            if order == 'C':
-                shape_rev.reverse()
-            for sh in shape_rev:
-                strides.append(s)
-                backstrides.append(s * (sh - 1))
-                s *= sh
-            if order == 'C':
-                strides.reverse()
-                backstrides.reverse()
-            self.strides = strides[:]
-            self.backstrides = backstrides[:]
+            self.calc_strides(shape)
+
+    def calc_strides(self, shape):
+        strides = []
+        backstrides = []
+        s = 1
+        shape_rev = shape[:]
+        if self.order == 'C':
+            shape_rev.reverse()
+        for sh in shape_rev:
+            strides.append(s)
+            backstrides.append(s * (sh - 1))
+            s *= sh
+        if self.order == 'C':
+            strides.reverse()
+            backstrides.reverse()
+        self.strides = strides[:]
+        self.backstrides = backstrides[:]
 
     def invalidated(self):
         if self.invalidates:
@@ -499,7 +522,7 @@
         return space.wrap(self.find_size())
 
     def descr_copy(self, space):
-        return space.call_function(space.gettypefor(BaseArray), self, self.find_dtype())
+        return self.get_concrete().copy()
 
     def descr_len(self, space):
         return self.get_concrete().descr_len(space)
@@ -674,6 +697,7 @@
                 return False
         return True
 
+    @jit.unroll_safe
     def _prepare_slice_args(self, space, w_idx):
         if (space.isinstance_w(w_idx, space.w_int) or
             space.isinstance_w(w_idx, space.w_slice)):
@@ -684,6 +708,9 @@
     def descr_getitem(self, space, w_idx):
         if self._single_item_result(space, w_idx):
             concrete = self.get_concrete()
+            if len(concrete.shape) < 1:
+                raise OperationError(space.w_IndexError, space.wrap(
+                        "0-d arrays can't be indexed"))
             item = concrete._index_of_single_item(space, w_idx)
             return concrete.getitem(item).wrap(space)
         chunks = self._prepare_slice_args(space, w_idx)
@@ -691,24 +718,21 @@
 
     def descr_setitem(self, space, w_idx, w_value):
         self.invalidated()
-        concrete = self.get_concrete()
         if self._single_item_result(space, w_idx):
+            concrete = self.get_concrete()
+            if len(concrete.shape) < 1:
+                raise OperationError(space.w_IndexError, space.wrap(
+                        "0-d arrays can't be indexed"))
             item = concrete._index_of_single_item(space, w_idx)
             concrete.setitem_w(space, item, w_value)
             return
-        if isinstance(w_value, BaseArray):
-            # for now we just copy if setting part of an array from
-            # part of itself. can be improved.
-            if (concrete.get_root_storage() ==
-                w_value.get_concrete().get_root_storage()):
-                w_value = space.call_function(space.gettypefor(BaseArray), w_value)
-                assert isinstance(w_value, BaseArray)
-        else:
+        if not isinstance(w_value, BaseArray):
             w_value = convert_to_array(space, w_value)
         chunks = self._prepare_slice_args(space, w_idx)
         view = self.create_slice(space, chunks)
         view.setslice(space, w_value)
 
+    @jit.unroll_safe
     def create_slice(self, space, chunks):
         if len(chunks) == 1:
             start, stop, step, lgt = chunks[0]
@@ -750,21 +774,41 @@
         return space.wrap(space.float_w(self.descr_sum(space)) / self.find_size())
 
     def descr_nonzero(self, space):
-        try:
-            if self.find_size() > 1:
-                raise OperationError(space.w_ValueError, space.wrap(
-                    "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
-        except ValueError:
-            pass
+        if self.find_size() > 1:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"))
         return space.wrap(space.is_true(self.get_concrete().eval(
             self.start_iter(self.shape)).wrap(space)))
 
+    def descr_get_transpose(self, space):
+        concrete = self.get_concrete()
+        if len(concrete.shape) < 2:
+            return space.wrap(self)
+        new_sig = signature.Signature.find_sig([
+            NDimSlice.signature, self.signature
+        ])
+        strides = []
+        backstrides = []
+        shape = []
+        for i in range(len(concrete.shape) - 1, -1, -1):
+            strides.append(concrete.strides[i])
+            backstrides.append(concrete.backstrides[i])
+            shape.append(concrete.shape[i])
+        return space.wrap(NDimSlice(concrete, new_sig, self.start, strides[:],
+                           backstrides[:], shape[:]))
+
+    def descr_get_flatiter(self, space):
+        return space.wrap(W_FlatIterator(self))
+
     def getitem(self, item):
         raise NotImplementedError
 
     def start_iter(self, res_shape=None):
         raise NotImplementedError
 
+    def descr_debug_repr(self, space):
+        return space.wrap(self.debug_repr())
+
 def convert_to_array(space, w_obj):
     if isinstance(w_obj, BaseArray):
         return w_obj
@@ -796,7 +840,7 @@
         self.value = value
 
     def find_size(self):
-        raise ValueError
+        return 1
 
     def get_concrete(self):
         return self
@@ -805,7 +849,7 @@
         return self.dtype
 
     def getitem(self, item):
-        return self.value
+        raise NotImplementedError
 
     def eval(self, iter):
         return self.value
@@ -816,6 +860,12 @@
     def to_str(self, space, comma, builder, indent=' ', use_ellipsis=False):
         builder.append(self.dtype.str_format(self.value))
 
+    def copy(self):
+        return Scalar(self.dtype, self.value)
+
+    def debug_repr(self):
+        return 'Scalar'
+
 class VirtualArray(BaseArray):
     """
     Class for representing virtual arrays, such as binary ops or ufuncs
@@ -907,6 +957,17 @@
             return self.forced_result.start_iter(res_shape)
         return Call1Iterator(self.values.start_iter(res_shape))
 
+    def debug_repr(self):
+        sig = self.signature
+        assert isinstance(sig, signature.Signature)
+        call_sig = sig.components[0]
+        assert isinstance(call_sig, signature.Call1)
+        if self.forced_result is not None:
+            return 'Call1(%s, forced=%s)' % (call_sig.name,
+                                             self.forced_result.debug_repr())
+        return 'Call1(%s, %s)' % (call_sig.name,
+                                  self.values.debug_repr())
+
 class Call2(VirtualArray):
     """
     Intermediate class for performing binary operations.
@@ -946,6 +1007,18 @@
         assert isinstance(call_sig, signature.Call2)
         return call_sig.func(self.calc_dtype, lhs, rhs)
 
+    def debug_repr(self):
+        sig = self.signature
+        assert isinstance(sig, signature.Signature)
+        call_sig = sig.components[0]
+        assert isinstance(call_sig, signature.Call2)
+        if self.forced_result is not None:
+            return 'Call2(%s, forced=%s)' % (call_sig.name,
+                self.forced_result.debug_repr())
+        return 'Call2(%s, %s, %s)' % (call_sig.name,
+            self.left.debug_repr(),
+            self.right.debug_repr())
+
 class ViewArray(BaseArray):
     """
     Class for representing views of arrays, they will reflect changes of parent
@@ -985,8 +1058,6 @@
             return space.wrap(self.shape[0])
         return space.wrap(1)
 
-class VirtualView(VirtualArray):
-    pass
 
 class NDimSlice(ViewArray):
     signature = signature.BaseSignature()
@@ -1001,9 +1072,6 @@
         for sh in shape:
             self.size *= sh
 
-    def get_root_storage(self):
-        return self.parent.get_concrete().get_root_storage()
-
     def find_size(self):
         return self.size
 
@@ -1032,13 +1100,24 @@
     def start_iter(self, res_shape=None):
         if res_shape is not None and res_shape != self.shape:
             return BroadcastIterator(self, res_shape)
-        # XXX there is a possible optimization here with SingleDimViewIterator
-        #     ignore for now
+        if len(self.shape) == 1:
+            return OneDimIterator(self.start, self.strides[0], self.shape[0])
         return ViewIterator(self)
 
     def setitem(self, item, value):
         self.parent.setitem(item, value)
 
+    def debug_repr(self):
+        return 'Slice(%s)' % self.parent.debug_repr()
+
+    def copy(self):
+        array = NDimArray(self.size, self.shape[:], self.find_dtype())
+        iter = self.start_iter()
+        while not iter.done():
+            array.setitem(iter.offset, self.getitem(iter.offset))
+            iter = iter.next(len(self.shape))
+        return array
+
 class NDimArray(BaseArray):
     """ A class representing contiguous array. We know that each iteration
     by say ufunc will increase the data index by one
@@ -1053,9 +1132,6 @@
     def get_concrete(self):
         return self
 
-    def get_root_storage(self):
-        return self.storage
-
     def find_size(self):
         return self.size
 
@@ -1068,6 +1144,15 @@
     def eval(self, iter):
         return self.dtype.getitem(self.storage, iter.get_offset())
 
+    def copy(self):
+        array = NDimArray(self.size, self.shape[:], self.dtype, self.order)
+        rffi.c_memcpy(
+            rffi.cast(rffi.VOIDP, array.storage),
+            rffi.cast(rffi.VOIDP, self.storage),
+            self.size * self.dtype.num_bytes
+        )
+        return array
+
     def descr_len(self, space):
         if len(self.shape):
             return space.wrap(self.shape[0])
@@ -1089,6 +1174,9 @@
             return ArrayIterator(self.size)
         raise NotImplementedError  # use ViewIterator simply, test it
 
+    def debug_repr(self):
+        return 'Array'
+
     def __del__(self):
         lltype.free(self.storage, flavor='raw', track_allocation=False)
 
@@ -1122,6 +1210,12 @@
     arr.dtype.fill(arr.storage, one, 0, size)
     return space.wrap(arr)
 
+def dot(space, w_obj, w_obj2):
+    w_arr = convert_to_array(space, w_obj)
+    if isinstance(w_arr, Scalar):
+        return convert_to_array(space, w_obj2).descr_dot(space, w_arr)
+    return w_arr.descr_dot(space, w_obj2)
+
 BaseArray.typedef = TypeDef(
     'numarray',
     __new__ = interp2app(descr_new_array),
@@ -1159,11 +1253,15 @@
 
     __repr__ = interp2app(BaseArray.descr_repr),
     __str__ = interp2app(BaseArray.descr_str),
+    __debug_repr__ = interp2app(BaseArray.descr_debug_repr),
 
     dtype = GetSetProperty(BaseArray.descr_get_dtype),
     shape = GetSetProperty(BaseArray.descr_get_shape),
     size = GetSetProperty(BaseArray.descr_get_size),
 
+    T = GetSetProperty(BaseArray.descr_get_transpose),
+    flat = GetSetProperty(BaseArray.descr_get_flatiter),
+
     mean = interp2app(BaseArray.descr_mean),
     sum = interp2app(BaseArray.descr_sum),
     prod = interp2app(BaseArray.descr_prod),
@@ -1177,3 +1275,54 @@
 
     copy = interp2app(BaseArray.descr_copy),
 )
+
+
+class W_FlatIterator(ViewArray):
+    signature = signature.BaseSignature()
+
+    @jit.unroll_safe
+    def __init__(self, arr):
+        size = 1
+        for sh in arr.shape:
+            size *= sh
+        new_sig = signature.Signature.find_sig([
+            W_FlatIterator.signature, arr.signature
+        ])
+        ViewArray.__init__(self, arr, new_sig, [arr.strides[-1]],
+                           [arr.backstrides[-1]], [size])
+        self.shapelen = len(arr.shape)
+        self.arr = arr
+        self.iter = self.start_iter()
+
+    def start_iter(self, res_shape=None):
+        if res_shape is not None and res_shape != self.shape:
+            return BroadcastIterator(self, res_shape)
+        return OneDimIterator(self.arr.start, self.strides[0],
+                              self.shape[0])
+
+    def find_dtype(self):
+        return self.arr.find_dtype()
+
+    def find_size(self):
+        return self.shape[0]
+
+    def descr_next(self, space):
+        if self.iter.done():
+            raise OperationError(space.w_StopIteration, space.wrap(''))
+        result = self.eval(self.iter)
+        self.iter = self.iter.next(self.shapelen)
+        return result.wrap(space)
+
+    def descr_iter(self):
+        return self
+
+    def debug_repr(self):
+        return 'FlatIter(%s)' % self.arr.debug_repr()
+
+
+W_FlatIterator.typedef = TypeDef(
+    'flatiter',
+    next = interp2app(W_FlatIterator.descr_next),
+    __iter__ = interp2app(W_FlatIterator.descr_iter),
+)
+W_FlatIterator.acceptable_as_base_class = False
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -319,6 +319,8 @@
             ("floor", "floor", 1, {"promote_to_float": True}),
             ("exp", "exp", 1, {"promote_to_float": True}),
 
+            ('sqrt', 'sqrt', 1, {'promote_to_float': True}),
+
             ("sin", "sin", 1, {"promote_to_float": True}),
             ("cos", "cos", 1, {"promote_to_float": True}),
             ("tan", "tan", 1, {"promote_to_float": True}),
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -40,13 +40,15 @@
         return Signature._known_sigs.setdefault(components, Signature(components))
 
 class Call1(BaseSignature):
-    _immutable_fields_ = ["func"]
+    _immutable_fields_ = ["func", "name"]
 
     def __init__(self, func):
         self.func = func
+        self.name = func.func_name
 
 class Call2(BaseSignature):
-    _immutable_fields_ = ["func"]
+    _immutable_fields_ = ["func", "name"]
 
     def __init__(self, func):
         self.func = func
+        self.name = func.func_name
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -177,6 +177,27 @@
         """)
         assert interp.results[0].value.val == 6
 
+    def test_setslice(self):
+        interp = self.run("""
+        a = |30|
+        b = |10|
+        b[1] = 5
+        a[::3] = b
+        a -> 3
+        """)
+        assert interp.results[0].value.val == 5
+
+
+    def test_slice2(self):
+        interp = self.run("""
+        a = |30|
+        s1 = a -> 0:20:2
+        s2 = a -> 0:30:3
+        b = s1 + s2
+        b -> 3
+        """)
+        assert interp.results[0].value.val == 15
+
     def test_multidim_getitem(self):
         interp = self.run("""
         a = [[1,2]]
@@ -191,3 +212,23 @@
         b -> 1 -> 1
         """)
         assert interp.results[0].value.val == 8
+
+    def test_set_slice(self):
+        interp = self.run("""
+        a = |30|
+        b = |30|
+        b[:] = a + a
+        b -> 3
+        """)
+        assert interp.results[0].value.val == 6
+
+    def test_set_slice2(self):
+        interp = self.run("""
+        a = |30|
+        b = |10|
+        b[1] = 5.5
+        c = b + b
+        a[0:30:3] = c
+        a -> 3
+        """)
+        assert interp.results[0].value.val == 11        
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -6,11 +6,14 @@
 from pypy.interpreter.error import OperationError
 from pypy.conftest import gettestobjspace
 
+
 class MockDtype(object):
     signature = signature.BaseSignature()
+
     def malloc(self, size):
         return None
 
+
 class TestNumArrayDirect(object):
     def newslice(self, *args):
         return self.space.newslice(*[self.space.wrap(arg) for arg in args])
@@ -150,8 +153,11 @@
         assert shape_agreement(self.space, [1, 2, 3], [1, 2, 3]) == [1, 2, 3]
         py.test.raises(OperationError, shape_agreement, self.space, [2], [3])
         assert shape_agreement(self.space, [4, 4], []) == [4, 4]
-        assert shape_agreement(self.space, [8, 1, 6, 1], [7, 1, 5]) == [8, 7, 6, 5]
-        assert shape_agreement(self.space, [5, 2], [4, 3, 5, 2]) == [4, 3, 5, 2]
+        assert shape_agreement(self.space,
+                [8, 1, 6, 1], [7, 1, 5]) == [8, 7, 6, 5]
+        assert shape_agreement(self.space,
+                [5, 2], [4, 3, 5, 2]) == [4, 3, 5, 2]
+
 
 class AppTestNumArray(BaseNumpyAppTest):
     def test_type(self):
@@ -170,8 +176,7 @@
 
     def test_size(self):
         from numpypy import array
-        # XXX fixed on multidim branch
-        #assert array(3).size == 1
+        assert array(3).size == 1
         a = array([1, 2, 3])
         assert a.size == 3
         assert (a + a).size == 3
@@ -204,13 +209,13 @@
         a[3] = 22
         assert b[3] == 3
 
+        a = array(1)
+        assert a.copy() == a
+
     def test_iterator_init(self):
         from numpypy import array
         a = array(range(5))
         assert a[3] == 3
-        a = array(1)
-        assert a[0] == 1
-        assert a.shape == ()
 
     def test_getitem(self):
         from numpypy import array
@@ -258,7 +263,7 @@
         assert a[1] == 0.
         assert a[3] == 1.
         b[::-1] = b
-        assert b[0] == 1.
+        assert b[0] == 0.
         assert b[1] == 0.
 
     def test_setslice_of_slice_array(self):
@@ -296,9 +301,13 @@
         assert a[3] == 0.
 
     def test_scalar(self):
-        from numpypy import array
+        from numpypy import array, dtype
         a = array(3)
-        assert a[0] == 3
+        #assert a[0] == 3
+        raises(IndexError, "a[0]")
+        assert a.size == 1
+        assert a.shape == ()
+        assert a.dtype is dtype(int)
 
     def test_len(self):
         from numpypy import array
@@ -455,9 +464,11 @@
         a = array(range(5), float)
         b = a ** a
         for i in range(5):
-            print b[i], i ** i
             assert b[i] == i ** i
 
+        a = array(range(5))
+        assert (a ** 2 == a * a).all()
+
     def test_pow_other(self):
         from numpypy import array
         a = array(range(5), float)
@@ -681,12 +692,14 @@
         assert c.any() == False
 
     def test_dot(self):
-        from numpypy import array
+        from numpypy import array, dot
         a = array(range(5))
         assert a.dot(a) == 30.0
 
         a = array(range(5))
         assert a.dot(range(5)) == 30
+        assert dot(range(5), range(5)) == 30
+        assert (dot(5, [1, 2, 3]) == [5, 10, 15]).all()
 
     def test_dot_constant(self):
         from numpypy import array
@@ -737,6 +750,29 @@
         assert bool(array([1]))
         assert not bool(array([0]))
 
+    def test_slice_assignment(self):
+        from numpypy import array
+        a = array(range(5))
+        a[::-1] = a
+        assert (a == [0, 1, 2, 1, 0]).all()
+        # but we force intermediates
+        a = array(range(5))
+        a[::-1] = a + a
+        assert (a == [8, 6, 4, 2, 0]).all()
+
+    def test_debug_repr(self):
+        from numpypy import zeros, sin
+        a = zeros(1)
+        assert a.__debug_repr__() == 'Array'
+        assert (a + a).__debug_repr__() == 'Call2(add, Array, Array)'
+        assert (a[::2]).__debug_repr__() == 'Slice(Array)'
+        assert (a + 2).__debug_repr__() == 'Call2(add, Array, Scalar)'
+        assert (a + a.flat).__debug_repr__() == 'Call2(add, Array, FlatIter(Array))'
+        assert sin(a).__debug_repr__() == 'Call1(sin, Array)'
+        b = a + a
+        b[0] = 3
+        assert b.__debug_repr__() == 'Call2(add, forced=Array)'
+
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
         import numpypy
@@ -829,7 +865,8 @@
     def test_ufunc(self):
         from numpypy import array
         a = array([[1, 2], [3, 4], [5, 6]])
-        assert ((a + a) == array([[1 + 1, 2 + 2], [3 + 3, 4 + 4], [5 + 5, 6 + 6]])).all()
+        assert ((a + a) == \
+            array([[1 + 1, 2 + 2], [3 + 3, 4 + 4], [5 + 5, 6 + 6]])).all()
 
     def test_getitem_add(self):
         from numpypy import array
@@ -844,7 +881,8 @@
 
     def test_getitem_3(self):
         from numpypy import array
-        a = array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]])
+        a = array([[1, 2], [3, 4], [5, 6], [7, 8],
+                   [9, 10], [11, 12], [13, 14]])
         b = a[::2]
         print a
         print b
@@ -877,11 +915,12 @@
         b = array(((10, 11, 12), (20, 21, 22), (30, 31, 32)))
         c = ((a + b) == [b, b, b])
         assert c.all()
-        a = array((((10,11,12), ), ((20, 21, 22), ), ((30,31,32), )))
+        a = array((((10, 11, 12), ), ((20, 21, 22), ), ((30, 31, 32), )))
         assert(a.shape == (3, 1, 3))
         d = zeros((3, 3))
         c = ((a + d) == [b, b, b])
-        c = ((a + d) == array([[[10., 11., 12.]]*3, [[20.,21.,22.]]*3, [[30.,31.,32.]]*3]))
+        c = ((a + d) == array([[[10., 11., 12.]] * 3,
+                               [[20., 21., 22.]] * 3, [[30., 31., 32.]] * 3]))
         assert c.all()
 
     def test_broadcast_scalar(self):
@@ -906,14 +945,15 @@
         from numpypy import array
         a = array([[1, 2], [3, 4], [5, 6]])
         assert a.argmax() == 5
-        assert a[:2,].argmax() == 3
+        assert a[:2, ].argmax() == 3
 
     def test_broadcast_wrong_shapes(self):
         from numpypy import zeros
         a = zeros((4, 3, 2))
         b = zeros((4, 2))
         exc = raises(ValueError, lambda: a + b)
-        assert str(exc.value) == "operands could not be broadcast together with shapes (4,3,2) (4,2)"
+        assert str(exc.value) == "operands could not be broadcast" \
+            " together with shapes (4,3,2) (4,2)"
 
     def test_reduce(self):
         from numpypy import array
@@ -923,6 +963,51 @@
         c = b + b
         assert c.sum() == (6 + 8 + 10 + 12) * 2
 
+    def test_transpose(self):
+        from numpypy import array
+        a = array(((range(3), range(3, 6)),
+                   (range(6, 9), range(9, 12)),
+                   (range(12, 15), range(15, 18)),
+                   (range(18, 21), range(21, 24))))
+        assert a.shape == (4, 2, 3)
+        b = a.T
+        assert b.shape == (3, 2, 4)
+        assert(b[0, :, 0] == [0, 3]).all()
+        b[:, 0, 0] = 1000
+        assert(a[0, 0, :] == [1000, 1000, 1000]).all()
+        a = array(range(5))
+        b = a.T
+        assert(b == range(5)).all()
+        a = array((range(10), range(20, 30)))
+        b = a.T
+        assert(b[:, 0] == a[0, :]).all()
+
+    def test_flatiter(self):
+        from numpypy import array, flatiter
+        a = array([[10, 30], [40, 60]])
+        f_iter = a.flat
+        assert f_iter.next() == 10
+        assert f_iter.next() == 30
+        assert f_iter.next() == 40
+        assert f_iter.next() == 60
+        raises(StopIteration, "f_iter.next()")
+        raises(TypeError, "flatiter()")
+        s = 0
+        for k in a.flat:
+            s += k
+        assert s == 140
+
+    def test_flatiter_array_conv(self):
+        from numpypy import array, dot
+        a = array([1, 2, 3])
+        assert dot(a.flat, a.flat) == 14
+
+    def test_slice_copy(self):
+        from numpypy import zeros
+        a = zeros((10, 10))
+        b = a[0].copy()
+        assert (b == zeros(10)).all()
+
 class AppTestSupport(object):
     def setup_class(cls):
         import struct
@@ -936,6 +1021,7 @@
             assert a[i] == i + 1
         raises(ValueError, fromstring, "abc")
 
+
 class AppTestRepr(BaseNumpyAppTest):
     def test_repr(self):
         from numpypy import array, zeros
@@ -1008,7 +1094,9 @@
         assert str(a) == "3"
 
         a = zeros((400, 400), dtype=int)
-        assert str(a) == "[[0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n ..., \n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]]"
+        assert str(a) == "[[0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]\n" \
+           " [0 0 0 ..., 0 0 0]\n ..., \n [0 0 0 ..., 0 0 0]\n" \
+           " [0 0 0 ..., 0 0 0]\n [0 0 0 ..., 0 0 0]]"
         a = zeros((2, 2, 2))
         r = str(a)
         assert r == '[[[0.0 0.0]\n  [0.0 0.0]]\n\n [[0.0 0.0]\n  [0.0 0.0]]]'
@@ -1026,3 +1114,25 @@
         assert str(b) == "[7 8 9]"
         b = a[2:1, ]
         assert str(b) == "[]"
+
+
+class AppTestRanges(BaseNumpyAppTest):
+    def test_arange(self):
+        from numpypy import arange, array, dtype
+        a = arange(3)
+        assert (a == [0, 1, 2]).all()
+        assert a.dtype is dtype(int)
+        a = arange(3.0)
+        assert (a == [0., 1., 2.]).all()
+        assert a.dtype is dtype(float)
+        a = arange(3, 7)
+        assert (a == [3, 4, 5, 6]).all()
+        assert a.dtype is dtype(int)
+        a = arange(3, 7, 2)
+        assert (a == [3, 5]).all()
+        a = arange(3, dtype=float)
+        assert (a == [0., 1., 2.]).all()
+        assert a.dtype is dtype(float)
+        a = arange(0, 0.8, 0.1)
+        assert len(a) == 8
+        assert arange(False, True, True).dtype is dtype(int)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -111,6 +111,8 @@
         for i in range(3):
             assert c[i] == a[i] / b[i]
 
+        assert (divide(array([-10]), array([2])) == array([-5])).all()
+
     def test_fabs(self):
         from numpypy import array, fabs
         from math import fabs as math_fabs
@@ -319,6 +321,17 @@
         for v in [1.0, -1.0]:
             assert arctanh(v) == math.copysign(float("inf"), v)
 
+    def test_sqrt(self):
+        import math
+        from numpypy import sqrt
+
+        nan, inf = float("nan"), float("inf")
+        data = [1, 2, 3, inf]
+        results = [math.sqrt(1), math.sqrt(2), math.sqrt(3), inf]
+        assert (sqrt(data) == results).all()
+        assert math.isnan(sqrt(-1))
+        assert math.isnan(sqrt(nan))
+
     def test_reduce_errors(self):
         from numpypy import sin, add
 
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -11,7 +11,8 @@
 from pypy.module.micronumpy import interp_ufuncs, signature
 from pypy.module.micronumpy.compile import (numpy_compile, FakeSpace,
     FloatObject, IntObject, BoolObject, Parser, InterpreterState)
-from pypy.module.micronumpy.interp_numarray import NDimArray, NDimSlice
+from pypy.module.micronumpy.interp_numarray import NDimArray, NDimSlice,\
+     BaseArray
 from pypy.rlib.nonconst import NonConstant
 from pypy.rpython.annlowlevel import llstr, hlstr
 
@@ -48,6 +49,7 @@
             interp = InterpreterState(codes[i])
             interp.run(space)
             res = interp.results[-1]
+            assert isinstance(res, BaseArray)
             w_res = res.eval(res.start_iter()).wrap(interp.space)
             if isinstance(w_res, BoolObject):
                 return float(w_res.boolval)
@@ -78,7 +80,7 @@
 
     def test_add(self):
         result = self.run("add")
-        self.check_loops({'getarrayitem_raw': 2, 'float_add': 1,
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add': 1,
                           'setarrayitem_raw': 1, 'int_add': 3,
                           'int_ge': 1, 'guard_false': 1, 'jump': 1})
         assert result == 3 + 3
@@ -92,7 +94,7 @@
     def test_floatadd(self):
         result = self.run("float_add")
         assert result == 3 + 3
-        self.check_loops({"getarrayitem_raw": 1, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 1, "float_add": 1,
                           "setarrayitem_raw": 1, "int_add": 2,
                           "int_ge": 1, "guard_false": 1, "jump": 1})
 
@@ -106,7 +108,7 @@
     def test_sum(self):
         result = self.run("sum")
         assert result == 2 * sum(range(30))
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 2,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 2,
                           "int_add": 2,
                           "int_ge": 1, "guard_false": 1, "jump": 1})
 
@@ -123,7 +125,7 @@
         for i in range(30):
             expected *= i * 2
         assert result == expected
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
                           "float_mul": 1, "int_add": 2,
                           "int_ge": 1, "guard_false": 1, "jump": 1})
 
@@ -136,7 +138,7 @@
         max(b)
         """)
         assert result == 256
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
                           "float_mul": 1, "int_add": 1,
                           "int_lt": 1, "guard_true": 1, "jump": 1})
 
@@ -149,7 +151,7 @@
         min(b)
         """)
         assert result == -24
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
                           "float_mul": 1, "int_add": 1,
                           "int_lt": 1, "guard_true": 1, "jump": 1})
 
@@ -164,7 +166,7 @@
     def test_any(self):
         result = self.run("any")
         assert result == 1
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1,
                           "float_ne": 1, "int_add": 2,
                           "int_ge": 1, "jump": 1,
                           "guard_false": 2})
@@ -184,9 +186,13 @@
         # This is the sum of the ops for both loops, however if you remove the
         # optimization then you end up with 2 float_adds, so we can still be
         # sure it was optimized correctly.
-        self.check_loops({"getarrayitem_raw": 2, "float_mul": 1, "float_add": 1,
-                           "setarrayitem_raw": 2, "int_add": 4,
-                           "int_ge": 2, "guard_false": 2, "jump": 2})
+        # XXX the comment above is wrong now.  We need preferrably a way to
+        # count the two loops separately
+        self.check_resops({'setarrayitem_raw': 4, 'guard_nonnull': 1, 'getfield_gc': 35,
+                           'guard_class': 22, 'int_add': 8, 'float_mul': 2,
+                           'guard_isnull': 2, 'jump': 4, 'int_ge': 4,
+                           'getarrayitem_raw': 4, 'float_add': 2, 'guard_false': 4,
+                           'guard_value': 2})
 
     def define_ufunc():
         return """
@@ -199,7 +205,7 @@
     def test_ufunc(self):
         result = self.run("ufunc")
         assert result == -6
-        self.check_loops({"getarrayitem_raw": 2, "float_add": 1, "float_neg": 1,
+        self.check_simple_loop({"getarrayitem_raw": 2, "float_add": 1, "float_neg": 1,
                           "setarrayitem_raw": 1, "int_add": 3,
                           "int_ge": 1, "guard_false": 1, "jump": 1,
         })
@@ -240,10 +246,28 @@
     def test_slice(self):
         result = self.run("slice")
         assert result == 18
-        py.test.skip("Few remaining arraylen_gc left")
-        self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1,
-                          'setarrayitem_raw': 1, 'int_add': 3,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        self.check_simple_loop({'getarrayitem_raw': 2,
+                                'float_add': 1,
+                                'setarrayitem_raw': 1,
+                                'int_add': 3,
+                                'int_ge': 1, 'guard_false': 1,
+                                'jump': 1})
+
+    def define_slice2():
+        return """
+        a = |30|
+        s1 = a -> :20:2
+        s2 = a -> :30:3
+        b = s1 + s2
+        b -> 3
+        """
+
+    def test_slice2(self):
+        result = self.run("slice2")
+        assert result == 15
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add': 1,
+                                'setarrayitem_raw': 1, 'int_add': 3,
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1})
 
     def define_multidim():
         return """
@@ -255,7 +279,7 @@
     def test_multidim(self):
         result = self.run('multidim')
         assert result == 8
-        self.check_loops({'float_add': 1, 'getarrayitem_raw': 2,
+        self.check_simple_loop({'float_add': 1, 'getarrayitem_raw': 2,
                           'guard_false': 1, 'int_add': 3, 'int_ge': 1,
                           'jump': 1, 'setarrayitem_raw': 1})
         # int_add might be 1 here if we try slightly harder with
@@ -275,7 +299,7 @@
         py.test.skip("improve")
         # XXX the bridge here is scary. Hopefully jit-targets will fix that,
         #     otherwise it looks kind of good
-        self.check_loops({})
+        self.check_simple_loop({})
 
     def define_broadcast():
         return """
@@ -289,7 +313,25 @@
         result = self.run("broadcast")
         assert result == 10
         py.test.skip("improve")
-        self.check_loops({})
+        self.check_simple_loop({})
+
+    def define_setslice():
+        return """
+        a = |30|
+        b = |10|
+        b[1] = 5.5
+        c = b + b
+        a[0:30:3] = c
+        a -> 3
+        """
+
+    def test_setslice(self):
+        result = self.run("setslice")
+        assert result == 11.0
+        self.check_loop_count(1)
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add' : 1,
+                                'setarrayitem_raw': 1, 'int_add': 3,
+                                'int_eq': 1, 'guard_false': 1, 'jump': 1})
 
 class TestNumpyOld(LLJitMixin):
     def setup_class(cls):
@@ -300,48 +342,6 @@
         cls.space = FakeSpace()
         cls.float64_dtype = cls.space.fromcache(W_Float64Dtype)
 
-    def test_slice2(self):
-        def f(i):
-            step1 = 2
-            step2 = 3
-            ar = NDimArray(step2*i, dtype=self.float64_dtype)
-            new_sig = signature.Signature.find_sig([
-                NDimSlice.signature, ar.signature
-            ])
-            s1 = NDimSlice(0, step1*i, step1, i, ar, new_sig)
-            new_sig = signature.Signature.find_sig([
-                NDimSlice.signature, s1.signature
-            ])
-            s2 = NDimSlice(0, step2*i, step2, i, ar, new_sig)
-            v = interp_ufuncs.get(self.space).add.call(self.space, [s1, s2])
-            return v.get_concrete().eval(3).val
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'int_mul': 2, 'getarrayitem_raw': 2, 'float_add': 1,
-                          'setarrayitem_raw': 1, 'int_add': 1,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
-        assert result == f(5)
-
-    def test_setslice(self):
-        space = self.space
-        float64_dtype = self.float64_dtype
-
-        def f(i):
-            step = NonConstant(3)
-            ar = NDimArray(step*i, dtype=float64_dtype)
-            ar2 = NDimArray(i, dtype=float64_dtype)
-            ar2.get_concrete().setitem(1, float64_dtype.box(5.5))
-            arg = ar2.descr_add(space, ar2)
-            ar.setslice(space, 0, step*i, step, i, arg)
-            return ar.get_concrete().eval(3).val
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'getarrayitem_raw': 2,
-                          'float_add' : 1,
-                          'setarrayitem_raw': 1, 'int_add': 2,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
-        assert result == 11.0
-
     def test_int32_sum(self):
         py.test.skip("pypy/jit/backend/llimpl.py needs to be changed to "
                      "deal correctly with int dtypes for this test to "
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -3,7 +3,7 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
 from pypy.rlib import rmmap
-from pypy.rlib.rmmap import RValueError, RTypeError, ROverflowError
+from pypy.rlib.rmmap import RValueError, RTypeError
 
 
 class W_MMap(Wrappable):
@@ -212,8 +212,6 @@
             raise OperationError(space.w_ValueError, space.wrap(e.message))
         except RTypeError, e:
             raise OperationError(space.w_TypeError, space.wrap(e.message))
-        except ROverflowError, e:
-            raise OperationError(space.w_OverflowError, space.wrap(e.message))
         return space.wrap(self)
 
 elif rmmap._MS_WINDOWS:
@@ -233,8 +231,6 @@
             raise OperationError(space.w_ValueError, space.wrap(e.message))
         except RTypeError, e:
             raise OperationError(space.w_TypeError, space.wrap(e.message))
-        except ROverflowError, e:
-            raise OperationError(space.w_OverflowError, space.wrap(e.message))
         return space.wrap(self)
 
 W_MMap.typedef = TypeDef("mmap",
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
@@ -33,8 +33,12 @@
             i24 = int_ge(i19, i12)
             guard_false(i24, descr=...)
             i25 = unicodegetitem(p13, i19)
-            i26 = int_eq(i23, i25)
-            guard_true(i26, descr=...)
+            p27 = newstr(1)
+            strsetitem(p27, 0, i23)
+            p30 = call(ConstClass(ll_str2unicode__rpy_stringPtr), p27, descr=...)
+            guard_no_exception(descr=...)
+            i32 = call(ConstClass(_ll_2_str_eq_checknull_char__rpy_unicodePtr_UniChar), p30, i25, descr=...)
+            guard_true(i32, descr=...)
             i34 = int_add(i6, 1)
             --TICK--
             jump(p0, p1, p2, p3, p4, p5, i34, p7, p8, i9, i10, p11, i12, p13, descr=...)
diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -3,7 +3,7 @@
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.rpython.lltypesystem import lltype
-from pypy.rlib.rarithmetic import ovfcheck_float_to_int
+from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask
 from pypy.rlib import rposix
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 import os
@@ -585,7 +585,7 @@
                 # More likely, the format yields an empty result,
                 # e.g. an empty format, or %Z when the timezone
                 # is unknown.
-                result = rffi.charp2strn(outbuf, buflen)
+                result = rffi.charp2strn(outbuf, intmask(buflen))
                 return space.wrap(result)
         finally:
             lltype.free(outbuf, flavor='raw')
diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py
--- a/pypy/objspace/flow/model.py
+++ b/pypy/objspace/flow/model.py
@@ -38,7 +38,6 @@
     def __init__(self, name, startblock, return_var=None):
         self.name        = name    # function name (possibly mangled already)
         self.startblock  = startblock
-        self.startblock.isstartblock = True
         # build default returnblock
         self.returnblock = Block([return_var or Variable()])
         self.returnblock.operations = ()
@@ -171,11 +170,10 @@
 
 
 class Block(object):
-    __slots__ = """isstartblock inputargs operations exitswitch
+    __slots__ = """inputargs operations exitswitch
                 exits blockcolor""".split()
     
     def __init__(self, inputargs):
-        self.isstartblock = False
         self.inputargs = list(inputargs)  # mixed list of variable/const XXX 
         self.operations = []              # list of SpaceOperation(s)
         self.exitswitch = None            # a variable or
@@ -452,7 +450,6 @@
         newblock.closeblock(*newlinks)
 
     newstartblock = blockmap[graph.startblock]
-    newstartblock.isstartblock = True
     newgraph = FunctionGraph(graph.name, newstartblock)
     newgraph.returnblock = blockmap[graph.returnblock]
     newgraph.exceptblock = blockmap[graph.exceptblock]
@@ -490,7 +487,6 @@
 
 
         for block in graph.iterblocks():
-            assert bool(block.isstartblock) == (block is graph.startblock)
             assert type(block.exits) is tuple, (
                 "block.exits is a %s (closeblock() or recloseblock() missing?)"
                 % (type(block.exits).__name__,))
diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py
--- a/pypy/objspace/flow/objspace.py
+++ b/pypy/objspace/flow/objspace.py
@@ -96,6 +96,12 @@
         self.executioncontext.recorder = previous_recorder
         self.concrete_mode -= 1
 
+    def is_w(self, w_one, w_two):
+        return self.is_true(self.is_(w_one, w_two))
+
+    is_ = None     # real version added by add_operations()
+    id  = None     # real version added by add_operations()
+
     def newdict(self):
         if self.concrete_mode:
             return Constant({})
diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py
--- a/pypy/objspace/flow/operation.py
+++ b/pypy/objspace/flow/operation.py
@@ -315,7 +315,7 @@
 del _add_exceptions, _add_except_ovf
 
 def make_op(fs, name, symbol, arity, specialnames):
-    if hasattr(fs, name):
+    if getattr(fs, name, None) is not None:
         return
 
     op = None
diff --git a/pypy/objspace/flow/test/test_checkgraph.py b/pypy/objspace/flow/test/test_checkgraph.py
--- a/pypy/objspace/flow/test/test_checkgraph.py
+++ b/pypy/objspace/flow/test/test_checkgraph.py
@@ -13,20 +13,6 @@
     py.test.raises(AssertionError, checkgraph, g)
 
 
-def test_nostartblock():
-    g = FunctionGraph("g", Block([]))
-    g.startblock.closeblock(Link([Constant(1)], g.returnblock))
-    g.startblock.isstartblock = False
-    py.test.raises(AssertionError, checkgraph, g)
-
-def test_twostartblocks():
-    g = FunctionGraph("g", Block([]))
-    b = Block([])
-    b.isstartblock = True
-    g.startblock.closeblock(Link([], b))
-    b.closeblock(Link([Constant(1)], g.returnblock))
-    py.test.raises(AssertionError, checkgraph, g)
-
 def test_exitlessblocknotexitblock():
     g = FunctionGraph("g", Block([]))
     py.test.raises(AssertionError, checkgraph, g)
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -31,9 +31,9 @@
         imag2 = float2longlong(imag2)
         return real1 == real2 and imag1 == imag2
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         from pypy.rlib.longlong2float import float2longlong
         from pypy.objspace.std.model import IDTAG_COMPLEX as tag
         real = space.float_w(space.getattr(self, space.wrap("real")))
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -34,9 +34,9 @@
         two = float2longlong(space.float_w(w_other))
         return one == two
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         from pypy.rlib.longlong2float import float2longlong
         from pypy.objspace.std.model import IDTAG_FLOAT as tag
         val = float2longlong(space.float_w(self))
diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py
--- a/pypy/objspace/std/frame.py
+++ b/pypy/objspace/std/frame.py
@@ -3,13 +3,11 @@
 import operator
 
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.interpreter import pyopcode, function
+from pypy.interpreter import pyopcode
 from pypy.interpreter.pyframe import PyFrame
-from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.module.__builtin__ import Module
+from pypy.interpreter.error import OperationError
 from pypy.objspace.std import intobject, smallintobject
 from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
 from pypy.objspace.std.listobject import W_ListObject
 
 
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -26,9 +26,9 @@
             return self is w_other
         return space.int_w(self) == space.int_w(w_other)
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         from pypy.objspace.std.model import IDTAG_INT as tag
         b = space.bigint_w(self)
         b = b.lshift(3).or_(rbigint.fromint(tag))
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -50,6 +50,13 @@
     else:
         return space.fromcache(StringListStrategy)
 
+    # check for floats
+    for w_obj in list_w:
+        if not is_W_FloatObject(w_obj):
+            break
+    else:
+        return space.fromcache(FloatListStrategy)
+
     return space.fromcache(ObjectListStrategy)
 
 def is_W_IntObject(w_object):
@@ -60,7 +67,9 @@
     from pypy.objspace.std.stringobject import W_StringObject
     return type(w_object) is W_StringObject
 
-
+def is_W_FloatObject(w_object):
+    from pypy.objspace.std.floatobject import W_FloatObject
+    return type(w_object) is W_FloatObject
 
 class W_ListObject(W_AbstractListObject):
     from pypy.objspace.std.listtype import list_typedef as typedef
@@ -364,6 +373,8 @@
             strategy = self.space.fromcache(IntegerListStrategy)
         elif is_W_StringObject(w_item):
             strategy = self.space.fromcache(StringListStrategy)
+        elif is_W_FloatObject(w_item):
+            strategy = self.space.fromcache(FloatListStrategy)
         else:
             strategy = self.space.fromcache(ObjectListStrategy)
 
@@ -905,6 +916,32 @@
         if reverse:
             l.reverse()
 
+class FloatListStrategy(AbstractUnwrappedStrategy, ListStrategy):
+    _none_value = 0.0
+
+    def wrap(self, floatval):
+        return self.space.wrap(floatval)
+
+    def unwrap(self, w_float):
+        return self.space.float_w(w_float)
+
+    erase, unerase = rerased.new_erasing_pair("float")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def is_correct_type(self, w_obj):
+        return is_W_FloatObject(w_obj)
+
+    def list_is_correct_type(self, w_list):
+        return w_list.strategy is self.space.fromcache(FloatListStrategy)
+
+    def sort(self, w_list, reverse):
+        l = self.unerase(w_list.lstorage)
+        sorter = FloatSort(l, len(l))
+        sorter.sort()
+        if reverse:
+            l.reverse()
+
 class StringListStrategy(AbstractUnwrappedStrategy, ListStrategy):
     _none_value = None
 
@@ -934,6 +971,7 @@
     def getitems_str(self, w_list):
         return self.unerase(w_list.lstorage)
 
+
 # _______________________________________________________
 
 init_signature = Signature(['sequence'], None, None)
@@ -1282,6 +1320,7 @@
 
 TimSort = make_timsort_class()
 IntBaseTimSort = make_timsort_class()
+FloatBaseTimSort = make_timsort_class()
 StringBaseTimSort = make_timsort_class()
 
 class KeyContainer(baseobjspace.W_Root):
@@ -1302,6 +1341,10 @@
     def lt(self, a, b):
         return a < b
 
+class FloatSort(FloatBaseTimSort):
+    def lt(self, a, b):
+        return a < b
+
 class StringSort(StringBaseTimSort):
     def lt(self, a, b):
         return a < b
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -18,9 +18,9 @@
             return self is w_other
         return space.bigint_w(self).eq(space.bigint_w(w_other))
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         from pypy.objspace.std.model import IDTAG_LONG as tag
         b = space.bigint_w(self)
         b = b.lshift(3).or_(rbigint.fromint(tag))
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -453,12 +453,12 @@
     multi = r_uint(1822399083) + r_uint(1822399083) + 1
     if w_set.hash != 0:
         return space.wrap(w_set.hash)
-    hash = 1927868237
-    hash *= (len(w_set.setdata) + 1)
+    hash = r_uint(1927868237)
+    hash *= r_uint(len(w_set.setdata) + 1)
     for w_item in w_set.setdata:
         h = space.hash_w(w_item)
-        value = ((h ^ (h << 16) ^ 89869747)  * multi)
-        hash = intmask(hash ^ value)
+        value = (r_uint(h ^ (h << 16) ^ 89869747)  * multi)
+        hash = hash ^ value
     hash = hash * 69069 + 907133923
     if hash == 0:
         hash = 590923713
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -32,9 +32,9 @@
             return False
         return space.str_w(self) is space.str_w(w_other)
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         return space.wrap(compute_unique_id(space.str_w(self)))
 
 
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -1,4 +1,4 @@
-from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, StringListStrategy, RangeListStrategy, make_range_list
+from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, StringListStrategy, RangeListStrategy, make_range_list
 from pypy.objspace.std import listobject
 from pypy.objspace.std.test.test_listobject import TestW_ListObject
 
@@ -15,7 +15,7 @@
     def test_empty_to_any(self):
         l = W_ListObject(self.space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
-        l.append(self.space.wrap(1.))
+        l.append(self.space.wrap((1,3)))
         assert isinstance(l.strategy, ObjectListStrategy)
 
         l = W_ListObject(self.space, [])
@@ -28,6 +28,11 @@
         l.append(self.space.wrap('a'))
         assert isinstance(l.strategy, StringListStrategy)
 
+        l = W_ListObject(self.space, [])
+        assert isinstance(l.strategy, EmptyListStrategy)
+        l.append(self.space.wrap(1.2))
+        assert isinstance(l.strategy, FloatListStrategy)
+
     def test_int_to_any(self):
         l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
@@ -44,6 +49,14 @@
         l.append(self.space.wrap(3))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+    def test_float_to_any(self):
+        l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)])
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.append(self.space.wrap(4.4))
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.append(self.space.wrap("a"))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
     def test_setitem(self):
         # This should work if test_listobject.py passes
         l = W_ListObject(self.space, [self.space.wrap('a'),self.space.wrap('b'),self.space.wrap('c')])
@@ -65,6 +78,12 @@
         l.setitem(0, self.space.wrap(2))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+        # FloatStrategy to ObjectStrategy
+        l = W_ListObject(self.space, [self.space.wrap(1.2),self.space.wrap(2.3),self.space.wrap(3.4)])
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.setitem(0, self.space.wrap("a"))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
     def test_insert(self):
         # no change
         l = W_ListObject(self.space, [self.space.wrap(1),self.space.wrap(2),self.space.wrap(3)])
@@ -84,6 +103,12 @@
         l.insert(3, self.space.wrap('d'))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+        # FloatStrategy
+        l = W_ListObject(self.space, [self.space.wrap(1.1),self.space.wrap(2.2),self.space.wrap(3.3)])
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.insert(3, self.space.wrap('d'))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
         # EmptyStrategy
         l = W_ListObject(self.space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
@@ -95,7 +120,9 @@
         l.insert(0, self.space.wrap(2))
         assert isinstance(l.strategy, IntegerListStrategy)
 
-    def notest_list_empty_after_delete(self):
+    def test_list_empty_after_delete(self):
+        import py
+        py.test.skip("return to emptyliststrategy is not supported anymore")
         l = W_ListObject(self.space, [self.space.wrap(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
         l.deleteitem(0)
@@ -117,21 +144,36 @@
         l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
+        # IntegerStrategy to IntegerStrategy
         l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
         l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
+        # ObjectStrategy to ObjectStrategy
         l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap('b'), self.space.wrap(3)])
         assert isinstance(l.strategy, ObjectListStrategy)
         l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+        # IntegerStrategy to ObjectStrategy
         l = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
         assert isinstance(l.strategy, IntegerListStrategy)
         l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
+        # StringStrategy to ObjectStrategy
+        l = W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap('b'), self.space.wrap('c')])
+        assert isinstance(l.strategy, StringListStrategy)
+        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
+        # FloatStrategy to ObjectStrategy
+        l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)])
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.setslice(0, 1, 2, W_ListObject(self.space, [self.space.wrap('a'), self.space.wrap(2), self.space.wrap(3)]))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
     def test_setslice_List(self):
 
         def wrapitems(items):
@@ -160,6 +202,11 @@
         keep_other_strategy(l, 0, 2, other.length(), other)
         assert l.strategy is self.space.fromcache(StringListStrategy)
 
+        l = W_ListObject(self.space, wrapitems([1.1, 2.2, 3.3, 4.4, 5.5]))
+        other = W_ListObject(self.space, [])
+        keep_other_strategy(l, 0, 1, l.length(), other)
+        assert l.strategy is self.space.fromcache(FloatListStrategy)
+
         l = W_ListObject(self.space, wrapitems(["a",3,"c",4,"e"]))
         other = W_ListObject(self.space, wrapitems(["a", "b", "c"]))
         keep_other_strategy(l, 0, 2, other.length(), other)
@@ -194,6 +241,11 @@
         l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
+        l = W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)])
+        assert isinstance(l.strategy, FloatListStrategy)
+        l.extend(W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5), self.space.wrap(6)]))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
     def test_empty_extend_with_any(self):
         empty = W_ListObject(self.space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
@@ -220,6 +272,11 @@
 
         empty = W_ListObject(self.space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
+        empty.extend(W_ListObject(self.space, [self.space.wrap(1.1), self.space.wrap(2.2), self.space.wrap(3.3)]))
+        assert isinstance(empty.strategy, FloatListStrategy)
+
+        empty = W_ListObject(self.space, [])
+        assert isinstance(empty.strategy, EmptyListStrategy)
         empty.extend(W_ListObject(self.space, []))
         assert isinstance(empty.strategy, EmptyListStrategy)
 
@@ -293,12 +350,13 @@
         l.setslice(0, 1, 3, W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)]))
         assert isinstance(l.strategy, IntegerListStrategy)
 
-    def test_get_items_copy(self):
+    def test_copy_list(self):
         l1 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap(2), self.space.wrap(3)])
-        l2 = l1.getitems()
+        l2 = l1.clone()
         l2.append(self.space.wrap(4))
         assert not l2 == l1.getitems()
 
+    def test_getitems_does_not_copy_object_list(self):
         l1 = W_ListObject(self.space, [self.space.wrap(1), self.space.wrap("two"), self.space.wrap(3)])
         l2 = l1.getitems()
         l2.append(self.space.wrap("four"))
@@ -345,7 +403,6 @@
         # should not raise
         assert getslice__List_ANY_ANY(self.space, l, self.space.wrap(15), self.space.wrap(2222)).strategy == self.space.fromcache(EmptyListStrategy)
 
-
     def test_add_to_rangelist(self):
         l1 = make_range_list(self.space, 1, 1, 3)
         l2 = W_ListObject(self.space, [self.space.wrap(4), self.space.wrap(5)])
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -32,9 +32,9 @@
             return False
         return space.unicode_w(self) is space.unicode_w(w_other)
 
-    def id(self, space):
+    def unique_id(self, space):
         if self.user_overridden_class:
-            return W_Object.id(self, space)
+            return W_Object.unique_id(self, space)
         return space.wrap(compute_unique_id(space.unicode_w(self)))
 
 
diff --git a/pypy/rlib/_stacklet_n_a.py b/pypy/rlib/_stacklet_n_a.py
--- a/pypy/rlib/_stacklet_n_a.py
+++ b/pypy/rlib/_stacklet_n_a.py
@@ -1,4 +1,5 @@
 from pypy.rlib import _rffi_stacklet as _c
+from pypy.rlib import objectmodel, debug
 from pypy.rpython.annlowlevel import llhelper
 from pypy.tool.staticmethods import StaticMethods
 
@@ -21,6 +22,9 @@
 
     def destroy(thrd, h):
         _c.destroy(thrd._thrd, h)
+        if objectmodel.we_are_translated():
+            debug.debug_print("not using a framework GC: "
+                              "stacklet_destroy() may leak")
 
     is_empty_handle = _c.is_empty_handle
 
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -176,7 +176,6 @@
     return decorator
 
 @oopspec("jit.isconstant(value)")
- at specialize.ll()
 def isconstant(value):
     """
     While tracing, returns whether or not the value is currently known to be
@@ -186,9 +185,9 @@
     This is for advanced usage only.
     """
     return NonConstant(False)
+isconstant._annspecialcase_ = "specialize:call_location"
 
 @oopspec("jit.isvirtual(value)")
- at specialize.ll()
 def isvirtual(value):
     """
     Returns if this value is virtual, while tracing, it's relatively
@@ -197,6 +196,7 @@
     This is for advanced usage only.
     """
     return NonConstant(False)
+isvirtual._annspecialcase_ = "specialize:call_location"
 
 class Entry(ExtRegistryEntry):
     _about_ = hint
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -143,7 +143,9 @@
         return self_type
     if self_type in (bool, int, long):
         return other_type
-    return build_int(None, self_type.SIGNED and other_type.SIGNED, max(self_type.BITS, other_type.BITS))
+    if self_type.SIGNED == other_type.SIGNED:
+        return build_int(None, self_type.SIGNED, max(self_type.BITS, other_type.BITS))
+    raise AssertionError, "Merging these types (%s, %s) is not supported" % (self_type, other_type)
 
 def signedtype(t):
     if t in (bool, int, long):
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -229,7 +229,7 @@
         sign = self.sign
         if intmask(x) < 0 and (sign > 0 or (x << 1) != 0):
             raise OverflowError
-        return intmask(x * sign)
+        return intmask(intmask(x) * sign)
 
     def tolonglong(self):
         return _AsLongLong(self)
@@ -1384,7 +1384,7 @@
 
     # Now remove the excess 2 bits, rounding to nearest integer (with
     # ties rounded to even).
-    q = (q >> 2) + (bool(q & 2) and bool(q & 5))
+    q = (q >> 2) + r_uint((bool(q & 2) and bool(q & 5)))
 
     if exp > DBL_MAX_EXP or (exp == DBL_MAX_EXP and
                              q == r_ulonglong(1) << DBL_MANT_DIG):
@@ -1540,8 +1540,8 @@
     assert extra_bits == 2 or extra_bits == 3
 
     # Round by remembering a modified copy of the low digit of x
-    mask = 1 << (extra_bits - 1)
-    low = x.udigit(0) | inexact
+    mask = r_uint(1 << (extra_bits - 1))
+    low = x.udigit(0) | r_uint(inexact)
     if (low & mask) != 0 and (low & (3*mask-1)) != 0:
         low += mask
     x_digit_0 = low & ~(mask-1)
@@ -1790,7 +1790,7 @@
     i = v.numdigits() - 1
     while i >= 0:
         prev = x
-        x = (x << SHIFT) + v.widedigit(i)
+        x = (x << SHIFT) + r_ulonglong(v.widedigit(i))
         if (x >> SHIFT) != prev:
                 raise OverflowError(
                     "long int too large to convert to unsigned long long int")
@@ -1833,8 +1833,8 @@
         if x < v.udigit(i):
             x += 1
         i -= 1
-    x = intmask(x * sign)
-    return x
+    res = intmask(intmask(x) * sign)
+    return res
 
 #_________________________________________________________________
 
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -23,10 +23,6 @@
     def __init__(self, message):
         self.message = message
 
-class ROverflowError(Exception):
-    def __init__(self, message):
-        self.message = message
-
 includes = ["sys/types.h"]
 if _POSIX:
     includes += ['unistd.h', 'sys/mman.h']
@@ -597,8 +593,6 @@
 def _check_map_size(size):
     if size < 0:
         raise RTypeError("memory mapped size must be positive")
-    if rffi.cast(size_t, size) != size:
-        raise ROverflowError("memory mapped size is too large (limited by C int)")
 
 if _POSIX:
     def mmap(fileno, length, flags=MAP_SHARED,
diff --git a/pypy/rlib/rrandom.py b/pypy/rlib/rrandom.py
--- a/pypy/rlib/rrandom.py
+++ b/pypy/rlib/rrandom.py
@@ -31,7 +31,7 @@
         mt[0]= s & MASK_32
         for mti in range(1, N):
             mt[mti] = (MAGIC_CONSTANT_A *
-                           (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti)
+                           (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + r_uint(mti))
             # See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
             # In the previous versions, MSBs of the seed affect
             # only MSBs of the array mt[].
@@ -52,7 +52,7 @@
         for k in range(max_k, 0, -1):
             mt[i] = ((mt[i] ^
                          ((mt[i - 1] ^ (mt[i - 1] >> 30)) * MAGIC_CONSTANT_C))
-                     + init_key[j] + j) # non linear
+                     + init_key[j] + r_uint(j)) # non linear
             mt[i] &= MASK_32 # for WORDSIZE > 32 machines
             i += 1
             j += 1
@@ -104,5 +104,5 @@
             j = n % i
             mt[i], mt[j] = mt[j], mt[i]
         for i in range(N):
-            mt[i] += i + 1
+            mt[i] += r_uint(i + 1)
         self.index = N
diff --git a/pypy/rlib/rsocket.py b/pypy/rlib/rsocket.py
--- a/pypy/rlib/rsocket.py
+++ b/pypy/rlib/rsocket.py
@@ -17,7 +17,7 @@
 
 from pypy.rlib.objectmodel import instantiate, keepalive_until_here
 from pypy.rlib import _rsocket_rffi as _c
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, r_uint
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rpython.lltypesystem.rffi import sizeof, offsetof
 
@@ -131,11 +131,12 @@
     from_object = staticmethod(from_object)
 
     @staticmethod
-    def _check_port(space, port):
+    def make_ushort_port(space, port):
         from pypy.interpreter.error import OperationError
         if port < 0 or port > 0xffff:
             raise OperationError(space.w_ValueError, space.wrap(
                 "port must be 0-65535."))
+        return rffi.cast(rffi.USHORT, port)
 
     def fill_from_object(self, space, w_address):
         """ Purely abstract
@@ -167,7 +168,7 @@
 
     # IPv4 also supports the special name "<broadcast>".
     if name == '<broadcast>':
-        return makeipv4addr(intmask(INADDR_BROADCAST), result)
+        return makeipv4addr(r_uint(INADDR_BROADCAST), result)
 
     # "dd.dd.dd.dd" format.
     digits = name.split('.')
@@ -184,9 +185,11 @@
                 0 <= d1 <= 255 and
                 0 <= d2 <= 255 and
                 0 <= d3 <= 255):
-                return makeipv4addr(intmask(htonl(
-                    (intmask(d0 << 24)) | (d1 << 16) | (d2 << 8) | (d3 << 0))),
-                                    result)
+
+                addr = intmask(d0 << 24) | (d1 << 16) | (d2 << 8) | (d3 << 0)
+                addr = rffi.cast(rffi.UINT, addr)
+                addr = htonl(addr)
+                return makeipv4addr(addr, result)
 
     # generic host name to IP conversion
     info = getaddrinfo(name, None, family=family, address_to_fill=result)
@@ -236,7 +239,9 @@
 
         def get_protocol(self):
             a = self.lock(_c.sockaddr_ll)
-            res = ntohs(rffi.getintfield(a, 'c_sll_protocol'))
+            proto = rffi.getintfield(a, 'c_sll_protocol')
+            proto = rffi.cast(rffi.USHORT, proto)
+            res = ntohs(proto)
             self.unlock()
             return res
 
@@ -277,6 +282,7 @@
     def __init__(self, host, port):
         makeipaddr(host, self)
         a = self.lock(_c.sockaddr_in)
+        port = rffi.cast(rffi.USHORT, port)
         rffi.setintfield(a, 'c_sin_port', htons(port))
         self.unlock()
 
@@ -309,7 +315,7 @@
             raise TypeError("AF_INET address must be a tuple of length 2")
         host = space.str_w(w_host)
         port = space.int_w(w_port)
-        Address._check_port(space, port)
+        port = Address.make_ushort_port(space, port)
         return INETAddress(host, port)
     from_object = staticmethod(from_object)
 
@@ -318,7 +324,7 @@
         from pypy.interpreter.error import OperationError
         _, w_port = space.unpackiterable(w_address, 2)
         port = space.int_w(w_port)
-        self._check_port(space, port)
+        port = self.make_ushort_port(space, port)
         a = self.lock(_c.sockaddr_in)
         rffi.setintfield(a, 'c_sin_port', htons(port))
         self.unlock()
@@ -403,7 +409,7 @@
                                "to 4, not %d" % len(pieces_w))
         host = space.str_w(pieces_w[0])
         port = space.int_w(pieces_w[1])
-        Address._check_port(space, port)
+        port = Address.make_ushort_port(space, port)
         if len(pieces_w) > 2: flowinfo = space.uint_w(pieces_w[2])
         else:                 flowinfo = 0
         if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3])
@@ -419,7 +425,7 @@
             raise RSocketError("AF_INET6 address must be a tuple of length 2 "
                                "to 4, not %d" % len(pieces_w))
         port = space.int_w(pieces_w[1])
-        self._check_port(space, port)
+        port = self.make_ushort_port(space, port)
         if len(pieces_w) > 2: flowinfo = space.uint_w(pieces_w[2])
         else:                 flowinfo = 0
         if len(pieces_w) > 3: scope_id = space.uint_w(pieces_w[3])
@@ -1295,9 +1301,13 @@
     servent = _c.getservbyname(name, proto)
     if not servent:
         raise RSocketError("service/proto not found")
-    return ntohs(servent.c_s_port)
+    port = rffi.cast(rffi.UINT, servent.c_s_port)
+    return ntohs(port)
 
 def getservbyport(port, proto=None):
+    # This function is only called from pypy/module/_socket and the range of
+    # port is checked there
+    port = rffi.cast(rffi.USHORT, port)
     servent = _c.getservbyport(htons(port), proto)
     if not servent:
         raise RSocketError("port/proto not found")
diff --git a/pypy/rlib/rsre/test/test_zjit.py b/pypy/rlib/rsre/test/test_zjit.py
--- a/pypy/rlib/rsre/test/test_zjit.py
+++ b/pypy/rlib/rsre/test/test_zjit.py
@@ -96,7 +96,7 @@
     def test_fast_search(self):
         res = self.meta_interp_search(r"<foo\w+>", "e<f<f<foxd<f<fh<foobar>ua")
         assert res == 15
-        self.check_loops(guard_value=0)
+        self.check_resops(guard_value=0)
 
     def test_regular_search(self):
         res = self.meta_interp_search(r"<\w+>", "eiofweoxdiwhdoh<foobar>ua")
@@ -120,7 +120,7 @@
     def test_aorbstar(self):
         res = self.meta_interp_match("(a|b)*a", "a" * 100)
         assert res == 100
-        self.check_loops(guard_value=0)
+        self.check_resops(guard_value=0)
 
 
     # group guards tests
@@ -165,4 +165,4 @@
     def test_find_repetition_end_fastpath(self):
         res = self.meta_interp_search(r"b+", "a"*30 + "b")
         assert res == 30
-        self.check_loops(call=0)
+        self.check_resops(call=0)
diff --git a/pypy/rlib/rstruct/standardfmttable.py b/pypy/rlib/rstruct/standardfmttable.py
--- a/pypy/rlib/rstruct/standardfmttable.py
+++ b/pypy/rlib/rstruct/standardfmttable.py
@@ -206,7 +206,7 @@
                 if signed and i == 0 and x >= 128:
                     x -= 256
                 intvalue <<= 8
-                intvalue |= x
+                intvalue |= inttype(x)
                 idx += 1
         else:
             for i in unroll_range_size:
diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py
--- a/pypy/rlib/test/test_rarithmetic.py
+++ b/pypy/rlib/test/test_rarithmetic.py
@@ -126,13 +126,18 @@
             cmp = f(r_uint(arg))
             assert res == cmp
         
-    def binary_test(self, f, rargs = None):
+    def binary_test(self, f, rargs = None, translated=False):
         mask = maxint_mask 
         if not rargs:
             rargs = (1, 3, 55)
+        # when translated merging different int types is not allowed
+        if translated:
+            alltypes = [(r_uint, r_uint)]
+        else:
+            alltypes = [(int, r_uint), (r_uint, int), (r_uint, r_uint)]
         for larg in (0, 1, 2, 3, 1234):
             for rarg in rargs:
-                for types in ((int, r_uint), (r_uint, int), (r_uint, r_uint)):
+                for types in alltypes:
                     res = f(larg, rarg)
                     left, right = types
                     cmp = f(left(larg), right(rarg))
@@ -335,6 +340,14 @@
     from pypy.rpython.lltypesystem.rffi import r_int_real
     assert compute_restype(r_int_real, r_int_real) is r_int_real
 
+def test_compute_restype_incompatible():
+    from pypy.rpython.lltypesystem.rffi import r_int_real, r_short, r_ushort
+    testcases = [(r_uint, r_longlong), (r_int_real, r_uint),
+                (r_short, r_ushort)]
+    for t1, t2 in testcases:
+        py.test.raises(AssertionError, compute_restype, t1, t2)
+        py.test.raises(AssertionError, compute_restype, t2, t1)
+
 def test_most_neg_value_of():
     assert most_neg_value_of_same_type(123) == -sys.maxint-1
     assert most_neg_value_of_same_type(r_uint(123)) == 0
diff --git a/pypy/rlib/test/test_rrandom.py b/pypy/rlib/test/test_rrandom.py
--- a/pypy/rlib/test/test_rrandom.py
+++ b/pypy/rlib/test/test_rrandom.py
@@ -1,4 +1,5 @@
 from pypy.rlib.rrandom import Random, N, r_uint
+from pypy.rlib.rarithmetic import intmask
 import _random
 
 # the numbers were created by using CPython's _randommodule.c
@@ -24,13 +25,13 @@
 
 def test_init_by_array():
     rnd = Random()
-    rnd.init_by_array([1, 2, 3, 4])
+    rnd.init_by_array([r_uint(n) for n in [1, 2, 3, 4]])
     assert rnd.state[:14] == [2147483648, 1269538435, 699006892, 381364451,
             172015551, 3237099449, 3609464087, 2187366456, 654585064,
             2665903765, 3735624613, 1241943673, 2038528247, 3774211972]
     # try arrays of various sizes to test for corner cases
     for size in [N, N - 1, N + 1, N // 2, 2 * N]:
-        rnd.init_by_array(range(N))
+        rnd.init_by_array([r_uint(n) for n in range(N)])
 
 def test_jumpahead():
     rnd = Random()
@@ -47,8 +48,8 @@
     def f(x, y):
         rnd = Random(x)
         rnd.init_by_array([x, y])
-        rnd.jumpahead(y)
+        rnd.jumpahead(intmask(y))
         return rnd.genrand32(), rnd.random()
     t = Translation(f)
-    fc = t.compile_c([int, int])
-    assert fc(1, 2) == f(1, 2)
+    fc = t.compile_c([r_uint, r_uint])
+    assert fc(r_uint(1), r_uint(2)) == f(r_uint(1), r_uint(2))
diff --git a/pypy/rlib/test/test_rstacklet.py b/pypy/rlib/test/test_rstacklet.py
--- a/pypy/rlib/test/test_rstacklet.py
+++ b/pypy/rlib/test/test_rstacklet.py
@@ -1,4 +1,4 @@
-import gc
+import gc, sys
 import py
 from pypy.rpython.tool.rffi_platform import CompilationError
 try:
@@ -65,6 +65,15 @@
             self.tasks[0].withdepth(self.random.genrand32() % 50)
             assert len(self.tasks[0].lst) == 0
 
+    @here_is_a_test
+    def test_destroy(self):
+        # this used to give MemoryError in shadowstack tests
+        for i in range(100000):
+            self.status = 0
+            h = self.sthread.new(switchbackonce_callback,
+                                 rffi.cast(llmemory.Address, 321))
+            self.sthread.destroy(h)
+
     def any_alive(self):
         for task in self.tasks:
             if task.h:
@@ -228,6 +237,8 @@
         cls.old_values = Runner.config, Runner.STATUSMAX
         Runner.config = config
         Runner.STATUSMAX = 25000
+        if cls.gcrootfinder == "asmgcc" and sys.platform == "win32":
+            py.test.skip("fails with asmgcc on win32")
 
     def teardown_class(cls):
         Runner.config, Runner.STATUSMAX = cls.old_values
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -711,7 +711,7 @@
             #
             # Record the newly allocated object and its full malloced size.
             # The object is young or old depending on the argument.
-            self.rawmalloced_total_size += allocsize
+            self.rawmalloced_total_size += r_uint(allocsize)
             if can_make_young:
                 if not self.young_rawmalloced_objects:
                     self.young_rawmalloced_objects = self.AddressDict()
@@ -888,8 +888,8 @@
         #return (num_bits + (LONG_BIT - 1)) >> LONG_BIT_SHIFT
         # --- Optimized version:
         return intmask(
-            ((r_uint(length) + ((LONG_BIT << self.card_page_shift) - 1)) >>
-             (self.card_page_shift + LONG_BIT_SHIFT)))
+          ((r_uint(length) + r_uint((LONG_BIT << self.card_page_shift) - 1)) >>
+           (self.card_page_shift + LONG_BIT_SHIFT)))
 
     def card_marking_bytes_for_length(self, length):
         # --- Unoptimized version:
@@ -897,7 +897,7 @@
         #return (num_bits + 7) >> 3
         # --- Optimized version:
         return intmask(
-            ((r_uint(length) + ((8 << self.card_page_shift) - 1)) >>
+            ((r_uint(length) + r_uint((8 << self.card_page_shift) - 1)) >>
              (self.card_page_shift + 3)))
 
     def debug_check_consistency(self):
@@ -1525,7 +1525,7 @@
         llarena.arena_reserve(arena, totalsize)
         #
         size_gc_header = self.gcheaderbuilder.size_gc_header
-        self.rawmalloced_total_size += raw_malloc_usage(totalsize)
+        self.rawmalloced_total_size += r_uint(raw_malloc_usage(totalsize))
         self.old_rawmalloced_objects.append(arena + size_gc_header)
         return arena
 
@@ -1691,7 +1691,7 @@
                 allocsize += extra_words * WORD
             #
             llarena.arena_free(arena)
-            self.rawmalloced_total_size -= allocsize
+            self.rawmalloced_total_size -= r_uint(allocsize)
 
     def free_unvisited_rawmalloc_objects(self):
         list = self.old_rawmalloced_objects
diff --git a/pypy/rpython/memory/gc/minimarkpage.py b/pypy/rpython/memory/gc/minimarkpage.py
--- a/pypy/rpython/memory/gc/minimarkpage.py
+++ b/pypy/rpython/memory/gc/minimarkpage.py
@@ -149,7 +149,7 @@
         ll_assert(nsize > 0, "malloc: size is null or negative")
         ll_assert(nsize <= self.small_request_threshold,"malloc: size too big")
         ll_assert((nsize & (WORD-1)) == 0, "malloc: size is not aligned")
-        self.total_memory_used += nsize
+        self.total_memory_used += r_uint(nsize)
         #
         # Get the page to use from the size
         size_class = nsize >> WORD_POWER_2
@@ -474,7 +474,7 @@
             obj += block_size
         #
         # Update the global total size of objects.
-        self.total_memory_used += surviving * block_size
+        self.total_memory_used += r_uint(surviving * block_size)
         #
         # Return the number of surviving objects.
         return surviving
diff --git a/pypy/rpython/memory/gctransform/asmgcroot.py b/pypy/rpython/memory/gctransform/asmgcroot.py
--- a/pypy/rpython/memory/gctransform/asmgcroot.py
+++ b/pypy/rpython/memory/gctransform/asmgcroot.py
@@ -92,7 +92,6 @@
         # make a copy of the graph that will reload the values
         graph2 = copygraph(fnptr._obj.graph)
         block2 = graph2.startblock
-        block2.isstartblock = False
         block1 = Block([])
         reloadedvars = []
         for v, c_p in zip(block2.inputargs, sra):
@@ -109,7 +108,6 @@
                                                         [w], v))
             reloadedvars.append(v)
         block1.closeblock(Link(reloadedvars, block2))
-        block1.isstartblock = True
         graph2.startblock = block1
         FUNC2 = lltype.FuncType([], FUNC1.RESULT)
         fnptr2 = lltype.functionptr(FUNC2,
diff --git a/pypy/rpython/memory/gctransform/shadowstack.py b/pypy/rpython/memory/gctransform/shadowstack.py
--- a/pypy/rpython/memory/gctransform/shadowstack.py
+++ b/pypy/rpython/memory/gctransform/shadowstack.py
@@ -307,7 +307,7 @@
                   "restore_state_from: broken shadowstack")
         self.gcdata.root_stack_base = shadowstackref.base
         self.gcdata.root_stack_top  = shadowstackref.top
-        self.destroy(shadowstackref)
+        self._cleanup(shadowstackref)
 
     def start_fresh_new_state(self):
         self.gcdata.root_stack_base = self.unused_full_stack
@@ -315,6 +315,10 @@
         self.unused_full_stack = llmemory.NULL
 
     def destroy(self, shadowstackref):
+        llmemory.raw_free(shadowstackref.base)
+        self._cleanup(shadowstackref)
+
+    def _cleanup(self, shadowstackref):
         shadowstackref.base = llmemory.NULL
         shadowstackref.top = llmemory.NULL
         shadowstackref.context = llmemory.NULL
diff --git a/pypy/rpython/memory/gctransform/test/test_transform.py b/pypy/rpython/memory/gctransform/test/test_transform.py
--- a/pypy/rpython/memory/gctransform/test/test_transform.py
+++ b/pypy/rpython/memory/gctransform/test/test_transform.py
@@ -102,12 +102,12 @@
         llops.genop("gc_pop_alive", [var])
 
 
-def checkblock(block, is_borrowed):
+def checkblock(block, is_borrowed, is_start_block):
     if block.operations == ():
         # a return/exception block -- don't want to think about them
         # (even though the test passes for somewhat accidental reasons)
         return
-    if block.isstartblock:
+    if is_start_block:
         refs_in = 0
     else:
         refs_in = len([v for v in block.inputargs if isinstance(v, Variable)
@@ -167,7 +167,7 @@
     if check:
         for graph, is_borrowed in graphs_borrowed.iteritems():
             for block in graph.iterblocks():
-                checkblock(block, is_borrowed)
+                checkblock(block, is_borrowed, block is graph.startblock)
     return t, transformer
 
 def getops(graph):
diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py
--- a/pypy/rpython/memory/gctransform/transform.py
+++ b/pypy/rpython/memory/gctransform/transform.py
@@ -263,9 +263,7 @@
         # still be empty (but let's check)
         if starts_with_empty_block(graph) and inserted_empty_startblock:
             old_startblock = graph.startblock
-            graph.startblock.isstartblock = False
             graph.startblock = graph.startblock.exits[0].target
-            graph.startblock.isstartblock = True
 
         checkgraph(graph)
 
diff --git a/pypy/rpython/module/ll_termios.py b/pypy/rpython/module/ll_termios.py
--- a/pypy/rpython/module/ll_termios.py
+++ b/pypy/rpython/module/ll_termios.py
@@ -72,9 +72,14 @@
 
 def tcsetattr_llimpl(fd, when, attributes):
     c_struct = lltype.malloc(TERMIOSP.TO, flavor='raw')
-    c_struct.c_c_iflag, c_struct.c_c_oflag, c_struct.c_c_cflag, \
-    c_struct.c_c_lflag, ispeed, ospeed, cc = attributes
     try:
+        c_struct.c_c_iflag = r_uint(attributes[0])
+        c_struct.c_c_oflag = r_uint(attributes[1])
+        c_struct.c_c_cflag = r_uint(attributes[2])
+        c_struct.c_c_lflag = r_uint(attributes[3])
+        ispeed = r_uint(attributes[4])
+        ospeed = r_uint(attributes[5])
+        cc = attributes[6]
         for i in range(NCCS):
             c_struct.c_c_cc[i] = rffi.r_uchar(ord(cc[i][0]))
         if c_cfsetispeed(c_struct, ispeed) < 0:
@@ -87,8 +92,8 @@
         lltype.free(c_struct, flavor='raw')
 
 r_uint = rffi.r_uint
-register_external(rtermios.tcsetattr, [int, int, (r_uint, r_uint, r_uint,
-                  r_uint, r_uint, r_uint, [str])], llimpl=tcsetattr_llimpl,
+register_external(rtermios.tcsetattr, [int, int, (int, int, int,
+                  int, int, int, [str])], llimpl=tcsetattr_llimpl,
                   export_name='termios.tcsetattr')
 
 # a bit C-c C-v code follows...
diff --git a/pypy/rpython/normalizecalls.py b/pypy/rpython/normalizecalls.py
--- a/pypy/rpython/normalizecalls.py
+++ b/pypy/rpython/normalizecalls.py
@@ -116,8 +116,6 @@
                     v = Constant(default)
                 outlist.append(v)
             newblock.closeblock(Link(outlist, oldblock))
-            oldblock.isstartblock = False
-            newblock.isstartblock = True
             graph.startblock = newblock
             for i in range(len(newdefaults)-1,-1,-1):
                 if newdefaults[i] is NODEFAULT:
@@ -171,8 +169,6 @@
             # prepare the output args of newblock and link
             outlist = inlist[:]
             newblock.closeblock(Link(outlist, oldblock))
-            oldblock.isstartblock = False
-            newblock.isstartblock = True
             graph.startblock = newblock
             # finished
             checkgraph(graph)
diff --git a/pypy/tool/nullpath.py b/pypy/tool/nullpath.py
--- a/pypy/tool/nullpath.py
+++ b/pypy/tool/nullpath.py
@@ -1,4 +1,4 @@
-import py
+import py, os
 
 class NullPyPathLocal(py.path.local):
 
@@ -6,7 +6,7 @@
         return self.__class__(py.path.local.join(self, *args))
 
     def open(self, mode):
-        return open('/dev/null', mode)
+        return open(os.devnull, mode)
 
     def __repr__(self):
         return py.path.local.__repr__(self) + ' [fake]'
diff --git a/pypy/tool/test/test_nullpath.py b/pypy/tool/test/test_nullpath.py
--- a/pypy/tool/test/test_nullpath.py
+++ b/pypy/tool/test/test_nullpath.py
@@ -1,11 +1,7 @@
-import sys
+import sys, os
 import py
 from pypy.tool.nullpath import NullPyPathLocal
 
-def setup_module():
-    if 'posix' not in sys.builtin_module_names:
-        py.test.skip('posix only')
-
 def test_nullpath(tmpdir):
     path = NullPyPathLocal(tmpdir)
     assert repr(path).endswith('[fake]')
@@ -13,4 +9,4 @@
     assert isinstance(foo_txt, NullPyPathLocal)
     #
     f = foo_txt.open('w')
-    assert f.name == '/dev/null'
+    assert f.name == os.devnull
diff --git a/pypy/translator/backendopt/constfold.py b/pypy/translator/backendopt/constfold.py
--- a/pypy/translator/backendopt/constfold.py
+++ b/pypy/translator/backendopt/constfold.py
@@ -37,8 +37,9 @@
                 except (KeyboardInterrupt, SystemExit):
                     raise
                 except Exception, e:
-                    log.WARNING('constant-folding %r:' % (spaceop,))
-                    log.WARNING('  %s: %s' % (e.__class__.__name__, e))
+                    pass   # turn off reporting these as warnings: useless
+                    #log.WARNING('constant-folding %r:' % (spaceop,))
+                    #log.WARNING('  %s: %s' % (e.__class__.__name__, e))
                 else:
                     # success in folding this space operation
                     if spaceop.opname in fixup_op_result:
diff --git a/pypy/translator/backendopt/inline.py b/pypy/translator/backendopt/inline.py
--- a/pypy/translator/backendopt/inline.py
+++ b/pypy/translator/backendopt/inline.py
@@ -453,7 +453,6 @@
         #vars that need to be passed through the blocks of the inlined function
         linktoinlined = splitlink
         copiedstartblock = self.copy_block(self.graph_to_inline.startblock)
-        copiedstartblock.isstartblock = False
         #find args passed to startblock of inlined function
         passon_args = []
         for arg in self.op.args[1:]:
diff --git a/pypy/translator/backendopt/mallocv.py b/pypy/translator/backendopt/mallocv.py
--- a/pypy/translator/backendopt/mallocv.py
+++ b/pypy/translator/backendopt/mallocv.py
@@ -391,7 +391,6 @@
         virtualframe = VirtualFrame(graph2.startblock, 0, nodelist)
         graphbuilder = GraphBuilder(self, graph2)
         specblock = graphbuilder.start_from_virtualframe(virtualframe)
-        specblock.isstartblock = True
         specgraph = graph2
         specgraph.name += '_mallocv'
         specgraph.startblock = specblock
diff --git a/pypy/translator/backendopt/test/test_malloc.py b/pypy/translator/backendopt/test/test_malloc.py
--- a/pypy/translator/backendopt/test/test_malloc.py
+++ b/pypy/translator/backendopt/test/test_malloc.py
@@ -50,7 +50,8 @@
         # we do the loop ourselves instead of calling remove_simple_mallocs()
         while True:
             progress = remover.remove_mallocs_once(graph)
-            simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
+            simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()),
+                                                      [graph])
             if progress and option.view:
                 t.view()
             if expected_result is not Ellipsis:
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -542,7 +542,7 @@
             mk.rule(*rule)
 
         if self.config.translation.gcrootfinder == 'asmgcc':
-            trackgcfiles = [cfile[:-2] for cfile in mk.cfiles]
+            trackgcfiles = [cfile[:cfile.rfind('.')] for cfile in mk.cfiles]
             if self.translator.platform.name == 'msvc':
                 trackgcfiles = [f for f in trackgcfiles
                                 if f.startswith(('implement', 'testing',
@@ -579,7 +579,7 @@
             if self.translator.platform.name == 'msvc':
                 lblofiles = []
                 for cfile in mk.cfiles:
-                    f = cfile[:-2]
+                    f = cfile[:cfile.rfind('.')]
                     if f in trackgcfiles:
                         ofile = '%s.lbl.obj' % (f,)
                     else:
diff --git a/pypy/translator/c/test/test_lltyped.py b/pypy/translator/c/test/test_lltyped.py
--- a/pypy/translator/c/test/test_lltyped.py
+++ b/pypy/translator/c/test/test_lltyped.py
@@ -476,12 +476,13 @@
         def f(n):
             result = ()
             for cls in classes:
+                nn = cls(n)
                 for OP in operators:
                     x = getmin(cls)
-                    res1 = OP(x, n)
+                    res1 = OP(x, nn)
                     result = result + (res1,)
                     x = getmax(cls)
-                    res1 = OP(x, n)
+                    res1 = OP(x, nn)
                     result = result + (res1,)
             return result
 
diff --git a/pypy/translator/c/test/test_refcount.py b/pypy/translator/c/test/test_refcount.py
--- a/pypy/translator/c/test/test_refcount.py
+++ b/pypy/translator/c/test/test_refcount.py
@@ -229,7 +229,6 @@
     graph = t.buildflowgraph(g)
     assert graph.startblock.operations == []
     graph.startblock = graph.startblock.exits[0].target
-    graph.startblock.isstartblock = True
     from pypy.objspace.flow.model import checkgraph
     checkgraph(graph)
     t._prebuilt_graphs[g] = graph
diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py
--- a/pypy/translator/c/test/test_standalone.py
+++ b/pypy/translator/c/test/test_standalone.py
@@ -224,7 +224,7 @@
         filename = str(udir.join('test_standalone_largefile'))
         r4800000000 = r_longlong(4800000000L)
         def entry_point(argv):
-            assert str(r4800000000 + len(argv)) == '4800000003'
+            assert str(r4800000000 + r_longlong(len(argv))) == '4800000003'
             fd = os.open(filename, os.O_RDWR | os.O_CREAT, 0644)
             os.lseek(fd, r4800000000, 0)
             newpos = os.lseek(fd, 0, 1)
diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py
--- a/pypy/translator/c/test/test_typed.py
+++ b/pypy/translator/c/test/test_typed.py
@@ -261,7 +261,7 @@
         f._annspecialcase_ = "specialize:argtype(0)"
         def g(n):
             if n > 0:
-                return f(r_longlong(0))
+                return intmask(f(r_longlong(0)))
             else:
                 return f(0)
 
diff --git a/pypy/translator/jvm/test/test_rarithmetic.py b/pypy/translator/jvm/test/test_rarithmetic.py
--- a/pypy/translator/jvm/test/test_rarithmetic.py
+++ b/pypy/translator/jvm/test/test_rarithmetic.py
@@ -32,7 +32,7 @@
                     cache[types] = fun
                 return cache[types](x, y)
             return f(x,y)
-        super(BaseAdaptedTest,self).binary_test(new_func, rargs)
+        super(BaseAdaptedTest,self).binary_test(new_func, rargs, translated=True)
 
 class Test_r_uint(BaseAdaptedTest, BaseTest_r_uint):
     RTYPE = ra.r_uint    
diff --git a/pypy/translator/platform/darwin.py b/pypy/translator/platform/darwin.py
--- a/pypy/translator/platform/darwin.py
+++ b/pypy/translator/platform/darwin.py
@@ -12,17 +12,10 @@
 
     so_ext = 'dylib'
 
-    # NOTE: GCC 4.2 will fail at runtime due to subtle issues, possibly
-    # related to GC roots. Using LLVM-GCC or Clang will break the build.
-    default_cc = 'gcc-4.0'
-
-    def __init__(self, cc=None):
-        if cc is None:
-            try:
-                cc = os.environ['CC']
-            except KeyError:
-                cc = self.default_cc
-        self.cc = cc
+    # NOTE: With asmgcc GCC 4.2 will fail at runtime due to subtle issues,
+    # possibly related to GC roots. Using LLVM-GCC or Clang will break the
+    # build. On Darwin asmgcc is not the default anymore, so it is fine to use
+    # whatever gcc we find on the system
 
     def _args_for_shared(self, args):
         return (list(self.shared_only)
diff --git a/pypy/translator/platform/windows.py b/pypy/translator/platform/windows.py
--- a/pypy/translator/platform/windows.py
+++ b/pypy/translator/platform/windows.py
@@ -179,7 +179,7 @@
         # The c compiler accepts any order of arguments, while
         # the assembler still has the old behavior that all options
         # must come first, and after the file name all options are ignored.
-        # So please be careful with the oder of parameters! ;-)
+        # So please be careful with the order of parameters! ;-)
         args = ['/nologo', '/c'] + compile_args + ['/Fo%s' % (oname,), str(cfile)]
         self._execute_c_compiler(cc, args, oname)
         return oname
@@ -265,7 +265,7 @@
                 return fpath
 
         rel_cfiles = [m.pathrel(cfile) for cfile in cfiles]
-        rel_ofiles = [rel_cfile[:-2]+'.obj' for rel_cfile in rel_cfiles]
+        rel_ofiles = [rel_cfile[:rel_cfile.rfind('.')]+'.obj' for rel_cfile in rel_cfiles]
         m.cfiles = rel_cfiles
 
         rel_includedirs = [pypyrel(incldir) for incldir in eci.include_dirs]
@@ -296,6 +296,7 @@
         rules = [
             ('all', '$(DEFAULT_TARGET)', []),
             ('.c.obj', '', '$(CC) /nologo $(CFLAGS) $(CFLAGSEXTRA) /Fo$@ /c $< $(INCLUDEDIRS)'),
+            ('.asm.obj', '', '$(MASM) /nologo /Fo$@ /c $< $(INCLUDEDIRS)'),
             ]
 
         for rule in rules:
diff --git a/pypy/translator/simplify.py b/pypy/translator/simplify.py
--- a/pypy/translator/simplify.py
+++ b/pypy/translator/simplify.py
@@ -397,7 +397,8 @@
 def transform_dead_op_vars(graph, translator=None):
     """Remove dead operations and variables that are passed over a link
     but not used in the target block. Input is a graph."""
-    return transform_dead_op_vars_in_blocks(list(graph.iterblocks()), translator)
+    return transform_dead_op_vars_in_blocks(list(graph.iterblocks()),
+                                            [graph], translator)
 
 # the set of operations that can safely be removed
 # (they have no side effects, at least in R-Python)
@@ -419,11 +420,19 @@
     hasattr: True,
     }
 
-def transform_dead_op_vars_in_blocks(blocks, translator=None):
+def find_start_blocks(graphs):
+    start_blocks = set()
+    for graph in graphs:
+        start_blocks.add(graph.startblock)
+    return start_blocks
+
+def transform_dead_op_vars_in_blocks(blocks, graphs, translator=None):
     """Remove dead operations and variables that are passed over a link
     but not used in the target block. Input is a set of blocks"""
     read_vars = {}  # set of variables really used
     variable_flow = {}  # map {Var: list-of-Vars-it-depends-on}
+    set_of_blocks = set(blocks)
+    start_blocks = find_start_blocks(graphs)
 
     def canremove(op, block):
         if op.opname not in CanRemove:
@@ -451,7 +460,7 @@
 
         if block.exits:
             for link in block.exits:
-                if link.target not in blocks:
+                if link.target not in set_of_blocks:
                     for arg, targetarg in zip(link.args, link.target.inputargs):
                         read_vars[arg] = True
                         read_vars[targetarg] = True
@@ -465,7 +474,7 @@
                 read_vars[arg] = True
         # an input block's inputargs should not be modified, even if some
         # of the function's input arguments are not actually used
-        if block.isstartblock:
+        if block in start_blocks:
             for arg in block.inputargs:
                 read_vars[arg] = True
 
diff --git a/pypy/translator/transform.py b/pypy/translator/transform.py
--- a/pypy/translator/transform.py
+++ b/pypy/translator/transform.py
@@ -115,7 +115,7 @@
     # to kill dead (never-followed) links,
     # which can possibly remove more variables.
     from pypy.translator.simplify import transform_dead_op_vars_in_blocks
-    transform_dead_op_vars_in_blocks(block_subset)
+    transform_dead_op_vars_in_blocks(block_subset, self.translator.graphs)
 
 def transform_dead_code(self, block_subset):
     """Remove dead code: these are the blocks that are not annotated at all
diff --git a/pypy/translator/unsimplify.py b/pypy/translator/unsimplify.py
--- a/pypy/translator/unsimplify.py
+++ b/pypy/translator/unsimplify.py
@@ -42,9 +42,7 @@
     vars = [copyvar(annotator, v) for v in graph.startblock.inputargs]
     newblock = Block(vars)
     newblock.closeblock(Link(vars, graph.startblock))
-    graph.startblock.isstartblock = False
     graph.startblock = newblock
-    graph.startblock.isstartblock = True
 
 def starts_with_empty_block(graph):
     return (not graph.startblock.operations
@@ -151,9 +149,7 @@
     newop = SpaceOperation('direct_call', [c_initial_func], v_none)
     extrablock.operations = [newop]
     extrablock.closeblock(Link(args, entry_point.startblock))
-    entry_point.startblock.isstartblock = False
     entry_point.startblock = extrablock
-    entry_point.startblock.isstartblock = True
     checkgraph(entry_point)
 
 def call_final_function(translator, final_func, annhelper=None):


More information about the pypy-commit mailing list