[pypy-commit] pypy numpy-dtype-refactor: Merged default in.

alex_gaynor noreply at buildbot.pypy.org
Tue Nov 29 04:50:57 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: numpy-dtype-refactor
Changeset: r49937:d54332f52707
Date: 2011-11-28 22:50 -0500
http://bitbucket.org/pypy/pypy/changeset/d54332f52707/

Log:	Merged default in.

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/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -188,6 +188,12 @@
 
     # -------------------------------------------------------------------
 
+    def is_w(self, space, w_other):
+        return self is w_other
+
+    def unique_id(self, space):
+        return space.wrap(compute_unique_id(self))
+
     def str_w(self, space):
         w_msg = typed_unwrap_error_msg(space, "string", self)
         raise OperationError(space.w_TypeError, w_msg)
@@ -681,9 +687,17 @@
         """shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
         return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
 
-    def is_w(self, w_obj1, w_obj2):
-        """shortcut for space.is_true(space.is_(w_obj1, w_obj2))"""
-        return self.is_true(self.is_(w_obj1, w_obj2))
+    def is_(self, w_one, w_two):
+        return self.newbool(self.is_w(w_one, w_two))
+
+    def is_w(self, w_one, w_two):
+        # done by a method call on w_two (and not on w_one, because of the
+        # expected programming style where we say "if x is None" or
+        # "if x is object").
+        return w_two.is_w(self, w_one)
+
+    def id(self, w_obj):
+        return w_obj.unique_id(self)
 
     def hash_w(self, w_obj):
         """shortcut for space.int_w(space.hash(w_obj))"""
@@ -1023,9 +1037,6 @@
     def isinstance_w(self, w_obj, w_type):
         return self.is_true(self.isinstance(w_obj, w_type))
 
-    def id(self, w_obj):
-        return self.wrap(compute_unique_id(w_obj))
-
     # The code below only works
     # for the simple case (new-style instance).
     # These methods are patched with the full logic by the __builtin__
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/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/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
@@ -491,7 +486,7 @@
             def __init__(self, s):
                 self.defaultencoding = s
         _str = self._str
-        sys = Sys(_str('ascii'))        
+        sys = Sys(_str('ascii'))
         mydriver = JitDriver(reds = ['n', 'sa'], greens = [])
         def f(n):
             sa = 0
@@ -504,13 +499,13 @@
             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'])
-        
+
         def f(n):
             while n < 21:
                 driver.jit_merge_point(n=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/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_': 'types.Bool.True',
         'False_': 'types.Bool.False',
@@ -59,6 +61,7 @@
         ("sign", "sign"),
         ("sin", "sin"),
         ("subtract", "subtract"),
+        ('sqrt', 'sqrt'),
         ("tan", "tan"),
     ]:
         interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
@@ -68,4 +71,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
@@ -217,13 +217,21 @@
     def execute(self, interp):
         arr = interp.variables[self.name]
         assert isinstance(arr, BaseArray)
-        w_index = self.index.execute(interp).eval(arr.start_iter())
-        # cast to int
-        if isinstance(w_index, FloatObject):
-            w_index = IntObject(int(w_index.floatval))
-        elif isinstance(w_index, interp_boxes.W_Float64Box):
-            w_index = IntObject(int(w_index.value))
-        w_val = self.expr.execute(interp).eval(arr.start_iter())
+        if isinstance(self.index, SliceConstant):
+            w_index = self.index.wrap(interp.space)
+            w_val = self.expr.execute(interp)
+        else:
+            w_index = self.index.execute(interp)
+            assert isinstance(w_index, BaseArray)
+            w_index = w_index.eval(arr.start_iter())
+            # cast to int
+            if isinstance(w_index, FloatObject):
+                w_index = IntObject(int(w_index.floatval))
+            elif isinstance(w_index, interp_boxes.W_Float64Box):
+                w_index = IntObject(int(w_index.value))
+            w_val = self.expr.execute(interp)
+            assert isinstance(w_val, BaseArray)
+            w_val = w_val.eval(arr.start_iter())
         arr.descr_setitem(interp.space, w_index, w_val)
 
     def __repr__(self):
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -87,6 +87,7 @@
     descr_gt = _binop_impl("greater")
     descr_ge = _binop_impl("greater_equal")
 
+    descr_radd = _binop_right_impl("add")
     descr_rmul = _binop_right_impl("multiply")
 
     descr_neg = _unaryop_impl("negative")
@@ -168,6 +169,7 @@
     __mul__ = interp2app(W_GenericBox.descr_mul),
     __div__ = interp2app(W_GenericBox.descr_div),
 
+    __radd__ = interp2app(W_GenericBox.descr_add),
     __rmul__ = interp2app(W_GenericBox.descr_rmul),
 
     __eq__ = interp2app(W_GenericBox.descr_eq),
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, size):
+        self.offset = start
+        self.step = step
+        self.size = size
+
+    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:
@@ -498,7 +521,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)
@@ -614,6 +637,7 @@
         concrete.to_str(space, 0, ret, ' ')
         return space.wrap(ret.build())
 
+    @jit.unroll_safe
     def _index_of_single_item(self, space, w_idx):
         if space.isinstance_w(w_idx, space.w_int):
             idx = space.int_w(w_idx)
@@ -642,6 +666,7 @@
             item += v * self.strides[i]
         return item
 
+    @jit.unroll_safe
     def _single_item_result(self, space, w_idx):
         """ The result of getitem/setitem is a single item if w_idx
         is a list of scalars that match the size of shape
