[pypy-commit] pypy share-guard-info: merge default

fijal noreply at buildbot.pypy.org
Sun Sep 27 18:03:32 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: share-guard-info
Changeset: r79867:303ed67a871d
Date: 2015-09-27 18:03 +0200
http://bitbucket.org/pypy/pypy/changeset/303ed67a871d/

Log:	merge default

diff too long, truncating to 2000 out of 3974 lines

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -92,6 +92,8 @@
 if sys.platform == "win32":
     module_suggests["cpyext"].append(("translation.shared", True))
 
+
+# NOTE: this dictionary is not used any more
 module_import_dependencies = {
     # no _rawffi if importing rpython.rlib.clibffi raises ImportError
     # or CompilationError or py.test.skip.Exception
@@ -108,6 +110,7 @@
     }
 
 def get_module_validator(modname):
+    # NOTE: this function is not used any more
     if modname in module_import_dependencies:
         modlist = module_import_dependencies[modname]
         def validator(config):
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -67,7 +67,7 @@
 The other commands of ``setup.py`` are available too, like ``build``.
 
 .. _PyPI: https://pypi.python.org/pypi
-.. _`use virtualenv (as documented here)`: getting-started.html#installing-using-virtualenv
+.. _`use virtualenv (as documented here)`: install.html#installing-using-virtualenv
 
 
 Module xyz does not work in the sandboxed PyPy?
diff --git a/pypy/doc/jit-hooks.rst b/pypy/doc/jit-hooks.rst
--- a/pypy/doc/jit-hooks.rst
+++ b/pypy/doc/jit-hooks.rst
@@ -5,19 +5,8 @@
 understanding what's pypy's JIT doing while running your program. There
 are three functions related to that coming from the ``pypyjit`` module:
 
-.. function:: set_optimize_hook(callable)
 
-    Set a compiling hook that will be called each time a loop is optimized,
-    but before assembler compilation. This allows adding additional
-    optimizations on Python level.
-
-    The callable will be called with the ``pypyjit.JitLoopInfo`` object.
-    Refer to it's documentation for details.
-
-    Result value will be the resulting list of operations, or None
-
-
-.. function:: set_compile_hook(callable)
+.. function:: set_compile_hook(callable, operations=True)
 
     Set a compiling hook that will be called each time a loop is compiled.
 
@@ -28,6 +17,9 @@
     inside the jit hook is itself jitted, it will get compiled, but the
     jit hook won't be called for that.
 
+    if operations=False, no list of operations will be available. Useful
+    if the hook is supposed to be very lighweight.
+
 .. function:: set_abort_hook(hook)
 
     Set a hook (callable) that will be called each time there is tracing
@@ -66,3 +58,25 @@
 
     * ``loop_run_times`` - counters for number of times loops are run, only
       works when ``enable_debug`` is called.
+
+.. class:: JitLoopInfo
+
+   A class containing information about the compiled loop. Usable attributes:
+
+   * ``operations`` - list of operations, if requested
+
+   * ``jitdriver_name`` - the name of jitdriver associated with this loop
+
+   * ``greenkey`` - a key at which the loop got compiled (e.g. code position,
+     is_being_profiled, pycode tuple for python jitdriver)
+
+   * ``loop_no`` - loop cardinal number
+
+   * ``bridge_no`` - id of the fail descr
+
+   * ``type`` - "entry bridge", "loop" or "bridge"
+
+   * ``asmaddr`` - an address in raw memory where assembler resides
+
+   * ``asmlen`` - length of raw memory with assembler associated
+
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -21,3 +21,15 @@
 
 .. branch: missing_openssl_include
 Fix for missing headers in OpenBSD, already applied in downstream ports
+
+.. branch: gc-more-incremental
+Remove a source of non-incremental-ness in the GC: now
+external_malloc() no longer runs gc_step_until() any more. If there
+is a currently-running major collection, we do only so many steps
+before returning. This number of steps depends on the size of the
+allocated object. It is controlled by tracking the general progress
+of these major collection steps and the size of old objects that
+keep adding up between them.
+
+.. branch: remember-tracing-counts
+Reenable jithooks
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -341,8 +341,8 @@
 
     def jitpolicy(self, driver):
         from pypy.module.pypyjit.policy import PyPyJitPolicy
-        #from pypy.module.pypyjit.hooks import pypy_hooks
-        return PyPyJitPolicy()#pypy_hooks)
+        from pypy.module.pypyjit.hooks import pypy_hooks
+        return PyPyJitPolicy(pypy_hooks)
 
     def get_entry_point(self, config):
         from pypy.tool.lib_pypy import import_from_lib_pypy
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -241,20 +241,26 @@
         res = libssl_RAND_status()
         return space.wrap(res)
 
-    @unwrap_spec(path=str)
-    def RAND_egd(space, path):
-        """RAND_egd(path) -> bytes
+    if HAVE_OPENSSL_RAND_EGD:
+        @unwrap_spec(path=str)
+        def RAND_egd(space, path):
+            """RAND_egd(path) -> bytes
 
-        Queries the entropy gather daemon (EGD) on socket path.  Returns number
-        of bytes read.  Raises socket.sslerror if connection to EGD fails or
-        if it does provide enough data to seed PRNG."""
-        with rffi.scoped_str2charp(path) as socket_path:
-            bytes = libssl_RAND_egd(socket_path)
-        if bytes == -1:
-            raise ssl_error(space,
-                            "EGD connection failed or EGD did not return "
-                            "enough data to seed the PRNG")
-        return space.wrap(bytes)
+            Queries the entropy gather daemon (EGD) on socket path.  Returns number
+            of bytes read.  Raises socket.sslerror if connection to EGD fails or
+            if it does provide enough data to seed PRNG."""
+            with rffi.scoped_str2charp(path) as socket_path:
+                bytes = libssl_RAND_egd(socket_path)
+            if bytes == -1:
+                raise ssl_error(space,
+                                "EGD connection failed or EGD did not return "
+                                "enough data to seed the PRNG")
+            return space.wrap(bytes)
+    else:
+        # Dummy func for platforms missing RAND_egd(). Most likely LibreSSL.
+        @unwrap_spec(path=str)
+        def RAND_egd(space, path):
+            raise ssl_error(space, "RAND_egd unavailable")
 
 
 class _SSLSocket(W_Root):
diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -36,7 +36,8 @@
         assert isinstance(_ssl.OPENSSL_VERSION_INFO, tuple)
         assert len(_ssl.OPENSSL_VERSION_INFO) == 5
         assert isinstance(_ssl.OPENSSL_VERSION, str)
-        assert 'openssl' in _ssl.OPENSSL_VERSION.lower()
+        lower_version = _ssl.OPENSSL_VERSION.lower()
+        assert 'openssl' in lower_version or "libressl" in lower_version
 
         assert isinstance(_ssl.ALERT_DESCRIPTION_ACCESS_DENIED, int)
 
@@ -69,8 +70,9 @@
 
     def test_sslwrap(self):
         import _ssl, _socket, sys, gc
-        if sys.platform == 'darwin' or 'freebsd' in sys.platform:
-            skip("hangs indefinitely on OSX & FreeBSD (also on CPython)")
+        if sys.platform == 'darwin' or 'freebsd' in sys.platform or \
+                'openbsd' in sys.platform:
+            skip("hangs indefinitely on OSX & BSD (also on CPython)")
         s = _socket.socket()
         if sys.version_info < (2, 7, 9):
             ss = _ssl.sslwrap(s, 0)
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.tool.pairtype import extendabletype
+from rpython.rlib.rarithmetic import ovfcheck
 from pypy.module.micronumpy import support
 from pypy.module.micronumpy import constants as NPY
 
@@ -44,9 +45,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(shape) * dtype.elsize
+            ovfcheck(support.product_check(shape) * dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         strides, backstrides = calc_strides(shape, dtype.base, order)
         impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
                                       backstrides, zero=zero)