@@ -671,6 +696,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)):
@@ -681,6 +707,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)
         chunks = self._prepare_slice_args(space, w_idx)
@@ -690,22 +719,25 @@
         self.invalidated()
         concrete = self.get_concrete()
         if self._single_item_result(space, w_idx):
+            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.
+            # 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)
+                w_value = w_value.descr_copy(space)
         else:
             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]
@@ -747,22 +779,42 @@
         return space.div(self.descr_sum(space), space.wrap(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))
         ))
 
+    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
@@ -793,7 +845,7 @@
         self.value = value
 
     def find_size(self):
-        raise ValueError
+        return 1
 
     def get_concrete(self):
         return self
@@ -802,7 +854,7 @@
         return self.dtype
 
     def getitem(self, item):
-        return self.value
+        raise NotImplementedError
 
     def eval(self, iter):
         return self.value
@@ -813,6 +865,12 @@
     def to_str(self, space, comma, builder, indent=' ', use_ellipsis=False):
         builder.append(self.dtype.itemtype.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
@@ -904,6 +962,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.
@@ -943,6 +1012,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
@@ -982,8 +1063,6 @@
             return space.wrap(self.shape[0])
         return space.wrap(1)
 
-class VirtualView(VirtualArray):
-    pass
 
 class NDimSlice(ViewArray):
     signature = signature.BaseSignature()
@@ -1036,6 +1115,9 @@
     def setitem(self, item, value):
         self.parent.setitem(item, value)
 
+    def debug_repr(self):
+        return 'Slice(%s)' % self.parent.debug_repr()
+
 class NDimArray(BaseArray):
     """ A class representing contiguous array. We know that each iteration
     by say ufunc will increase the data index by one
@@ -1065,6 +1147,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(
+            array.storage,
+            self.storage,
+            self.size * self.dtype.itemtype.get_element_size()
+        )
+        return array
+
     def descr_len(self, space):
         if len(self.shape):
             return space.wrap(self.shape[0])
@@ -1085,6 +1176,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)
 
@@ -1119,6 +1213,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),
@@ -1156,11 +1256,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),
@@ -1174,3 +1278,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.w_None)
+        result = self.eval(self.iter)
+        self.iter = self.iter.next(self.shapelen)
+        return result
+
+    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
@@ -325,6 +325,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,16 @@
         """)
         assert interp.results[0].value == 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 == 5
+
     def test_multidim_getitem(self):
         interp = self.run("""
         a = [[1,2]]
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
@@ -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
@@ -741,6 +754,7 @@
         assert bool(array([1]))
         assert not bool(array([0]))
 
+
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
         import numpypy
@@ -833,7 +847,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
@@ -848,7 +863,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
@@ -881,11 +897,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):
@@ -910,14 +927,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
@@ -927,6 +945,58 @@
         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_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 AppTestSupport(BaseNumpyAppTest):
     def setup_class(cls):
         import struct
@@ -940,6 +1010,7 @@
             assert a[i] == i + 1
         raises(ValueError, fromstring, "abc")
 
+
 class AppTestRepr(BaseNumpyAppTest):
     def test_repr(self):
         from numpypy import array, zeros
@@ -1012,7 +1083,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]]]'
@@ -1030,3 +1103,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
@@ -77,9 +77,9 @@
 
     def test_add(self):
         result = self.run("add")
-        self.check_loops({'getinteriorfield_raw': 2, 'float_add': 1,
-                          'setinteriorfield_raw': 1, 'int_add': 3,
-                          'int_ge': 1, 'guard_false': 1, 'jump': 1})
+        self.check_simple_loop({'getinteriorfield_raw': 2, 'float_add': 1,
+                                'setinteriorfield_raw': 1, 'int_add': 3,
+                                'int_ge': 1, 'guard_false': 1, 'jump': 1})
         assert result == 3 + 3
 
     def define_float_add():
@@ -91,9 +91,9 @@
     def test_floatadd(self):
         result = self.run("float_add")
         assert result == 3 + 3
-        self.check_loops({"getinteriorfield_raw": 1, "float_add": 1,
-                          "setinteriorfield_raw": 1, "int_add": 2,
-                          "int_ge": 1, "guard_false": 1, "jump": 1})
+        self.check_simple_loop({"getinteriorfield_raw": 1, "float_add": 1,
+                                "setinteriorfield_raw": 1, "int_add": 2,
+                                "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def define_sum():
         return """
@@ -105,9 +105,9 @@
     def test_sum(self):
         result = self.run("sum")
         assert result == 2 * sum(range(30))
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 2,
-                          "int_add": 2,
-                          "int_ge": 1, "guard_false": 1, "jump": 1})
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 2,
+                                "int_add": 2, "int_ge": 1, "guard_false": 1,
+                                "jump": 1})
 
     def define_prod():
         return """
@@ -122,9 +122,9 @@
         for i in range(30):
             expected *= i * 2
         assert result == expected
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 1,
-                          "float_mul": 1, "int_add": 2,
-                          "int_ge": 1, "guard_false": 1, "jump": 1})
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
+                                "float_mul": 1, "int_add": 2,
+                                "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def test_max(self):
         py.test.skip("broken, investigate")
@@ -135,9 +135,9 @@
         max(b)
         """)
         assert result == 256
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 1,
-                          "float_mul": 1, "int_add": 1,
-                          "int_lt": 1, "guard_true": 1, "jump": 1})
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
+                                "float_mul": 1, "int_add": 1,
+                                "int_lt": 1, "guard_true": 1, "jump": 1})
 
     def test_min(self):
         py.test.skip("broken, investigate")
@@ -148,9 +148,9 @@
         min(b)
         """)
         assert result == -24
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 1,
-                          "float_mul": 1, "int_add": 1,
-                          "int_lt": 1, "guard_true": 1, "jump": 1})
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
+                                "float_mul": 1, "int_add": 1,
+                                "int_lt": 1, "guard_true": 1, "jump": 1})
 
     def define_any():
         return """