@@ -68,9 +69,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            totalsize = support.product(shape) * isize
+            totalsize = ovfcheck(support.product_check(shape) * isize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         if storage_bytes > 0 :
             if totalsize > storage_bytes:
                 raise OperationError(space.w_TypeError, space.wrap(
diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -1,5 +1,6 @@
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib import jit, rgc
+from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rlib.buffer import Buffer
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage, \
@@ -409,6 +410,7 @@
         make_sure_not_resized(strides)
         make_sure_not_resized(backstrides)
         self.shape = shape
+        # already tested for overflow in from_shape_and_storage
         self.size = support.product(shape) * dtype.elsize
         self.order = order
         self.dtype = dtype
@@ -428,9 +430,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(new_shape) * self.dtype.elsize
+            ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         strides, backstrides = calc_strides(new_shape, self.dtype,
                                                     self.order)
         return SliceArray(self.start, strides, backstrides, new_shape, self,
@@ -457,8 +459,11 @@
                  storage=lltype.nullptr(RAW_STORAGE), zero=True):
         gcstruct = V_OBJECTSTORE
         flags = NPY.ARRAY_ALIGNED | NPY.ARRAY_WRITEABLE
-        length = support.product(shape)
-        self.size = length * dtype.elsize
+        try:
+            length = support.product_check(shape)
+            self.size = ovfcheck(length * dtype.elsize)
+        except OverflowError: 
+            raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.")
         if storage == lltype.nullptr(RAW_STORAGE):
             if dtype.num == NPY.OBJECT:
                 storage = dtype.itemtype.malloc(length * dtype.elsize, zero=True)
@@ -542,7 +547,10 @@
         self.gcstruct = parent.gcstruct
         self.order = parent.order
         self.dtype = dtype
-        self.size = support.product(shape) * self.dtype.elsize
+        try:
+            self.size = ovfcheck(support.product_check(shape) * self.dtype.elsize)
+        except OverflowError:
+            raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.")
         self.start = start
         self.orig_arr = orig_arr
         flags = parent.flags & NPY.ARRAY_ALIGNED
@@ -564,9 +572,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(new_shape) * self.dtype.elsize
+            ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         if len(self.get_shape()) < 2 or self.size == 0:
             # TODO: this code could be refactored into calc_strides
             # but then calc_strides would have to accept a stepping factor
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -153,7 +153,7 @@
             dtype = descriptor.variable_dtype(space, dtype.char + '1')
 
     w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
-    if support.product(shape) == 1:
+    if support.product(shape) == 1: # safe from overflow since from_shape checks
         w_arr.set_scalar_value(dtype.coerce(space, elems_w[0]))
     else:
         loop.assign(space, w_arr, elems_w)
@@ -213,10 +213,9 @@
             raise OperationError(space.w_ValueError, space.wrap(
                 "negative dimensions are not allowed"))
     try:
-        support.product(shape)
+        support.product_check(shape)
     except OverflowError:
-        raise OperationError(space.w_ValueError, space.wrap(
-            "array is too big."))
+        raise oefmt(space.w_ValueError, "array is too big.")
     return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
 
 def empty(space, w_shape, w_dtype=None, w_order=None):
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -6,6 +6,7 @@
 from rpython.rlib import jit
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rawstorage import RAW_STORAGE_PTR
+from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rtyper.lltypesystem import rffi
 from rpython.tool.sourcetools import func_with_new_name
 from pypy.module.micronumpy import descriptor, ufuncs, boxes, arrayops, loop, \
@@ -611,6 +612,7 @@
                 "__array__(dtype) not implemented"))
         if type(self) is W_NDimArray:
             return self
+        # sz cannot overflow since self is valid
         sz = support.product(self.get_shape()) * self.get_dtype().elsize
         return W_NDimArray.from_shape_and_storage(
             space, self.get_shape(), self.implementation.storage,
@@ -1405,9 +1407,9 @@
         return W_NDimArray.from_shape(space, shape, dtype, order)
     strides, backstrides = calc_strides(shape, dtype.base, order)
     try:
-        totalsize = support.product(shape) * dtype.base.elsize
+        totalsize = ovfcheck(support.product_check(shape) * dtype.base.elsize)
     except OverflowError as e:
-        raise oefmt(space.w_ValueError, "array is too big")
+        raise oefmt(space.w_ValueError, "array is too big.")
     impl = ConcreteArray(shape, dtype.base, order, strides, backstrides)
     w_ret = space.allocate_instance(W_NDimArray, w_subtype)
     W_NDimArray.__init__(w_ret, impl)
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -32,13 +32,19 @@
 def product(s):
     i = 1
     for x in s:
+        i *= x
+    return i
+
+ at jit.unroll_safe
+def product_check(s):
+    i = 1
+    for x in s:
         try:
             i = ovfcheck(i * x)
         except OverflowError:
             raise
     return i
 
-
 def check_and_adjust_index(space, index, size, axis):
     if index < -size or index >= size:
         if axis >= 0:
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -270,7 +270,7 @@
         exc = raises(ValueError, ndarray, [1,2,256]*10000)
         assert exc.value[0] == 'sequence too large; must be smaller than 32'
         exc = raises(ValueError, ndarray, [1,2,256]*10)
-        assert exc.value[0] == 'array is too big'
+        assert exc.value[0] == 'array is too big.'
 
     def test_ndmin(self):
         from numpy import array
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -1006,7 +1006,6 @@
             assert isinstance(curarg, W_NDimArray)
             if len(arg_shapes[i]) != curarg.ndims():
                 # reshape
-
                 sz = product(curarg.get_shape()) * curarg.get_dtype().elsize
                 with curarg.implementation as storage:
                     inargs[i] = W_NDimArray.from_shape_and_storage(
diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -8,16 +8,18 @@
         'set_param':    'interp_jit.set_param',
         'residual_call': 'interp_jit.residual_call',
         'not_from_assembler': 'interp_jit.W_NotFromAssembler',
-        #'set_compile_hook': 'interp_resop.set_compile_hook',
-        #'set_optimize_hook': 'interp_resop.set_optimize_hook',
-        #'set_abort_hook': 'interp_resop.set_abort_hook',
-        #'get_stats_snapshot': 'interp_resop.get_stats_snapshot',
-        #'enable_debug': 'interp_resop.enable_debug',
-        #'disable_debug': 'interp_resop.disable_debug',
-        #'ResOperation': 'interp_resop.WrappedOp',
-        #'DebugMergePoint': 'interp_resop.DebugMergePoint',
-        #'JitLoopInfo': 'interp_resop.W_JitLoopInfo',
-        #'Box': 'interp_resop.WrappedBox',
+        'get_jitcell_at_key': 'interp_jit.get_jitcell_at_key',
+        'dont_trace_here': 'interp_jit.dont_trace_here',
+        'trace_next_iteration': 'interp_jit.trace_next_iteration',
+        'trace_next_iteration_hash': 'interp_jit.trace_next_iteration_hash',
+        'set_compile_hook': 'interp_resop.set_compile_hook',
+        'set_abort_hook': 'interp_resop.set_abort_hook',
+        'get_stats_snapshot': 'interp_resop.get_stats_snapshot',
+        'enable_debug': 'interp_resop.enable_debug',
+        'disable_debug': 'interp_resop.disable_debug',
+        'ResOperation': 'interp_resop.WrappedOp',
+        'DebugMergePoint': 'interp_resop.DebugMergePoint',
+        'JitLoopInfo': 'interp_resop.W_JitLoopInfo',
         'PARAMETER_DOCS': 'space.wrap(rpython.rlib.jit.PARAMETER_DOCS)',
     }
 
diff --git a/pypy/module/pypyjit/hooks.py b/pypy/module/pypyjit/hooks.py
--- a/pypy/module/pypyjit/hooks.py
+++ b/pypy/module/pypyjit/hooks.py
@@ -35,10 +35,10 @@
         self._compile_hook(debug_info, is_bridge=True)
 
     def before_compile(self, debug_info):
-        self._optimize_hook(debug_info, is_bridge=False)
+        pass
 
     def before_compile_bridge(self, debug_info):
-        self._optimize_hook(debug_info, is_bridge=True)
+        pass
 
     def _compile_hook(self, debug_info, is_bridge):
         space = self.space
@@ -46,7 +46,8 @@
         if cache.in_recursion:
             return
         if space.is_true(cache.w_compile_hook):
-            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
+            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge,
+                                         cache.compile_hook_with_ops)
             cache.in_recursion = True
             try:
                 try:
@@ -57,33 +58,4 @@
             finally:
                 cache.in_recursion = False
 
-    def _optimize_hook(self, debug_info, is_bridge=False):
-        space = self.space
-        cache = space.fromcache(Cache)
-        if cache.in_recursion:
-            return
-        if space.is_true(cache.w_optimize_hook):
-            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
-            cache.in_recursion = True
-            try:
-                try:
-                    w_res = space.call_function(cache.w_optimize_hook,
-                                                space.wrap(w_debug_info))
-                    if space.is_w(w_res, space.w_None):
-                        return
-                    l = []
-                    for w_item in space.listview(w_res):
-                        item = space.interp_w(WrappedOp, w_item)
-                        l.append(jit_hooks._cast_to_resop(item.op))
-                    del debug_info.operations[:] # modifying operations above is
-                    # probably not a great idea since types may not work
-                    # and we'll end up with half-working list and
-                    # a segfault/fatal RPython error
-                    for elem in l:
-                        debug_info.operations.append(elem)
-                except OperationError, e:
-                    e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
-            finally:
-                cache.in_recursion = False
-
 pypy_hooks = PyPyJitIface()
diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -5,11 +5,14 @@
 
 from rpython.rlib.rarithmetic import r_uint, intmask
 from rpython.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
-from rpython.rlib import jit
-from rpython.rlib.jit import current_trace_length, unroll_parameters
+from rpython.rlib import jit, jit_hooks
+from rpython.rlib.jit import current_trace_length, unroll_parameters,\
+     JitHookInterface
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 import pypy.interpreter.pyopcode   # for side-effects
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.pycode import CO_GENERATOR, PyCode
+from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pyopcode import ExitFrame, Yield
 from pypy.interpreter.baseobjspace import W_Root
@@ -188,3 +191,100 @@
     __call__ = interp2app(W_NotFromAssembler.descr_call),
 )
 W_NotFromAssembler.typedef.acceptable_as_base_class = False
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at dont_look_inside
+def get_jitcell_at_key(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    return space.wrap(bool(jit_hooks.get_jitcell_at_key(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)))
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at dont_look_inside
+def dont_trace_here(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    jit_hooks.dont_trace_here(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)
+    return space.w_None
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at dont_look_inside
+def trace_next_iteration(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    jit_hooks.trace_next_iteration(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)
+    return space.w_None
+
+ at unwrap_spec(hash=r_uint)
+ at dont_look_inside
+def trace_next_iteration_hash(space, hash):
+    jit_hooks.trace_next_iteration_hash('pypyjit', hash)
+    return space.w_None
+
+# class Cache(object):
+#     in_recursion = False
+
+#     def __init__(self, space):
+#         self.w_compile_bridge = space.w_None
+#         self.w_compile_loop = space.w_None
+
+# def set_compile_bridge(space, w_hook):
+#     cache = space.fromcache(Cache)
+#     assert w_hook is not None
+#     cache.w_compile_bridge = w_hook
+
+# def set_compile_loop(space, w_hook):
+#     from rpython.rlib.nonconst import NonConstant
+    
+#     cache = space.fromcache(Cache)
+#     assert w_hook is not None
+#     cache.w_compile_loop = w_hook
+#     cache.in_recursion = NonConstant(False)
+
+# class PyPyJitHookInterface(JitHookInterface):
+#     def after_compile(self, debug_info):
+#         space = self.space
+#         cache = space.fromcache(Cache)
+#         if cache.in_recursion:
+#             return
+#         l_w = []
+#         if not space.is_true(cache.w_compile_loop):
+#             return
+#         for i, op in enumerate(debug_info.operations):
+#             if op.is_guard():
+#                 w_t = space.newtuple([space.wrap(i), space.wrap(op.getopnum()), space.wrap(op.getdescr().get_jitcounter_hash())])
+#                 l_w.append(w_t)
+#         try:
+#             cache.in_recursion = True
+#             try:
+#                 space.call_function(cache.w_compile_loop, space.newlist(l_w))
+#             except OperationError, e:
+#                 e.write_unraisable(space, "jit hook ", cache.w_compile_bridge)
+#         finally:
+#             cache.in_recursion = False
+
+#     def after_compile_bridge(self, debug_info):
+#         space = self.space
+#         cache = space.fromcache(Cache)
+#         if cache.in_recursion:
+#             return
+#         if not space.is_true(cache.w_compile_bridge):
+#             return
+#         w_hash = space.wrap(debug_info.fail_descr.get_jitcounter_hash())
+#         try:
+#             cache.in_recursion = True
+#             try:
+#                 space.call_function(cache.w_compile_bridge, w_hash)
+#             except OperationError, e:
+#                 e.write_unraisable(space, "jit hook ", cache.w_compile_bridge)
+#         finally:
+#             cache.in_recursion = False
+
+#     def before_compile(self, debug_info):
+#         pass
+
+#     def before_compile_bridge(self, debug_info):
+#         pass
+
+# pypy_hooks = PyPyJitHookInterface()
+
diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -22,7 +22,6 @@
     def __init__(self, space):
         self.w_compile_hook = space.w_None
         self.w_abort_hook = space.w_None
-        self.w_optimize_hook = space.w_None
 
     def getno(self):
         self.no += 1
@@ -43,8 +42,9 @@
     else:
         return space.wrap(greenkey_repr)
 
-def set_compile_hook(space, w_hook):
-    """ set_compile_hook(hook)
+ at unwrap_spec(operations=bool)
+def set_compile_hook(space, w_hook, operations=True):
+    """ set_compile_hook(hook, operations=True)
 
     Set a compiling hook that will be called each time a loop is compiled.
 
@@ -58,25 +58,9 @@
     cache = space.fromcache(Cache)
     assert w_hook is not None
     cache.w_compile_hook = w_hook
+    cache.compile_hook_with_ops = operations
     cache.in_recursion = NonConstant(False)
 
-def set_optimize_hook(space, w_hook):
-    """ set_optimize_hook(hook)
-
-    Set a compiling hook that will be called each time a loop is optimized,
-    but before assembler compilation. This allows adding additional
-    optimizations on Python level.
-
-    The hook will be called with the pypyjit.JitLoopInfo object. Refer to it's
-    docstring for details.
-
-    Result value will be the resulting list of operations, or None
-    """
-    cache = space.fromcache(Cache)
-    cache.w_optimize_hook = w_hook
-    cache.in_recursion = NonConstant(False)
-
-
 def set_abort_hook(space, w_hook):
     """ set_abort_hook(hook)
 
@@ -96,6 +80,9 @@
     cache.in_recursion = NonConstant(False)
 
 def wrap_oplist(space, logops, operations, ops_offset=None):
+    # this function is called from the JIT
+    from rpython.jit.metainterp.resoperation import rop
+    
     l_w = []
     jitdrivers_sd = logops.metainterp_sd.jitdrivers_sd
     for op in operations:
@@ -103,117 +90,58 @@
             ofs = -1
         else:
             ofs = ops_offset.get(op, 0)
-        if op.opnum == rop.DEBUG_MERGE_POINT:
+        num = op.getopnum()
+        name = op.getopname()
+        if num == rop.DEBUG_MERGE_POINT:
             jd_sd = jitdrivers_sd[op.getarg(0).getint()]
             greenkey = op.getarglist()[3:]
             repr = jd_sd.warmstate.get_location_str(greenkey)
             w_greenkey = wrap_greenkey(space, jd_sd.jitdriver, greenkey, repr)
-            l_w.append(DebugMergePoint(space, jit_hooks._cast_to_gcref(op),
+            l_w.append(DebugMergePoint(space, name,
                                        logops.repr_of_resop(op),
                                        jd_sd.jitdriver.name,
                                        op.getarg(1).getint(),
                                        op.getarg(2).getint(),
                                        w_greenkey))
         else:
-            l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs,
-                                 logops.repr_of_resop(op)))
+            l_w.append(WrappedOp(name, ofs, logops.repr_of_resop(op)))
     return l_w
 
+ at unwrap_spec(offset=int, repr=str, name=str)
+def descr_new_resop(space, w_tp, name, offset=-1, repr=''):
+    return WrappedOp(name, offset, repr)
 
-class WrappedBox(W_Root):
-    """ A class representing a single box
-    """
-    def __init__(self, llbox):
-        self.llbox = llbox
-
-    def descr_getint(self, space):
-        if not jit_hooks.box_isint(self.llbox):
-            raise OperationError(space.w_NotImplementedError,
-                                 space.wrap("Box has no int value"))
-        return space.wrap(jit_hooks.box_getint(self.llbox))
-
- at unwrap_spec(no=int)
-def descr_new_box(space, w_tp, no):
-    return WrappedBox(jit_hooks.boxint_new(no))
-
-WrappedBox.typedef = TypeDef(
-    'Box',
-    __new__ = interp2app(descr_new_box),
-    getint = interp2app(WrappedBox.descr_getint),
-)
-
- at unwrap_spec(num=int, offset=int, repr=str, w_res=W_Root)
-def descr_new_resop(space, w_tp, num, w_args, w_res, offset=-1,
-                    repr=''):
-    args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
-            space.listview(w_args)]
-    if space.is_none(w_res):
-        llres = jit_hooks.emptyval()
-    else:
-        if not isinstance(w_res, WrappedBox):
-            raise OperationError(space.w_TypeError, space.wrap(
-                "expected box type, got %s" % space.type(w_res)))
-        llres = w_res.llbox
-    return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr)
-
- at unwrap_spec(repr=str, jd_name=str, call_depth=int, call_id=int)
-def descr_new_dmp(space, w_tp, w_args, repr, jd_name, call_depth, call_id,
+ at unwrap_spec(repr=str, name=str, jd_name=str, call_depth=int, call_id=int)
+def descr_new_dmp(space, w_tp, name, repr, jd_name, call_depth, call_id,
     w_greenkey):
 
-    args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
-            space.listview(w_args)]
-    num = rop.DEBUG_MERGE_POINT
-    return DebugMergePoint(space,
-                           jit_hooks.resop_new(num, args, jit_hooks.emptyval()),
+    return DebugMergePoint(space, name,
                            repr, jd_name, call_depth, call_id, w_greenkey)
 
 
 class WrappedOp(W_Root):
     """ A class representing a single ResOperation, wrapped nicely
     """
-    def __init__(self, op, offset, repr_of_resop):
-        self.op = op
+    def __init__(self, name, offset, repr_of_resop):
         self.offset = offset
+        self.name = name
         self.repr_of_resop = repr_of_resop
 
     def descr_repr(self, space):
         return space.wrap(self.repr_of_resop)
 
-    def descr_num(self, space):
-        return space.wrap(jit_hooks.resop_getopnum(self.op))
-
     def descr_name(self, space):
-        return space.wrap(hlstr(jit_hooks.resop_getopname(self.op)))
-
-    @unwrap_spec(no=int)
-    def descr_getarg(self, space, no):
-        try:
-            box = jit_hooks.resop_getarg(self.op, no)
-        except IndexError:
-            raise OperationError(space.w_IndexError,
-                                 space.wrap("Index out of range"))
-        return WrappedBox(box)
-
-    @unwrap_spec(no=int, w_box=WrappedBox)
-    def descr_setarg(self, space, no, w_box):
-        jit_hooks.resop_setarg(self.op, no, w_box.llbox)
-
-    def descr_getresult(self, space):
-        return WrappedBox(jit_hooks.resop_getresult(self.op))
-
-    def descr_setresult(self, space, w_box):
-        box = space.interp_w(WrappedBox, w_box)
-        jit_hooks.resop_setresult(self.op, box.llbox)
+        return space.wrap(self.name)
 
 class DebugMergePoint(WrappedOp):
     """ A class representing Debug Merge Point - the entry point
     to a jitted loop.
     """
 
-    def __init__(self, space, op, repr_of_resop, jd_name, call_depth, call_id,
-        w_greenkey):
+    def __init__(self, space, name, repr_of_resop, jd_name, call_depth,
+                 call_id, w_greenkey):
 
-        WrappedOp.__init__(self, op, -1, repr_of_resop)
+        WrappedOp.__init__(self, name, -1, repr_of_resop)
         self.jd_name = jd_name
         self.call_depth = call_depth
         self.call_id = call_id
@@ -237,12 +165,7 @@
     __doc__ = WrappedOp.__doc__,
     __new__ = interp2app(descr_new_resop),
     __repr__ = interp2app(WrappedOp.descr_repr),
-    num = GetSetProperty(WrappedOp.descr_num),
     name = GetSetProperty(WrappedOp.descr_name),
-    getarg = interp2app(WrappedOp.descr_getarg),
-    setarg = interp2app(WrappedOp.descr_setarg),
-    result = GetSetProperty(WrappedOp.descr_getresult,
-                            WrappedOp.descr_setresult),
     offset = interp_attrproperty("offset", cls=WrappedOp),
 )
 WrappedOp.typedef.acceptable_as_base_class = False
@@ -278,14 +201,18 @@
     asmaddr     = 0
     asmlen      = 0
 
-    def __init__(self, space, debug_info, is_bridge=False):
-        logops = debug_info.logger._make_log_operations()
-        if debug_info.asminfo is not None:
-            ofs = debug_info.asminfo.ops_offset
+    def __init__(self, space, debug_info, is_bridge=False, wrap_ops=True):
+        if wrap_ops:
+            memo = {}
+            logops = debug_info.logger._make_log_operations(memo)
+            if debug_info.asminfo is not None:
+                ofs = debug_info.asminfo.ops_offset
+            else:
+                ofs = {}
+            ops = debug_info.operations
+            self.w_ops = space.newlist(wrap_oplist(space, logops, ops, ofs))
         else:
-            ofs = {}
-        self.w_ops = space.newlist(
-            wrap_oplist(space, logops, debug_info.operations, ofs))
+            self.w_ops = space.w_None
 
         self.jd_name = debug_info.get_jitdriver().name
         self.type = debug_info.type
diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py
--- a/pypy/module/pypyjit/test/test_jit_hook.py
+++ b/pypy/module/pypyjit/test/test_jit_hook.py
@@ -136,7 +136,6 @@
         assert dmp.call_id == 0
         assert dmp.offset == -1
         assert int_add.name == 'int_add'
-        assert int_add.num == self.int_add_num
         assert int_add.offset == 0
         self.on_compile_bridge()
         expected = ('<JitLoopInfo pypyjit, 4 operations, starting at '
@@ -173,10 +172,7 @@
         self.on_compile()
         loop = loops[0]
         op = loop.operations[2]
-        # Should not crash the interpreter
-        raises(IndexError, op.getarg, 2)
         assert op.name == 'guard_nonnull'
-        raises(NotImplementedError, op.getarg(0).getint)
 
     def test_non_reentrant(self):
         import pypyjit
@@ -234,35 +230,28 @@
         assert l == ['pypyjit']
 
     def test_creation(self):
-        from pypyjit import Box, ResOperation
+        from pypyjit import ResOperation
 
-        op = ResOperation(self.int_add_num, [Box(1), Box(3)], Box(4))
-        assert op.num == self.int_add_num
+        op = ResOperation("int_add", -1, "int_add(1, 2)")
         assert op.name == 'int_add'
-        box = op.getarg(0)
-        assert box.getint() == 1
-        box2 = op.result
-        assert box2.getint() == 4
-        op.setarg(0, box2)
-        assert op.getarg(0).getint() == 4
-        op.result = box
-        assert op.result.getint() == 1
+        assert repr(op) == "int_add(1, 2)"
 
     def test_creation_dmp(self):
-        from pypyjit import DebugMergePoint, Box
+        from pypyjit import DebugMergePoint
 
         def f():
             pass
 
-        op = DebugMergePoint([Box(0)], 'repr', 'pypyjit', 2, 3, (f.func_code, 0, 0))
+        op = DebugMergePoint("debug_merge_point", 'repr', 'pypyjit', 2, 3, (f.func_code, 0, 0))
         assert op.bytecode_no == 0
         assert op.pycode is f.func_code
         assert repr(op) == 'repr'
         assert op.jitdriver_name == 'pypyjit'
-        assert op.num == self.dmp_num
+        assert op.name == 'debug_merge_point'
         assert op.call_depth == 2
         assert op.call_id == 3
-        op = DebugMergePoint([Box(0)], 'repr', 'notmain', 5, 4, ('str',))
+        op = DebugMergePoint('debug_merge_point', 'repr', 'notmain',
+                             5, 4, ('str',))
         raises(AttributeError, 'op.pycode')
         assert op.call_depth == 5
 
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
@@ -422,11 +422,11 @@
         i114 = int_ne(i160, i112)
         guard_false(i114, descr=...)
         --TICK--
+        i123 = arraylen_gc(p67, descr=<ArrayP .>)
         i119 = call_i(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, descr=<Calli . i EF=5 OS=110>)
         raw_store(i119, 0, i160, descr=<ArrayS 2>)
         raw_store(i119, 2, i160, descr=<ArrayS 2>)
         raw_store(i119, 4, i160, descr=<ArrayS 2>)
         setfield_gc(p167, i119, descr=<FieldU pypy.module._cffi_backend.cdataobj.W_CData.inst__ptr .+>)
-        i123 = arraylen_gc(p67, descr=<ArrayP .>)
         jump(..., descr=...)
         """)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
--- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
@@ -47,7 +47,7 @@
             i31 = getfield_gc_pure_i(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_size \d+>)
             i32 = int_ge(i25, i31)
             guard_false(i32, descr=...)
-            p34 = new_with_vtable(#)
+            p34 = new_with_vtable(descr=...)
             {{{
             setfield_gc(p34, p1, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst_iterator \d+>)
             setfield_gc(p34, i25, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>)
@@ -154,7 +154,7 @@
             f86 = float_add(f74, f85)
             i87 = int_add(i76, 1)
             --TICK--
-            jump(p0, p1, p6, p7, p8, p11, p13, f86, p17, i87, i62, p42, i58, p48, i41, i64, i70, descr=...)
+            jump(..., descr=...)
         """)
 
     def test_array_flatiter_next(self):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py
--- a/pypy/module/pypyjit/test_pypy_c/test_misc.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py
@@ -148,6 +148,7 @@
         i18 = force_token()
         setfield_gc(p9, i17, descr=<.* .*W_XRangeIterator.inst_current .*>)
         guard_not_invalidated(descr=...)
+        i84 = int_sub(i14, 1)
         i21 = int_lt(i10, 0)
         guard_false(i21, descr=...)
         i22 = int_lt(i10, i14)
@@ -180,6 +181,7 @@
             i21 = force_token()
             setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>)
             guard_not_invalidated?
+            i88 = int_sub(i9, 1)
             i25 = int_ge(i11, i9)
             guard_false(i25, descr=...)
             i27 = int_add_ovf(i7, i11)
@@ -212,6 +214,7 @@
             i21 = force_token()
             setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>)
             guard_not_invalidated?
+            i95 = int_sub(i9, 1)
             i23 = int_lt(i18, 0)
             guard_false(i23, descr=...)
             i25 = int_ge(i18, i9)
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -385,7 +385,8 @@
 
 class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeCodePoint)):
     def union((uchr1, uchr2)):
-        return SomeUnicodeCodePoint()
+        no_nul = uchr1.no_nul and uchr2.no_nul
+        return SomeUnicodeCodePoint(no_nul=no_nul)
 
     def add((chr1, chr2)):
         return SomeUnicodeString()
@@ -598,32 +599,33 @@
 
 class __extend__(pairtype(SomeUnicodeString, SomeInteger)):
     def getitem((str1, int2)):
-        return SomeUnicodeCodePoint()
+        return SomeUnicodeCodePoint(no_nul=str1.no_nul)
     getitem.can_only_throw = []
 
     def getitem_idx((str1, int2)):
-        return SomeUnicodeCodePoint()
+        return SomeUnicodeCodePoint(no_nul=str1.no_nul)
     getitem_idx.can_only_throw = [IndexError]
 
     def mul((str1, int2)): # xxx do we want to support this
-        return SomeUnicodeString()
+        return SomeUnicodeString(no_nul=str1.no_nul)
 
 class __extend__(pairtype(SomeInteger, SomeString),
                  pairtype(SomeInteger, SomeUnicodeString)):
 
     def mul((int1, str2)): # xxx do we want to support this
-        return str2.basestringclass()
+        return str2.basestringclass(no_nul=str2.no_nul)
 
 class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeString),
                  pairtype(SomeUnicodeString, SomeUnicodeCodePoint),
                  pairtype(SomeUnicodeString, SomeUnicodeString)):
     def union((str1, str2)):
-        return SomeUnicodeString(can_be_None=str1.can_be_none() or
-                                 str2.can_be_none())
+        can_be_None = str1.can_be_None or str2.can_be_None
+        no_nul = str1.no_nul and str2.no_nul
+        return SomeUnicodeString(can_be_None=can_be_None, no_nul=no_nul)
 
     def add((str1, str2)):
         # propagate const-ness to help getattr(obj, 'prefix' + const_name)
-        result = SomeUnicodeString()
+        result = SomeUnicodeString(no_nul=str1.no_nul and str2.no_nul)
         if str1.is_immutable_constant() and str2.is_immutable_constant():
             result.const = str1.const + str2.const
         return result
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -237,10 +237,11 @@
             else:
                 result = SomeString(no_nul=no_nul)
         elif tp is unicode:
+            no_nul = not u'\x00' in x
             if len(x) == 1:
-                result = SomeUnicodeCodePoint()
+                result = SomeUnicodeCodePoint(no_nul=no_nul)
             else:
-                result = SomeUnicodeString()
+                result = SomeUnicodeString(no_nul=no_nul)
         elif tp is bytearray:
             result = SomeByteArray()
         elif tp is tuple:
diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -438,6 +438,18 @@
         assert s.knowntype == str
         assert s.no_nul
 
+    def test_unicode_join(self):
+        a = self.RPythonAnnotator()
+        def g(n):
+            if n:
+                return [u"foo", u"bar"]
+        def f(n):
+            g(0)
+            return u''.join(g(n))
+        s = a.build_types(f, [int])
+        assert s.knowntype == unicode
+        assert s.no_nul
+
     def test_str_split(self):
         a = self.RPythonAnnotator()
         def g(n):
@@ -451,6 +463,19 @@
         s_item = s.listdef.listitem.s_value
         assert s_item.no_nul
 
+    def test_unicode_split(self):
+        a = self.RPythonAnnotator()
+        def g(n):
+            if n:
+                return u"test string"
+        def f(n):
+            if n:
+                return g(n).split(u' ')
+        s = a.build_types(f, [int])
+        assert isinstance(s, annmodel.SomeList)
+        s_item = s.listdef.listitem.s_value
+        assert s_item.no_nul
+
     def test_str_split_nul(self):
         def f(n):
             return n.split('\0')[0]
@@ -470,6 +495,27 @@
         assert not s.can_be_None
         assert not s.no_nul
 
+    def test_unicode_split_nul(self):
+        def f(n):
+            return n.split(u'\0')[0]
+        a = self.RPythonAnnotator()
+        a.translator.config.translation.check_str_without_nul = True
+        s = a.build_types(f, [annmodel.SomeUnicodeString(
+                                  no_nul=False, can_be_None=False)])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert not s.can_be_None
+        assert s.no_nul
+
+        def g(n):
+            return n.split(u'\0', 1)[0]
+        a = self.RPythonAnnotator()
+        a.translator.config.translation.check_str_without_nul = True
+        s = a.build_types(g, [annmodel.SomeUnicodeString(
+                                  no_nul=False, can_be_None=False)])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert not s.can_be_None
+        assert not s.no_nul
+
     def test_str_splitlines(self):
         a = self.RPythonAnnotator()
         def f(a_str):
@@ -490,6 +536,18 @@
         s = a.build_types(f, [int, annmodel.SomeString(no_nul=True)])
         assert s.no_nul
 
+    def test_unicode_strip(self):
+        a = self.RPythonAnnotator()
+        def f(n, a_str):
+            if n == 0:
+                return a_str.strip(u' ')
+            elif n == 1:
+                return a_str.rstrip(u' ')
+            else:
+                return a_str.lstrip(u' ')
+        s = a.build_types(f, [int, annmodel.SomeUnicodeString(no_nul=True)])
+        assert s.no_nul
+
     def test_str_mul(self):
         a = self.RPythonAnnotator()
         def f(a_str):
@@ -2042,6 +2100,17 @@
         assert s.can_be_None
         assert s.no_nul
 
+    def test_unicode_noNUL_canbeNone(self):
+        def f(a):
+            if a:
+                return u"abc"
+            else:
+                return None
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert s.can_be_None
+        assert s.no_nul
+
     def test_str_or_None(self):
         def f(a):
             if a:
@@ -2058,6 +2127,22 @@
         assert s.can_be_None
         assert s.no_nul
 
+    def test_unicode_or_None(self):
+        def f(a):
+            if a:
+                return u"abc"
+            else:
+                return None
+        def g(a):
+            x = f(a)
+            if x is None:
+                return u"abcd"
+            return x
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert s.can_be_None
+        assert s.no_nul
+
     def test_emulated_pbc_call_simple(self):
         def f(a,b):
             return a + b
@@ -2124,6 +2209,19 @@
         assert isinstance(s, annmodel.SomeString)
         assert s.no_nul
 
+    def test_iteritems_unicode0(self):
+        def it(d):
+            return d.iteritems()
+        def f():
+            d0 = {u'1a': u'2a', u'3': u'4'}
+            for item in it(d0):
+                return u"%s=%s" % item
+            raise ValueError
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
+
     def test_no_nul_mod(self):
         def f(x):
             s = "%d" % x
@@ -2133,6 +2231,14 @@
         assert isinstance(s, annmodel.SomeString)
         assert s.no_nul
 
+    def test_no_nul_mod_unicode(self):
+        def f(x):
+            s = u"%d" % x
+            return s
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
 
     def test_mul_str0(self):
         def f(s):
@@ -2142,6 +2248,24 @@
         assert isinstance(s, annmodel.SomeString)
         assert s.no_nul
 
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
+
+    def test_reverse_mul_str0(self):
+        def f(s):
+            return 10*s
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeString(no_nul=True)])
+        assert isinstance(s, annmodel.SomeString)
+        assert s.no_nul
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
+
     def test_getitem_str0(self):
         def f(s, n):
             if n == 1:
@@ -2153,12 +2277,18 @@
             return s
         a = self.RPythonAnnotator()
         a.translator.config.translation.check_str_without_nul = True
-
         s = a.build_types(f, [annmodel.SomeString(no_nul=True),
                               annmodel.SomeInteger()])
         assert isinstance(s, annmodel.SomeString)
         assert s.no_nul
 
+        a = self.RPythonAnnotator()
+        a.translator.config.translation.check_str_without_nul = True
+        s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True),
+                              annmodel.SomeInteger()])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
+
     def test_non_none_and_none_with_isinstance(self):
         class A(object):
             pass
@@ -3411,6 +3541,7 @@
         a = self.RPythonAnnotator()
         s = a.build_types(f, [unicode])
         assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.no_nul
 
     def test_unicode_char(self):
         def f(x, i):
@@ -3916,6 +4047,19 @@
         assert s.can_be_None
         assert s.no_nul
 
+    def test_contains_no_nul_unicode(self):
+        def f(i):
+            if u"\0" in i:
+                return None
+            else:
+                return i
+        a = self.RPythonAnnotator()
+        a.translator.config.translation.check_str_without_nul = True
+        s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=False)])
+        assert isinstance(s, annmodel.SomeUnicodeString)
+        assert s.can_be_None
+        assert s.no_nul
+
     def test_no___call__(self):
         class X(object):
             def __call__(self):
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -574,7 +574,9 @@
         return self.basecharclass()
 
     def method_split(self, patt, max=-1):
-        if max == -1 and patt.is_constant() and patt.const == "\0":
+        # special-case for .split( '\x00') or .split(u'\x00')
+        if max == -1 and patt.is_constant() and (
+               len(patt.const) == 1 and ord(patt.const) == 0):
             no_nul = True
         else:
             no_nul = self.no_nul
diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -16,10 +16,11 @@
 
 DEFL_GC = "incminimark"   # XXX
 
+DEFL_ROOTFINDER_WITHJIT = "shadowstack"
 if sys.platform.startswith("linux"):
-    DEFL_ROOTFINDER_WITHJIT = "asmgcc"
-else:
-    DEFL_ROOTFINDER_WITHJIT = "shadowstack"
+    _mach = os.popen('uname -m', 'r').read().strip()
+    if _mach.startswith('x86') or _mach in ['i386', 'i486', 'i586', 'i686']:
+        DEFL_ROOTFINDER_WITHJIT = "asmgcc"   # only for Linux on x86 / x86-64
 
 IS_64_BITS = sys.maxint > 2147483647
 
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -909,7 +909,7 @@
             descr.adr_jump_offset = failure_recovery_pos
             relative_offset = tok.pos_recovery_stub - tok.offset
             guard_pos = block_start + tok.offset
-            if not tok.is_guard_not_invalidated:
+            if not tok.guard_not_invalidated():
                 # patch the guard jump to the stub
                 # overwrite the generate NOP with a B_offs to the pos of the
                 # stub
diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -36,11 +36,9 @@
 
 class ArmGuardToken(GuardToken):
     def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
-                 offset, exc, frame_depth, is_guard_not_invalidated=False,
-                 is_guard_not_forced=False, fcond=c.AL):
+                 offset, guard_opnum, frame_depth, fcond=c.AL):
         GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
-                            exc, frame_depth, is_guard_not_invalidated,
-                            is_guard_not_forced)
+                            guard_opnum, frame_depth)
         self.fcond = fcond
         self.offset = offset
 
@@ -175,10 +173,7 @@
         self.mc.RSB_ri(resloc.value, l0.value, imm=0)
         return fcond
 
-    def build_guard_token(self, op, frame_depth, arglocs, offset, fcond, save_exc,
-                                    is_guard_not_invalidated=False,
-                                    is_guard_not_forced=False):
-        assert isinstance(save_exc, bool)
+    def build_guard_token(self, op, frame_depth, arglocs, offset, fcond):
         assert isinstance(fcond, int)
         descr = op.getdescr()
         assert isinstance(descr, AbstractFailDescr)
@@ -189,16 +184,12 @@
                                     failargs=op.getfailargs(),
                                     fail_locs=arglocs,
                                     offset=offset,
-                                    exc=save_exc,
+                                    guard_opnum=op.getopnum(),
                                     frame_depth=frame_depth,
-                                    is_guard_not_invalidated=is_guard_not_invalidated,
-                                    is_guard_not_forced=is_guard_not_forced,
                                     fcond=fcond)
         return token
 
-    def _emit_guard(self, op, arglocs, save_exc,
-                                    is_guard_not_invalidated=False,
-                                    is_guard_not_forced=False):
+    def _emit_guard(self, op, arglocs, is_guard_not_invalidated=False):
         if is_guard_not_invalidated:
             fcond = c.cond_none
         else:
@@ -206,10 +197,9 @@
             self.guard_success_cc = c.cond_none
             assert fcond != c.cond_none
         pos = self.mc.currpos()
-        token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond, save_exc,
-                                        is_guard_not_invalidated,
-                                        is_guard_not_forced)
+        token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond)
         self.pending_guards.append(token)
+        assert token.guard_not_invalidated() == is_guard_not_invalidated
         # For all guards that are not GUARD_NOT_INVALIDATED we emit a
         # breakpoint to ensure the location is patched correctly. In the case
         # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only
@@ -221,12 +211,12 @@
         return c.AL
 
     def emit_op_guard_true(self, op, arglocs, regalloc, fcond):
-        fcond = self._emit_guard(op, arglocs, save_exc=False)
+        fcond = self._emit_guard(op, arglocs)
         return fcond
 
     def emit_op_guard_false(self, op, arglocs, regalloc, fcond):
         self.guard_success_cc = c.get_opposite_of(self.guard_success_cc)
-        fcond = self._emit_guard(op, arglocs, save_exc=False)
+        fcond = self._emit_guard(op, arglocs)
         return fcond
 
     def emit_op_guard_value(self, op, arglocs, regalloc, fcond):
@@ -244,7 +234,7 @@
             self.mc.VCMP(l0.value, l1.value)
             self.mc.VMRS(cond=fcond)
         self.guard_success_cc = c.EQ
-        fcond = self._emit_guard(op, failargs, save_exc=False)
+        fcond = self._emit_guard(op, failargs)
         return fcond
 
     emit_op_guard_nonnull = emit_op_guard_true
@@ -256,14 +246,14 @@
     def emit_op_guard_class(self, op, arglocs, regalloc, fcond):
         self._cmp_guard_class(op, arglocs, regalloc, fcond)
         self.guard_success_cc = c.EQ
-        self._emit_guard(op, arglocs[2:], save_exc=False)
+        self._emit_guard(op, arglocs[2:])
         return fcond
 
     def emit_op_guard_nonnull_class(self, op, arglocs, regalloc, fcond):
         self.mc.CMP_ri(arglocs[0].value, 1)
         self._cmp_guard_class(op, arglocs, regalloc, c.HS)
         self.guard_success_cc = c.EQ
-        self._emit_guard(op, arglocs[2:], save_exc=False)
+        self._emit_guard(op, arglocs[2:])
         return fcond
 
     def _cmp_guard_class(self, op, locs, regalloc, fcond):
@@ -288,7 +278,7 @@
     def emit_op_guard_gc_type(self, op, arglocs, regalloc, fcond):
         self._cmp_guard_gc_type(arglocs[0], arglocs[1].value, fcond)
         self.guard_success_cc = c.EQ
-        self._emit_guard(op, arglocs[2:], save_exc=False)
+        self._emit_guard(op, arglocs[2:])
         return fcond
 
     def emit_op_guard_is_object(self, op, arglocs, regalloc, fcond):
@@ -309,7 +299,7 @@
         self.mc.LDRB_rr(r.ip.value, r.ip.value, r.lr.value)
         self.mc.TST_ri(r.ip.value, imm=(IS_OBJECT_FLAG & 0xff))
         self.guard_success_cc = c.NE
-        self._emit_guard(op, arglocs[1:], save_exc=False)
+        self._emit_guard(op, arglocs[1:])
         return fcond
 
     def emit_op_guard_subclass(self, op, arglocs, regalloc, fcond):
@@ -353,12 +343,11 @@
             self.mc.CMP_rr(r.ip.value, r.lr.value)
         # the guard passes if we get a result of "below or equal"
         self.guard_success_cc = c.LS
-        self._emit_guard(op, arglocs[2:], save_exc=False)
+        self._emit_guard(op, arglocs[2:])
         return fcond
 
     def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond):
-        return self._emit_guard(op, locs, save_exc=False,
-                                            is_guard_not_invalidated=True)
+        return self._emit_guard(op, locs, is_guard_not_invalidated=True)
 
     def emit_op_label(self, op, arglocs, regalloc, fcond):
         self._check_frame_depth_debug(self.mc)
@@ -498,7 +487,7 @@
         self.mc.LDR_ri(loc.value, loc.value)
         self.mc.CMP_ri(loc.value, 0)
         self.guard_success_cc = c.EQ
-        fcond = self._emit_guard(op, failargs, save_exc=True)
+        fcond = self._emit_guard(op, failargs)
         # If the previous operation was a COND_CALL, overwrite its conditional
         # jump to jump over this GUARD_NO_EXCEPTION as well, if we can
         if self._find_nearby_operation(-1).getopnum() == rop.COND_CALL:
@@ -515,7 +504,7 @@
 
         self.mc.CMP_rr(r.ip.value, loc.value)
         self.guard_success_cc = c.EQ
-        self._emit_guard(op, failargs, save_exc=True)
+        self._emit_guard(op, failargs)
         self._store_and_reset_exception(self.mc, resloc)
         return fcond
 
@@ -1047,7 +1036,7 @@
 
     def store_force_descr(self, op, fail_locs, frame_depth):
         pos = self.mc.currpos()
-        guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL, True, False, True)
+        guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL)
         #self.pending_guards.append(guard_token)
         self._finish_gcmap = guard_token.gcmap
         self._store_force_index(op)
@@ -1152,7 +1141,7 @@
         self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs)
         self.mc.CMP_ri(r.ip.value, 0)
         self.guard_success_cc = c.EQ
-        self._emit_guard(op, arglocs, save_exc=True, is_guard_not_forced=True)
+        self._emit_guard(op, arglocs)
         return fcond
 
     def _genop_call_may_force(self, op, arglocs, regalloc, fcond):
diff --git a/rpython/jit/backend/arm/test/support.py b/rpython/jit/backend/arm/test/support.py
--- a/rpython/jit/backend/arm/test/support.py
+++ b/rpython/jit/backend/arm/test/support.py
@@ -10,7 +10,9 @@
 class JitARMMixin(support.LLJitMixin):
     type_system = 'lltype'
     CPUClass = getcpuclass()
-    basic = True
+    # we have to disable unroll
+    enable_opts = "intbounds:rewrite:virtualize:string:earlyforce:pure:heap"
+    basic = False
 
     def check_jumps(self, maxcount):
         pass
diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py
--- a/rpython/jit/backend/arm/test/test_calling_convention.py
+++ b/rpython/jit/backend/arm/test/test_calling_convention.py
@@ -10,18 +10,14 @@
 from rpython.jit.backend.arm import registers as r
 from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests
 from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat
-from rpython.jit.metainterp.resoperation import ResOperation, rop
-from rpython.jit.metainterp.history import (AbstractFailDescr,
-                                         AbstractDescr,
-                                         BasicFailDescr,
-                                         BasicFinalDescr,
-                                         BoxInt, Box, BoxPtr,
-                                         JitCellToken, TargetToken,
-                                         ConstInt, ConstPtr,
-                                         BoxFloat, ConstFloat)
+from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat
+from rpython.jit.metainterp.history import JitCellToken
 
 skip_unless_run_slow_tests()
 
+boxint = InputArgInt
+boxfloat = InputArgFloat.fromfloat
+
 class TestARMCallingConvention(CallingConvTests):
     # ../../test/calling_convention_test.py
 
@@ -82,9 +78,9 @@
                                     EffectInfo.MOST_GENERAL)
         funcbox = self.get_funcbox(cpu, func_ptr)
         args = ([boxfloat(.1) for i in range(7)] +
-                [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3),
+                [boxint(1), boxfloat(.2), boxint(2), boxfloat(.3),
                  boxfloat(.4)])
-        res = self.execute_operation(rop.CALL,
+        res = self.execute_operation(rop.CALL_F,
                                      [funcbox] + args,
                                      'float', descr=calldescr)
         for i,j in enumerate(callargs[0]):
@@ -112,7 +108,7 @@
                                     EffectInfo.MOST_GENERAL)
         funcbox = self.get_funcbox(cpu, func_ptr)
         args = ([boxfloat(.1) for i in range(10)])
-        res = self.execute_operation(rop.CALL,
+        res = self.execute_operation(rop.CALL_F,
                                      [funcbox] + args,
                                      'float', descr=calldescr)
         for i,j in enumerate(callargs[0]):
@@ -134,8 +130,8 @@
         calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                     EffectInfo.MOST_GENERAL)
         funcbox = self.get_funcbox(cpu, func_ptr)
-        args = ([BoxInt(1) for i in range(10)])
-        res = self.execute_operation(rop.CALL,
+        args = ([boxint(1) for i in range(10)])
+        res = self.execute_operation(rop.CALL_I,
                                      [funcbox] + args,
                                      'int', descr=calldescr)
         for i,j in enumerate(callargs[0]):
diff --git a/rpython/jit/backend/arm/test/test_generated.py b/rpython/jit/backend/arm/test/test_generated.py
--- a/rpython/jit/backend/arm/test/test_generated.py
+++ b/rpython/jit/backend/arm/test/test_generated.py
@@ -1,4 +1,6 @@
 import py
+py.test.skip("XXX FIX ME OR KILL ME")
+
 from rpython.jit.metainterp.history import (AbstractFailDescr,
                                          AbstractDescr,
                                          BasicFailDescr,
diff --git a/rpython/jit/backend/arm/test/test_helper.py b/rpython/jit/backend/arm/test/test_helper.py
--- a/rpython/jit/backend/arm/test/test_helper.py
+++ b/rpython/jit/backend/arm/test/test_helper.py
@@ -1,6 +1,8 @@
 from rpython.jit.backend.arm.helper.assembler import count_reg_args
-from rpython.jit.metainterp.history import (BoxInt, BoxPtr, BoxFloat,
-                                        INT, REF, FLOAT)
+from rpython.jit.metainterp.history import INT, REF, FLOAT
+from rpython.jit.metainterp.resoperation import InputArgInt as BoxInt
+from rpython.jit.metainterp.resoperation import InputArgRef as BoxPtr
+from rpython.jit.metainterp.resoperation import InputArgFloat as BoxFloat
 
 
 def test_count_reg_args():
diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py
--- a/rpython/jit/backend/arm/test/test_regalloc.py
+++ b/rpython/jit/backend/arm/test/test_regalloc.py
@@ -215,14 +215,14 @@
     def test_exception_bridge_no_exception(self):
         ops = '''
         [i0]
-        i1 = same_as(1)
-        call(ConstClass(raising_fptr), i0, descr=raising_calldescr)
+        i1 = same_as_i(1)
+        call_n(ConstClass(raising_fptr), i0, descr=raising_calldescr)
         guard_exception(ConstClass(zero_division_error)) [i1]
         finish(0)
         '''
         bridge_ops = '''
         [i3]
-        i2 = same_as(2)
+        i2 = same_as_i(2)
         guard_no_exception() [i2]
         finish(1)
         '''
@@ -379,7 +379,7 @@
     def test_bug_wrong_stack_adj(self):
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7, i8]
-        i9 = same_as(0)
+        i9 = same_as_i(0)
         guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
         finish(1)
         '''
@@ -387,7 +387,7 @@
         assert self.getint(0) == 0
         bridge_ops = '''
         [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
-        call(ConstClass(raising_fptr), 0, descr=raising_calldescr)
+        call_n(ConstClass(raising_fptr), 0, descr=raising_calldescr)
         guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8]
         finish(1)
         '''
@@ -430,7 +430,7 @@
     def test_cmp_op_0(self):
         ops = '''
         [i0, i3]
-        i1 = same_as(1)
+        i1 = same_as_i(1)
         i2 = int_lt(i0, 100)
         guard_true(i3) [i1, i2]
         finish(i2)
@@ -630,7 +630,7 @@
     def test_one_call(self):
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
-        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        i10 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr)
         guard_true(i10), [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9]
         '''
         self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9])
@@ -639,8 +639,8 @@
     def test_two_calls(self):
         ops = '''
         [i0, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
-        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
-        i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
+        i10 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        i11 = call_i(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
         guard_true(i11) [i11, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
         '''
         self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9])
@@ -649,7 +649,7 @@
     def test_call_many_arguments(self):
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7]
-        i8 = call(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr)
+        i8 = call_i(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr)
         finish(i8)
         '''
         self.interpret(ops, [2, 3, 4, 5, 6, 7, 8, 9])
@@ -658,7 +658,7 @@
     def test_bridge_calls_1(self):
         ops = '''
         [i0, i1]
-        i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        i2 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr)
         guard_value(i2, 0, descr=fdescr1) [i2, i1]
         finish(i1)
         '''
@@ -666,7 +666,7 @@
         assert self.getint(0) == 5
         ops = '''
         [i2, i1]
-        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
+        i3 = call_i(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
         finish(i3)
         '''
         self.attach_bridge(ops, loop, -2)
@@ -677,7 +677,7 @@
     def test_bridge_calls_2(self):
         ops = '''
         [i0, i1]
-        i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr)
+        i2 = call_i(ConstClass(f2ptr), i0, i1, descr=f2_calldescr)
         guard_value(i2, 0, descr=fdescr1) [i2]
         finish(i1)
         '''
@@ -685,7 +685,7 @@
         assert self.getint(0) == 4 * 7
         ops = '''
         [i2]
-        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)
+        i3 = call_i(ConstClass(f1ptr), i2, descr=f1_calldescr)
         finish(i3)
         '''
         self.attach_bridge(ops, loop, -2)
@@ -734,7 +734,7 @@
         loop2 = """
         [i0]
         i1 = force_token()
-        i2 = call_assembler(1,2,3,4,5,6,7,8,9,10,11, descr=looptoken)
+        i2 = call_assembler_i(1,2,3,4,5,6,7,8,9,10,11, descr=looptoken)
         guard_not_forced() [i0]
         guard_false(i0) [i0, i2]
         """
@@ -749,23 +749,23 @@
         label(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, descr=targettoken)
         i11 = int_add(i0, 1)
         i12 = int_lt(i11, 2)
-        i13 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i14 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i15 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i16 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i17 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i18 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i19 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i20 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i21 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i22 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i23 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i24 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i26 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i27 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i28 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i29 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
-        i30 = call(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i13 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i14 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i15 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i16 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i17 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i18 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i19 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i20 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i21 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i22 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i23 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i24 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i26 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i27 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i28 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i29 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
+        i30 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr)
         guard_true(i12) [i11, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10]
         jump(i11, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, descr=targettoken)
         """
diff --git a/rpython/jit/backend/arm/test/test_regalloc2.py b/rpython/jit/backend/arm/test/test_regalloc2.py
deleted file mode 100644
--- a/rpython/jit/backend/arm/test/test_regalloc2.py
+++ /dev/null
@@ -1,281 +0,0 @@
-import py
-from rpython.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\
-     BoxPtr, ConstPtr, BasicFailDescr, BasicFinalDescr
-from rpython.jit.metainterp.history import JitCellToken
-from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.backend.detect_cpu import getcpuclass
-from rpython.jit.backend.arm.arch import WORD
-CPU = getcpuclass()
-
-def test_bug_rshift():
-    v1 = BoxInt()
-    v2 = BoxInt()
-    v3 = BoxInt()
-    v4 = BoxInt()
-    inputargs = [v1]
-    operations = [
-        ResOperation(rop.INT_ADD, [v1, v1], v2),
-        ResOperation(rop.INT_INVERT, [v2], v3),
-        ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4),
-        ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()),
-        ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(1)),
-        ]
-    operations[-2].setfailargs([v4, v3])
-    cpu = CPU(None, None)
-    cpu.setup_once()
-    looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
-    deadframe = cpu.execute_token(looptoken, 9)
-    assert cpu.get_int_value(deadframe, 0) == (9 >> 3)
-    assert cpu.get_int_value(deadframe, 1) == (~18)
-
-def test_bug_int_is_true_1():
-    v1 = BoxInt()
-    v2 = BoxInt()
-    v3 = BoxInt()
-    v4 = BoxInt()
-    tmp5 = BoxInt()
-    inputargs = [v1]
-    operations = [
-        ResOperation(rop.INT_MUL, [v1, v1], v2),
-        ResOperation(rop.INT_MUL, [v2, v1], v3),
-        ResOperation(rop.INT_IS_TRUE, [v2], tmp5),
-        ResOperation(rop.INT_IS_ZERO, [tmp5], v4),
-        ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()),
-        ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr()),
-            ]
-    operations[-2].setfailargs([v4, v3, tmp5])
-    cpu = CPU(None, None)
-    cpu.setup_once()
-    looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
-    deadframe = cpu.execute_token(looptoken, -10)
-    assert cpu.get_int_value(deadframe, 0) == 0
-    assert cpu.get_int_value(deadframe, 1) == -1000
-    assert cpu.get_int_value(deadframe, 2) == 1
-
-def test_bug_0():
-    v1 = BoxInt()
-    v2 = BoxInt()
-    v3 = BoxInt()
-    v4 = BoxInt()
-    v5 = BoxInt()
-    v6 = BoxInt()
-    v7 = BoxInt()
-    v8 = BoxInt()
-    v9 = BoxInt()
-    v10 = BoxInt()
-    v11 = BoxInt()
-    v12 = BoxInt()
-    v13 = BoxInt()
-    v14 = BoxInt()
-    v15 = BoxInt()
-    v16 = BoxInt()
-    v17 = BoxInt()
-    v18 = BoxInt()
-    v19 = BoxInt()
-    v20 = BoxInt()
-    v21 = BoxInt()
-    v22 = BoxInt()
-    v23 = BoxInt()
-    v24 = BoxInt()
-    v25 = BoxInt()
-    v26 = BoxInt()
-    v27 = BoxInt()
-    v28 = BoxInt()
-    v29 = BoxInt()
-    v30 = BoxInt()
-    v31 = BoxInt()
-    v32 = BoxInt()
-    v33 = BoxInt()
-    v34 = BoxInt()
-    v35 = BoxInt()
-    v36 = BoxInt()
-    v37 = BoxInt()
-    v38 = BoxInt()
-    v39 = BoxInt()
-    v40 = BoxInt()
-    tmp41 = BoxInt()
-    tmp42 = BoxInt()
-    tmp43 = BoxInt()
-    tmp44 = BoxInt()
-    tmp45 = BoxInt()
-    tmp46 = BoxInt()
-    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
-    operations = [
-        ResOperation(rop.UINT_GT, [v3, ConstInt(-48)], v11),
-        ResOperation(rop.INT_XOR, [v8, v1], v12),
-        ResOperation(rop.INT_GT, [v6, ConstInt(-9)], v13),
-        ResOperation(rop.INT_LE, [v13, v2], v14),
-        ResOperation(rop.INT_LE, [v11, v5], v15),
-        ResOperation(rop.UINT_GE, [v13, v13], v16),
-        ResOperation(rop.INT_OR, [v9, ConstInt(-23)], v17),
-        ResOperation(rop.INT_LT, [v10, v13], v18),
-        ResOperation(rop.INT_OR, [v15, v5], v19),
-        ResOperation(rop.INT_XOR, [v17, ConstInt(54)], v20),
-        ResOperation(rop.INT_MUL, [v8, v10], v21),
-        ResOperation(rop.INT_OR, [v3, v9], v22),
-        ResOperation(rop.INT_AND, [v11, ConstInt(-4)], tmp41),
-        ResOperation(rop.INT_OR, [tmp41, ConstInt(1)], tmp42),
-        ResOperation(rop.INT_MOD, [v12, tmp42], v23),
-        ResOperation(rop.INT_IS_TRUE, [v6], v24),
-        ResOperation(rop.UINT_RSHIFT, [v15, ConstInt(6)], v25),
-        ResOperation(rop.INT_OR, [ConstInt(-4), v25], v26),
-        ResOperation(rop.INT_INVERT, [v8], v27),
-        ResOperation(rop.INT_SUB, [ConstInt(-113), v11], v28),
-        ResOperation(rop.INT_NEG, [v7], v29),
-        ResOperation(rop.INT_NEG, [v24], v30),
-        ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(53)], v31),
-        ResOperation(rop.INT_MUL, [v28, v27], v32),
-        ResOperation(rop.INT_AND, [v18, ConstInt(-4)], tmp43),
-        ResOperation(rop.INT_OR, [tmp43, ConstInt(1)], tmp44),
-        ResOperation(rop.INT_MOD, [v26, tmp44], v33),
-        ResOperation(rop.INT_OR, [v27, v19], v34),
-        ResOperation(rop.UINT_LT, [v13, ConstInt(1)], v35),
-        ResOperation(rop.INT_AND, [v21, ConstInt(31)], tmp45),
-        ResOperation(rop.INT_RSHIFT, [v21, tmp45], v36),
-        ResOperation(rop.INT_AND, [v20, ConstInt(31)], tmp46),
-        ResOperation(rop.UINT_RSHIFT, [v4, tmp46], v37),
-        ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38),
-        ResOperation(rop.INT_NEG, [v7], v39),
-        ResOperation(rop.INT_GT, [v24, v32], v40),
-        ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()),
-            ]
-    operations[-1].setfailargs([v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38])
-    cpu = CPU(None, None)
-    cpu.setup_once()
-    looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
-    args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26]
-    deadframe = cpu.execute_token(looptoken, *args)
-    assert cpu.get_int_value(deadframe, 0) == 0
-    assert cpu.get_int_value(deadframe, 1) == 0
-    assert cpu.get_int_value(deadframe, 2) == 0
-    assert cpu.get_int_value(deadframe, 3) == 0
-    assert cpu.get_int_value(deadframe, 4) == 1
-    assert cpu.get_int_value(deadframe, 5) == -7
-    assert cpu.get_int_value(deadframe, 6) == 1
-    assert cpu.get_int_value(deadframe, 7) == 0
-    assert cpu.get_int_value(deadframe, 8) == -2
-    assert cpu.get_int_value(deadframe, 9) == 18
-    assert cpu.get_int_value(deadframe, 10) == 1
-    assert cpu.get_int_value(deadframe, 11) == 18
-    assert cpu.get_int_value(deadframe, 12) == -1
-    assert cpu.get_int_value(deadframe, 13) == 0
-
-def test_bug_1():
-    v1 = BoxInt()
-    v2 = BoxInt()
-    v3 = BoxInt()
-    v4 = BoxInt()
-    v5 = BoxInt()
-    v6 = BoxInt()
-    v7 = BoxInt()
-    v8 = BoxInt()
-    v9 = BoxInt()
-    v10 = BoxInt()
-    v11 = BoxInt()
-    v12 = BoxInt()
-    v13 = BoxInt()
-    v14 = BoxInt()
-    v15 = BoxInt()
-    v16 = BoxInt()
-    v17 = BoxInt()
-    v18 = BoxInt()
-    v19 = BoxInt()
-    v20 = BoxInt()
-    v21 = BoxInt()
-    v22 = BoxInt()
-    v23 = BoxInt()
-    v24 = BoxInt()
-    v25 = BoxInt()
-    v26 = BoxInt()
-    v27 = BoxInt()
-    v28 = BoxInt()
-    v29 = BoxInt()
-    v30 = BoxInt()
-    v31 = BoxInt()
-    v32 = BoxInt()
-    v33 = BoxInt()
-    v34 = BoxInt()
-    v35 = BoxInt()
-    v36 = BoxInt()
-    v37 = BoxInt()
-    v38 = BoxInt()
-    v39 = BoxInt()
-    v40 = BoxInt()
-    tmp41 = BoxInt()
-    tmp42 = BoxInt()
-    tmp43 = BoxInt()
-    tmp44 = BoxInt()
-    tmp45 = BoxInt()
-    inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
-    operations = [
-        ResOperation(rop.UINT_LT, [v6, ConstInt(0)], v11),
-        ResOperation(rop.INT_AND, [v3, ConstInt(31)], tmp41),
-        ResOperation(rop.INT_RSHIFT, [v3, tmp41], v12),
-        ResOperation(rop.INT_NEG, [v2], v13),
-        ResOperation(rop.INT_ADD, [v11, v7], v14),
-        ResOperation(rop.INT_OR, [v3, v2], v15),
-        ResOperation(rop.INT_OR, [v12, v12], v16),
-        ResOperation(rop.INT_NE, [v2, v5], v17),
-        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp42),
-        ResOperation(rop.UINT_RSHIFT, [v14, tmp42], v18),
-        ResOperation(rop.INT_AND, [v14, ConstInt(31)], tmp43),
-        ResOperation(rop.INT_LSHIFT, [ConstInt(7), tmp43], v19),
-        ResOperation(rop.INT_NEG, [v19], v20),
-        ResOperation(rop.INT_MOD, [v3, ConstInt(1)], v21),
-        ResOperation(rop.UINT_GE, [v15, v1], v22),
-        ResOperation(rop.INT_AND, [v16, ConstInt(31)], tmp44),
-        ResOperation(rop.INT_LSHIFT, [v8, tmp44], v23),
-        ResOperation(rop.INT_IS_TRUE, [v17], v24),
-        ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp45),
-        ResOperation(rop.INT_LSHIFT, [v14, tmp45], v25),
-        ResOperation(rop.INT_LSHIFT, [v5, ConstInt(17)], v26),
-        ResOperation(rop.INT_EQ, [v9, v15], v27),


More information about the pypy-commit mailing list