@@ -163,10 +163,10 @@
     def test_any(self):
         result = self.run("any")
         assert result == 1
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 1,
-                          "float_ne": 1, "int_add": 2,
-                          "int_ge": 1, "jump": 1,
-                          "guard_false": 2})
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1,
+                                "float_ne": 1, "int_add": 2,
+                                "int_ge": 1, "jump": 1,
+                                "guard_false": 2})
 
     def define_already_forced():
         return """
@@ -183,9 +183,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({"getinteriorfield_raw": 2, "float_mul": 1, "float_add": 1,
-                          "setinteriorfield_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({'setinteriorfield_raw': 4, 'guard_nonnull': 1, 'getfield_gc': 41,
+                           'guard_class': 22, 'int_add': 8, 'float_mul': 2,
+                           'guard_isnull': 2, 'jump': 4, 'int_ge': 4,
+                           'getinteriorfield_raw': 4, 'float_add': 2, 'guard_false': 4,
+                           'guard_value': 2})
 
     def define_ufunc():
         return """
@@ -198,10 +202,9 @@
     def test_ufunc(self):
         result = self.run("ufunc")
         assert result == -6
-        self.check_loops({"getinteriorfield_raw": 2, "float_add": 1, "float_neg": 1,
-                          "setinteriorfield_raw": 1, "int_add": 3,
-                          "int_ge": 1, "guard_false": 1, "jump": 1,
-        })
+        self.check_simple_loop({"getinteriorfield_raw": 2, "float_add": 1, "float_neg": 1,
+                                "setinteriorfield_raw": 1, "int_add": 3,
+                                "int_ge": 1, "guard_false": 1, "jump": 1})
 
     def define_specialization():
         return """
@@ -240,9 +243,9 @@
         result = self.run("slice")
         assert result == 18
         py.test.skip("Few remaining arraylen_gc left")
-        self.check_loops({'int_mul': 2, 'getinteriorfield_raw': 2, 'float_add': 1,
-                          'setinteriorfield_raw': 1, 'int_add': 3,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        self.check_simple_loop({'int_mul': 2, 'getinteriorfield_raw': 2, 'float_add': 1,
+                                'setinteriorfield_raw': 1, 'int_add': 3,
+                                'int_lt': 1, 'guard_true': 1, 'jump': 1})
 
     def define_multidim():
         return """
@@ -254,11 +257,11 @@
     def test_multidim(self):
         result = self.run('multidim')
         assert result == 8
-        self.check_loops({'float_add': 1, 'getinteriorfield_raw': 2,
-                          'guard_false': 1, 'int_add': 3, 'int_ge': 1,
-                          'jump': 1, 'setinteriorfield_raw': 1})
         # int_add might be 1 here if we try slightly harder with
         # reusing indexes or some optimization
+        self.check_simple_loop({'float_add': 1, 'getinteriorfield_raw': 2,
+                                'guard_false': 1, 'int_add': 3, 'int_ge': 1,
+                                'jump': 1, 'setinteriorfield_raw': 1})
 
     def define_multidim_slice():
         return """
@@ -274,7 +277,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 """
@@ -288,7 +291,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
+        py.test.skip("generates 2 loops ATM, investigate")
+        self.check_simple_loop({'getarrayitem_raw': 2, 'float_add' : 1,
+                                'setarrayitem_raw': 1, 'int_add': 2,
+                                'int_lt': 1, 'guard_true': 1, 'jump': 1})
 
 class TestNumpyOld(LLJitMixin):
     def setup_class(cls):
@@ -337,33 +358,11 @@
             return v.value
 
         result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'int_mul': 2, 'getinteriorfield_raw': 2, 'float_add': 1,
-                          'setinteriorfield_raw': 1, 'int_add': 1,
-                          'int_lt': 1, 'guard_true': 1, 'jump': 1})
+        self.check_simple_loop({'int_mul': 2, 'getinteriorfield_raw': 2, 'float_add': 1,
+                                'setinteriorfield_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)
-            v = ar.get_concrete().eval(3)
-            assert isinstance(v, interp_boxes.W_Float64Box)
-            return v.value
-
-        result = self.meta_interp(f, [5], listops=True, backendopt=True)
-        self.check_loops({'getinteriorfield_raw': 2,
-                          'float_add' : 1,
-                          'setinteriorfield_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/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -206,6 +206,18 @@
     def mod(self, v1, v2):
         return v1 % v2
 
+    @simple_binary_op
+    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
+
     @simple_unary_op
     def sign(self, v):
         if v > 0:
@@ -357,6 +369,13 @@
             return rfloat.NAN
         return math.atanh(v)
 
+    @simple_unary_op
+    def sqrt(self, v):
+        try:
+            return math.sqrt(v)
+        except ValueError:
+            return rfloat.NAN
+
 
 class Float32(BaseType, Float):
     T = rffi.FLOAT
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/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/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -5,12 +5,46 @@
 from pypy.objspace.std.register_all import register_all
 from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
 from pypy.objspace.std.longobject import W_LongObject
+from pypy.rlib.rbigint import rbigint
 from pypy.rlib.rfloat import (
     formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
 
 import math
 
-class W_ComplexObject(W_Object):
+
+class W_AbstractComplexObject(W_Object):
+    __slots__ = ()
+
+    def is_w(self, space, w_other):
+        from pypy.rlib.longlong2float import float2longlong
+        if not isinstance(w_other, W_AbstractComplexObject):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        real1 = space.float_w(space.getattr(self,    space.wrap("real")))
+        real2 = space.float_w(space.getattr(w_other, space.wrap("real")))
+        imag1 = space.float_w(space.getattr(self,    space.wrap("imag")))
+        imag2 = space.float_w(space.getattr(w_other, space.wrap("imag")))
+        real1 = float2longlong(real1)
+        real2 = float2longlong(real2)
+        imag1 = float2longlong(imag1)
+        imag2 = float2longlong(imag2)
+        return real1 == real2 and imag1 == imag2
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            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")))
+        imag = space.float_w(space.getattr(self, space.wrap("imag")))
+        real_b = rbigint.fromrarith_int(float2longlong(real))
+        imag_b = rbigint.fromrarith_int(float2longlong(imag))
+        val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(val)
+
+
+class W_ComplexObject(W_AbstractComplexObject):
     """This is a reimplementation of the CPython "PyComplexObject"
     """
     from pypy.objspace.std.complextype import complex_typedef as typedef
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
@@ -21,10 +21,33 @@
 import math
 from pypy.objspace.std.intobject import W_IntObject
 
-class W_FloatObject(W_Object):
-    """This is a reimplementation of the CPython "PyFloatObject"
-       it is assumed that the constructor takes a real Python float as
-       an argument"""
+class W_AbstractFloatObject(W_Object):
+    __slots__ = ()
+
+    def is_w(self, space, w_other):
+        from pypy.rlib.longlong2float import float2longlong
+        if not isinstance(w_other, W_AbstractFloatObject):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        one = float2longlong(space.float_w(self))
+        two = float2longlong(space.float_w(w_other))
+        return one == two
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            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))
+        b = rbigint.fromrarith_int(val)
+        b = b.lshift(3).or_(rbigint.fromint(tag))
+        return space.newlong_from_rbigint(b)
+
+
+class W_FloatObject(W_AbstractFloatObject):
+    """This is a implementation of the app-level 'float' type.
+    The constructor takes an RPython float as an argument."""
     from pypy.objspace.std.floattype import float_typedef as typedef
     _immutable_fields_ = ['floatval']
 
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
@@ -19,6 +19,22 @@
 class W_AbstractIntObject(W_Object):
     __slots__ = ()
 
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractIntObject):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        return space.int_w(self) == space.int_w(w_other)
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            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))
+        return space.newlong_from_rbigint(b)
+
+
 class W_IntObject(W_AbstractIntObject):
     __slots__ = 'intval'
     _immutable_fields_ = ['intval']
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
@@ -11,6 +11,22 @@
 class W_AbstractLongObject(W_Object):
     __slots__ = ()
 
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractLongObject):
+            return False
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return self is w_other
+        return space.bigint_w(self).eq(space.bigint_w(w_other))
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            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))
+        return space.newlong_from_rbigint(b)
+
+
 class W_LongObject(W_AbstractLongObject):
     """This is a wrapper of rbigint."""
     from pypy.objspace.std.longtype import long_typedef as typedef
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -29,6 +29,11 @@
                     "proxyobject.W_TransparentDict"],
 }
 
+IDTAG_INT     = 1
+IDTAG_LONG    = 3
+IDTAG_FLOAT   = 5
+IDTAG_COMPLEX = 7
+
 class StdTypeModel:
 
     def __init__(self, config):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -453,77 +453,6 @@
                                  self.wrap("Expected tuple of length 3"))
         return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
 
-    def is_(self, w_one, w_two):
-        return self.newbool(self.is_w(w_one, w_two))
-
-    def is_w(self, w_one, w_two):
-        from pypy.rlib.longlong2float import float2longlong
-        w_typeone = self.type(w_one)
-        # cannot use self.is_w here to not get infinite recursion
-        if w_typeone is self.w_int:
-            return (self.type(w_two) is self.w_int and
-                    self.int_w(w_one) == self.int_w(w_two))
-        elif w_typeone is self.w_float:
-            if self.type(w_two) is not self.w_float:
-                return False
-            one = float2longlong(self.float_w(w_one))
-            two = float2longlong(self.float_w(w_two))
-            return one == two
-        elif w_typeone is self.w_long:
-            return (self.type(w_two) is self.w_long and
-                    self.bigint_w(w_one).eq(self.bigint_w(w_two)))
-        elif w_typeone is self.w_complex:
-            if self.type(w_two) is not self.w_complex:
-                return False
-            real1 = self.float_w(self.getattr(w_one, self.wrap("real")))
-            real2 = self.float_w(self.getattr(w_two, self.wrap("real")))
-            imag1 = self.float_w(self.getattr(w_one, self.wrap("imag")))
-            imag2 = self.float_w(self.getattr(w_two, self.wrap("imag")))
-            real1 = float2longlong(real1)
-            real2 = float2longlong(real2)
-            imag1 = float2longlong(imag1)
-            imag2 = float2longlong(imag2)
-            return real1 == real2 and imag1 == imag2
-        elif w_typeone is self.w_str:
-            return (self.type(w_two) is self.w_str and
-                    self.str_w(w_one) is self.str_w(w_two))
-        elif w_typeone is self.w_unicode:
-            return (self.type(w_two) is self.w_unicode and
-                    self.unicode_w(w_one) is self.unicode_w(w_two))
-        return w_one is w_two
-
-    def id(self, w_obj):
-        from pypy.rlib.rbigint import rbigint
-        from pypy.rlib import objectmodel
-        from pypy.rlib.longlong2float import float2longlong
-        w_type = self.type(w_obj)
-        if w_type is self.w_int:
-            tag = 1
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_long:
-            tag = 3
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_float:
-            tag = 5
-            val = float2longlong(self.float_w(w_obj))
-            w_obj = self.newlong_from_rbigint(rbigint.fromrarith_int(val))
-            return self.or_(self.lshift(w_obj, self.wrap(3)), self.wrap(tag))
-        elif w_type is self.w_complex:
-            real = self.float_w(self.getattr(w_obj, self.wrap("real")))
-            imag = self.float_w(self.getattr(w_obj, self.wrap("imag")))
-            tag = 5
-            real_b = rbigint.fromrarith_int(float2longlong(real))
-            imag_b = rbigint.fromrarith_int(float2longlong(imag))
-            val = real_b.lshift(8 * 8).or_(imag_b).lshift(3).or_(rbigint.fromint(3))
-            return self.newlong_from_rbigint(val)
-        elif w_type is self.w_str:
-            res = objectmodel.compute_unique_id(self.str_w(w_obj))
-        elif w_type is self.w_unicode:
-            res = objectmodel.compute_unique_id(self.unicode_w(w_obj))
-        else:
-            res = objectmodel.compute_unique_id(w_obj)
-        return self.wrap(res)
-
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
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
@@ -5,6 +5,7 @@
 from pypy.interpreter import gateway
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.objectmodel import we_are_translated, compute_hash, specialize
+from pypy.rlib.objectmodel import compute_unique_id
 from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype, newformat
@@ -22,6 +23,21 @@
 class W_AbstractStringObject(W_Object):
     __slots__ = ()
 
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractStringObject):
+            return False
+        if self is w_other:
+            return True
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return False
+        return space.str_w(self) is space.str_w(w_other)
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            return W_Object.unique_id(self, space)
+        return space.wrap(compute_unique_id(space.str_w(self)))
+
+
 class W_StringObject(W_AbstractStringObject):
     from pypy.objspace.std.stringtype import str_typedef as typedef
     _immutable_fields_ = ['_value']
diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -147,6 +147,28 @@
         s = "a"
         assert self.unwrap_wrap_str(s) is s
 
+    def test_is_on_subclasses(self):
+        for typ in [int, long, float, complex, str, unicode]:
+            class mytyp(typ):
+                pass
+            if not self.cpython_apptest and typ not in (str, unicode):
+                assert typ(42) is typ(42)
+            assert mytyp(42) is not mytyp(42)
+            assert mytyp(42) is not typ(42)
+            assert typ(42) is not mytyp(42)
+            x = mytyp(42)
+            assert x is x
+            assert x is not "43"
+            assert x is not None
+            assert "43" is not x
+            assert None is not x
+            x = typ(42)
+            assert x is x
+            assert x is not "43"
+            assert x is not None
+            assert "43" is not x
+            assert None is not x
+
     def test_id_on_primitives(self):
         if self.cpython_apptest:
             skip("cpython behaves differently")
@@ -226,6 +248,12 @@
                 if a is b:
                     assert a == b
 
+    def test_identity_bug(self):
+        x = 0x4000000000000000L
+        y = 2j
+        assert id(x) != id(y)
+
+
 def test_isinstance_shortcut():
     from pypy.objspace.std import objspace
     space = objspace.StdObjSpace()
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
@@ -11,6 +11,7 @@
 from pypy.objspace.std.tupleobject import W_TupleObject
 from pypy.rlib.rarithmetic import intmask, ovfcheck
 from pypy.rlib.objectmodel import compute_hash, specialize
+from pypy.rlib.objectmodel import compute_unique_id
 from pypy.rlib.rstring import UnicodeBuilder
 from pypy.rlib.runicode import unicode_encode_unicode_escape
 from pypy.module.unicodedata import unicodedb
@@ -22,6 +23,21 @@
 class W_AbstractUnicodeObject(W_Object):
     __slots__ = ()
 
+    def is_w(self, space, w_other):
+        if not isinstance(w_other, W_AbstractUnicodeObject):
+            return False
+        if self is w_other:
+            return True
+        if self.user_overridden_class or w_other.user_overridden_class:
+            return False
+        return space.unicode_w(self) is space.unicode_w(w_other)
+
+    def unique_id(self, space):
+        if self.user_overridden_class:
+            return W_Object.unique_id(self, space)
+        return space.wrap(compute_unique_id(space.unicode_w(self)))
+
+
 class W_UnicodeObject(W_AbstractUnicodeObject):
     from pypy.objspace.std.unicodetype import unicode_typedef as typedef
     _immutable_fields_ = ['_value']
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/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:
@@ -228,6 +228,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/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py
--- a/pypy/rpython/lltypesystem/rstr.py
+++ b/pypy/rpython/lltypesystem/rstr.py
@@ -316,7 +316,7 @@
         s.chars[0] = ch
         return s
 
-    @jit.look_inside_iff(lambda str: jit.isconstant(len(str)) and len(str) == 1)
+    # @jit.look_inside_iff(lambda str: jit.isconstant(len(str.chars)) and len(str.chars) == 1)
     @jit.oopspec("str.str2unicode(str)")
     def ll_str2unicode(str):
         lgt = len(str.chars)
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/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:


More information about the pypy-commit mailing list