[pypy-commit] pypy reflex-support: merge default into branch

wlav noreply at buildbot.pypy.org
Thu Dec 6 02:23:31 CET 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r59336:65021b9ad524
Date: 2012-11-28 12:05 -0800
http://bitbucket.org/pypy/pypy/changeset/65021b9ad524/

Log:	merge default into branch

diff too long, truncating to 2000 out of 9769 lines

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -2,3 +2,4 @@
 b48df0bf4e75b81d98f19ce89d4a7dc3e1dab5e5 benchmarked
 d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6
 ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7
+07e08e9c885ca67d89bcc304e45a32346daea2fa release-2.0-beta-1
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -169,10 +169,11 @@
     BoolOption("no__thread",
                "don't use __thread for implementing TLS",
                default=False, cmdline="--no__thread", negation=False),
-    StrOption("compilerflags", "Specify flags for the C compiler",
-               cmdline="--cflags"),
-    StrOption("linkerflags", "Specify flags for the linker (C backend only)",
-               cmdline="--ldflags"),
+##  --- not supported since a long time.  Use the env vars CFLAGS/LDFLAGS.
+##    StrOption("compilerflags", "Specify flags for the C compiler",
+##               cmdline="--cflags"),
+##    StrOption("linkerflags", "Specify flags for the linker (C backend only)",
+##               cmdline="--ldflags"),
     IntOption("make_jobs", "Specify -j argument to make for compilation"
               " (C backend only)",
               cmdline="--make-jobs", default=detect_number_of_processors()),
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -45,9 +45,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '1.9'
+version = '2.0'
 # The full version, including alpha/beta/rc tags.
-release = '1.9'
+release = '2.0-beta1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -103,8 +103,8 @@
 executable. The executable behaves mostly like a normal Python interpreter::
 
     $ ./pypy-c
-    Python 2.7.2 (341e1e3821ff, Jun 07 2012, 15:40:31)
-    [PyPy 1.9.0 with GCC 4.4.3] on linux2
+    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
+    [PyPy 2.0.0-beta1 with GCC 4.7.1] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``RPython magically makes you rich
     and famous (says so on the tin)''
@@ -234,7 +234,7 @@
 the ``bin/pypy`` executable.
 
 To install PyPy system wide on unix-like systems, it is recommended to put the
-whole hierarchy alone (e.g. in ``/opt/pypy1.9``) and put a symlink to the
+whole hierarchy alone (e.g. in ``/opt/pypy2.0-beta1``) and put a symlink to the
 ``pypy`` executable into ``/usr/bin`` or ``/usr/local/bin``
 
 If the executable fails to find suitable libraries, it will report
diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst
--- a/pypy/doc/getting-started.rst
+++ b/pypy/doc/getting-started.rst
@@ -53,15 +53,14 @@
 PyPy is ready to be executed as soon as you unpack the tarball or the zip
 file, with no need to install it in any specific location::
 
-    $ tar xf pypy-1.9-linux.tar.bz2
-    $ ./pypy-1.9/bin/pypy
-    Python 2.7.2 (341e1e3821ff, Jun 07 2012, 15:40:31)
-    [PyPy 1.9.0 with GCC 4.4.3] on linux2
+    $ tar xf pypy-2.0-beta1-linux.tar.bz2
+    $ ./pypy-2.0-beta1/bin/pypy
+    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
+    [PyPy 2.0.0-beta1 with GCC 4.7.1] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
-    And now for something completely different: ``it seems to me that once you
-    settle on an execution / object model and / or bytecode format, you've already
-    decided what languages (where the 's' seems superfluous) support is going to be
-    first class for''
+    And now for something completely different: ``PyPy is an exciting technology
+    that lets you to write fast, portable, multi-platform interpreters with less
+    effort''
     >>>>
 
 If you want to make PyPy available system-wide, you can put a symlink to the
@@ -76,14 +75,14 @@
 
     $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
 
-    $ ./pypy-1.9/bin/pypy distribute_setup.py
+    $ ./pypy-2.0-beta1/bin/pypy distribute_setup.py
 
-    $ ./pypy-1.9/bin/pypy get-pip.py
+    $ ./pypy-2.0-beta1/bin/pypy get-pip.py
 
-    $ ./pypy-1.9/bin/pip install pygments  # for example
+    $ ./pypy-2.0-beta1/bin/pip install pygments  # for example
 
-3rd party libraries will be installed in ``pypy-1.9/site-packages``, and
-the scripts in ``pypy-1.9/bin``.
+3rd party libraries will be installed in ``pypy-2.0-beta1/site-packages``, and
+the scripts in ``pypy-2.0-beta1/bin``.
 
 Installing using virtualenv
 ---------------------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -15,7 +15,7 @@
 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 1.9`_: the latest official release
+* `Release 2.0 beta 1`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
@@ -75,7 +75,7 @@
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 1.9`: http://pypy.org/download.html
+.. _`Release 2.0 beta 1`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html
@@ -120,9 +120,9 @@
 Windows, on top of .NET, and on top of Java.
 To dig into PyPy it is recommended to try out the current
 Mercurial default branch, which is always working or mostly working,
-instead of the latest release, which is `1.9`__.
+instead of the latest release, which is `2.0 beta1`__.
 
-.. __: release-1.9.0.html
+.. __: release-2.0.0-beta1.html
 
 PyPy is mainly developed on Linux and Mac OS X.  Windows is supported,
 but platform-specific bugs tend to take longer before we notice and fix
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,62 +5,36 @@
 understanding what's pypy's JIT doing while running your program. There
 are three functions related to that coming from the `pypyjit` module:
 
-* `set_optimize_hook`::
+* `set_optimize_hook(callable)`::
 
     Set a compiling hook that will be called each time a loop is optimized,
-    but before assembler compilation. This allows to add additional
+    but before assembler compilation. This allows adding additional
     optimizations on Python level.
-    
-    The hook will be called with the following signature:
-    hook(jitdriver_name, loop_type, greenkey or guard_number, operations)
 
-    jitdriver_name is the name of this particular jitdriver, 'pypyjit' is
-    the main interpreter loop
+    The callable will be called with the pypyjit.JitLoopInfo object.
+    Refer to it's documentation for details.
 
-    loop_type can be either `loop` `entry_bridge` or `bridge`
-    in case loop is not `bridge`, greenkey will be a tuple of constants
-    or a string describing it.
+    Result value will be the resulting list of operations, or None
 
-    for the interpreter loop` it'll be a tuple
-    (code, offset, is_being_profiled)
+
+* `set_compile_hook(callable)`::
+
+    Set a compiling hook that will be called each time a loop is compiled.
+
+    The callable will be called with the pypyjit.JitLoopInfo object.
+    Refer to it's documentation for details.
 
     Note that jit hook is not reentrant. It means that if the code
     inside the jit hook is itself jitted, it will get compiled, but the
     jit hook won't be called for that.
 
-    Result value will be the resulting list of operations, or None
-
-* `set_compile_hook`::
-
-    Set a compiling hook that will be called each time a loop is compiled.
-    The hook will be called with the following signature:
-    hook(jitdriver_name, loop_type, greenkey or guard_number, operations,
-         assembler_addr, assembler_length)
-
-    jitdriver_name is the name of this particular jitdriver, 'pypyjit' is
-    the main interpreter loop
-
-    loop_type can be either `loop` `entry_bridge` or `bridge`
-    in case loop is not `bridge`, greenkey will be a tuple of constants
-    or a string describing it.
-
-    for the interpreter loop` it'll be a tuple
-    (code, offset, is_being_profiled)
-
-    assembler_addr is an integer describing where assembler starts,
-    can be accessed via ctypes, assembler_lenght is the lenght of compiled
-    asm
-
-    Note that jit hook is not reentrant. It means that if the code
-    inside the jit hook is itself jitted, it will get compiled, but the
-    jit hook won't be called for that.
-
-* `set_abort_hook`::
+* `set_abort_hook(hook)`::
 
     Set a hook (callable) that will be called each time there is tracing
     aborted due to some reason.
 
     The hook will be called as in: hook(jitdriver_name, greenkey, reason)
 
-    Where reason is the reason for abort, see documentation for set_compile_hook
-    for descriptions of other arguments.
+    Reason is a string, the meaning of other arguments is the same
+    as attributes on JitLoopInfo object
+
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -23,6 +23,14 @@
 PyPy's bytearray type is very inefficient. It would be an interesting
 task to look into possible optimizations on this.
 
+Implement copy-on-write list slicing
+------------------------------------
+
+The idea is to have a special implementation of list objects which is used
+when doing ``myslice = mylist[a:b]``: the new list is not constructed
+immediately, but only when (and if) ``myslice`` or ``mylist`` are mutated.
+
+
 Numpy improvements
 ------------------
 
diff --git a/pypy/doc/release-2.0.0-beta1.rst b/pypy/doc/release-2.0.0-beta1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.0.0-beta1.rst
@@ -0,0 +1,120 @@
+===============
+PyPy 2.0 beta 1
+===============
+
+We're pleased to announce the 2.0 beta 1 release of PyPy. This release is
+not a typical beta, in a sense the stability is the same or better than 1.9
+and can be used in production. It does however include a few performance
+regressions documented below that don't allow us to label is as 2.0 final.
+(It also contains many performance improvements.)
+
+The main features of this release are support for ARM processor and
+compatibility with CFFI. It also includes
+numerous improvements to the numpy in pypy effort, cpyext and performance.
+
+You can download the PyPy 2.0 beta 1 release here:
+
+    http://pypy.org/download.html 
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7.3. It's fast (`pypy 2.0 beta 1 and cpython 2.7.3`_
+performance comparison) due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64 or
+Windows 32. It also supports ARM machines running Linux.
+Windows 64 work is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.0 beta 1 and cpython 2.7.3`: http://bit.ly/USXqpP
+
+How to use PyPy?
+================
+
+We suggest using PyPy from a `virtualenv`_. Once you have a virtualenv
+installed, you can follow instructions from `pypy documentation`_ on how
+to proceed. This document also covers other `installation schemes`_.
+
+.. _`pypy documentation`: http://doc.pypy.org/en/latest/getting-started.html#installing-using-virtualenv
+.. _`virtualenv`: http://www.virtualenv.org/en/latest/
+.. _`installation schemes`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy
+.. _`PyPy and pip`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy
+
+Regressions
+===========
+
+Reasons why this is not PyPy 2.0:
+
+* the ``ctypes`` fast path is now slower than it used to be. In PyPy
+  1.9 ``ctypes`` was either incredibly faster or slower than CPython depending whether
+  you hit the fast path or not. Right now it's usually simply slower. We're
+  probably going to rewrite ``ctypes`` using ``cffi``, which will make it
+  universally faster.
+
+* ``cffi`` (an alternative to interfacing with C code) is very fast, but
+  it is missing one optimization that will make it as fast as a native
+  call from C.
+
+* ``numpypy`` lazy computation was disabled for the sake of simplicity.
+  We should reenable this for the final 2.0 release.
+
+Highlights
+==========
+
+* ``cffi`` is officially supported by PyPy. You can install it normally by
+  using ``pip install cffi`` once you have installed `PyPy and pip`_.
+  The corresponding ``0.4`` version of ``cffi`` has been released.
+
+* ARM is now an officially supported processor architecture.
+  PyPy now work on soft-float ARM/Linux builds.  Currently ARM processors
+  supporting the ARMv7 and later ISA that include a floating-point unit are
+  supported.
+
+* This release contains the latest Python standard library 2.7.3 and is fully
+  compatible with Python 2.7.3.
+
+* It does not however contain hash randomization, since the solution present
+  in CPython is not solving the problem anyway. The reason can be
+  found on the `CPython issue tracker`_.
+
+* ``gc.get_referrers()`` is now faster.
+
+* Various numpy improvements. The list includes:
+
+  * axis argument support in many places
+
+  * full support for fancy indexing
+
+  * ``complex128`` and ``complex64`` dtypes
+
+* `JIT hooks`_ are now a powerful tool to introspect the JITting process that
+  PyPy performs.
+
+* ``**kwds`` usage is much faster in the typical scenario
+
+* operations on ``long`` objects are now as fast as in CPython (from
+  roughly 2x slower)
+
+* We now have special strategies for ``dict``/``set``/``list`` which contain
+  unicode strings, which means that now such collections will be both faster
+  and more compact.
+
+.. _`cpython issue tracker`: http://bugs.python.org/issue14621
+.. _`jit hooks`: http://doc.pypy.org/en/latest/jit-hooks.html
+
+Things we're working on
+=======================
+
+There are a few things that did not make it to the 2.0 beta 1, which
+are being actively worked on. Greenlets support in the JIT is one
+that we would like to have before 2.0 final. Two important items that
+will not make it to 2.0, but are being actively worked on, are:
+
+* Faster JIT warmup time.
+
+* Software Transactional Memory.
+
+Cheers,
+Maciej Fijalkowski, Armin Rigo and the PyPy team
diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst
--- a/pypy/doc/translation.rst
+++ b/pypy/doc/translation.rst
@@ -99,7 +99,7 @@
     .. image:: image/translation-greyscale-small.png
 
 
-.. _`PDF color version`: image/translation.pdf
+.. _`PDF color version`: https://bitbucket.org/pypy/pypy/raw/default/pypy/doc/image/translation.pdf
 .. _`bytecode evaluator`: interpreter.html
 .. _`abstract interpretation`: http://en.wikipedia.org/wiki/Abstract_interpretation
 .. _`Flow Object Space`: objspace.html#the-flow-object-space
diff --git a/pypy/doc/whatsnew-2.0.0-beta1.rst b/pypy/doc/whatsnew-2.0.0-beta1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-2.0.0-beta1.rst
@@ -0,0 +1,65 @@
+======================
+What's new in PyPy xxx
+======================
+
+.. this is the revision of the last merge from default to release-1.9.x
+.. startrev: 8d567513d04d
+
+Fixed the performance of gc.get_referrers()
+
+.. branch: default
+.. branch: app_main-refactor
+.. branch: win-ordinal
+.. branch: reflex-support
+Provides cppyy module (disabled by default) for access to C++ through Reflex.
+See doc/cppyy.rst for full details and functionality.
+.. branch: nupypy-axis-arg-check
+Check that axis arg is valid in _numpypy
+.. branch:less-gettestobjspace
+.. branch: move-apptest-support
+
+.. branch: iterator-in-rpython
+.. branch: numpypy_count_nonzero
+.. branch: numpy-refactor
+Remove numpy lazy evaluation and simplify everything
+.. branch: numpy-reintroduce-jit-drivers
+.. branch: numpy-fancy-indexing
+Support for array[array-of-ints] in numpy
+.. branch: even-more-jit-hooks
+Implement better JIT hooks
+.. branch: virtual-arguments
+Improve handling of **kwds greatly, making them virtual sometimes.
+.. branch: improve-rbigint
+Introduce __int128 on systems where it's supported and improve the speed of
+rlib/rbigint.py greatly.
+.. branch: translation-cleanup
+Start to clean up a bit the flow object space.
+.. branch: ffi-backend
+Support CFFI.  http://morepypy.blogspot.ch/2012/08/cffi-release-03.html
+.. branch: speedup-unpackiterable
+.. branch: stdlib-2.7.3
+The stdlib was updated to version 2.7.3
+
+.. branch: numpypy-complex2
+Complex dtype support for numpy
+.. branch: numpypy-problems
+Improve dtypes intp, uintp, void, string and record
+.. branch: numpypy.float16
+Add float16 numpy dtype
+.. branch: kill-someobject
+major cleanups including killing some object support
+.. branch: cpyext-PyThreadState_New
+implement threadstate-related functions in cpyext
+
+.. branch: unicode-strategies
+add dict/list/set strategies optimized for unicode items
+
+.. "uninteresting" branches that we should just ignore for the whatsnew:
+.. branch: slightly-shorter-c
+.. branch: better-enforceargs
+.. branch: rpython-unicode-formatting
+.. branch: jit-opaque-licm
+.. branch: rpython-utf8
+Support for utf-8 encoding in RPython
+.. branch: arm-backend-2
+Support ARM in the JIT.
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
@@ -2,60 +2,11 @@
 What's new in PyPy xxx
 ======================
 
-.. this is the revision of the last merge from default to release-1.9.x
-.. startrev: 8d567513d04d
+.. this is a revision shortly after release-2.0-beta1
+.. startrev: 0e6161a009c6
 
-Fixed the performance of gc.get_referrers()
+.. branch: autoreds
+XXX
 
-.. branch: default
-.. branch: app_main-refactor
-.. branch: win-ordinal
-.. branch: reflex-support
-Provides cppyy module (disabled by default) for access to C++ through Reflex.
-See doc/cppyy.rst for full details and functionality.
-.. branch: nupypy-axis-arg-check
-Check that axis arg is valid in _numpypy
-
-.. branch: iterator-in-rpython
-.. branch: numpypy_count_nonzero
-.. branch: numpy-refactor
-Remove numpy lazy evaluation and simplify everything
-.. branch: numpy-reintroduce-jit-drivers
-.. branch: numpy-fancy-indexing
-Support for array[array-of-ints] in numpy
-.. branch: even-more-jit-hooks
-Implement better JIT hooks
-.. branch: virtual-arguments
-Improve handling of **kwds greatly, making them virtual sometimes.
-.. branch: improve-rbigint
-Introduce __int128 on systems where it's supported and improve the speed of
-rlib/rbigint.py greatly.
-.. branch: translation-cleanup
-Start to clean up a bit the flow object space.
-.. branch: ffi-backend
-Support CFFI.  http://morepypy.blogspot.ch/2012/08/cffi-release-03.html
-.. branch: speedup-unpackiterable
-.. branch: stdlib-2.7.3
-The stdlib was updated to version 2.7.3
-
-.. branch: numpypy-complex2
-Complex dtype support for numpy
-.. branch: numpypy-problems
-Improve dtypes intp, uintp, void, string and record
-.. branch: kill-someobject
-major cleanups including killing some object support
-.. branch: cpyext-PyThreadState_New
-implement threadstate-related functions in cpyext
-
-.. branch: unicode-strategies
-add dict/list/set strategies optimized for unicode items
-
-.. "uninteresting" branches that we should just ignore for the whatsnew:
-.. branch: slightly-shorter-c
-.. branch: better-enforceargs
-.. branch: rpython-unicode-formatting
-.. branch: jit-opaque-licm
-.. branch: rpython-utf8
-Support for utf-8 encoding in RPython
-.. branch: arm-backend-2
-Support ARM in the JIT.
+.. branch: length-hint
+XXX
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -141,7 +141,7 @@
 unrolling_unary_folders = unrolling_iterable(unary_folders.items())
 
 for folder in binary_folders.values() + unary_folders.values():
-    folder._always_inline_ = True
+    folder._always_inline_ = 'try'
 del folder
 
 opposite_compare_operations = misc.dict_to_switch({
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -862,18 +862,10 @@
         """
         # If we can guess the expected length we can preallocate.
         try:
-            lgt_estimate = self.len_w(w_iterable)
-        except OperationError, o:
-            if (not o.match(self, self.w_AttributeError) and
-                not o.match(self, self.w_TypeError)):
-                raise
-            items = []
-        else:
-            try:
-                items = newlist_hint(lgt_estimate)
-            except MemoryError:
-                items = [] # it might have lied
-        #
+            items = newlist_hint(self.length_hint(w_iterable, 0))
+        except MemoryError:
+            items = [] # it might have lied
+
         tp = self.type(w_iterator)
         while True:
             unpackiterable_driver.jit_merge_point(tp=tp,
@@ -933,6 +925,36 @@
         return self._unpackiterable_known_length_jitlook(w_iterator,
                                                          expected_length)
 
+    def length_hint(self, w_obj, default):
+        """Return the length of an object, consulting its __length_hint__
+        method if necessary.
+        """
+        try:
+            return self.len_w(w_obj)
+        except OperationError, e:
+            if not (e.match(self, self.w_TypeError) or
+                    e.match(self, self.w_AttributeError)):
+                raise
+
+        w_descr = self.lookup(w_obj, '__length_hint__')
+        if w_descr is None:
+            return default
+        try:
+            w_hint = self.get_and_call_function(w_descr, w_obj)
+        except OperationError, e:
+            if not (e.match(self, self.w_TypeError) or
+                    e.match(self, self.w_AttributeError)):
+                raise
+            return default
+        if self.is_w(w_hint, self.w_NotImplemented):
+            return default
+
+        hint = self.int_w(w_hint)
+        if hint < 0:
+            raise OperationError(self.w_ValueError, self.wrap(
+                    "__length_hint__() should return >= 0"))
+        return hint
+
     def fixedview(self, w_iterable, expected_length=-1):
         """ A fixed list view of w_iterable. Don't modify the result
         """
@@ -969,6 +991,10 @@
     def newlist_str(self, list_s):
         return self.newlist([self.wrap(s) for s in list_s])
 
+    def newlist_hint(self, sizehint):
+        from pypy.objspace.std.listobject import make_empty_list_with_size
+        return make_empty_list_with_size(self, sizehint)
+
     @jit.unroll_safe
     def exception_match(self, w_exc_type, w_check_class):
         """Checks if the given exception type matches 'w_check_class'."""
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -224,7 +224,7 @@
         return w_type
 
     def write_unraisable(self, space, where, w_object=None,
-                         with_traceback=False):
+                         with_traceback=False, extra_line=''):
         if w_object is None:
             objrepr = ''
         else:
@@ -240,10 +240,13 @@
                 w_tb = space.wrap(self.get_traceback())
                 space.appexec([space.wrap(where),
                                space.wrap(objrepr),
+                               space.wrap(extra_line),
                                w_t, w_v, w_tb],
-                """(where, objrepr, t, v, tb):
+                """(where, objrepr, extra_line, t, v, tb):
                     import sys, traceback
                     sys.stderr.write('From %s%s:\\n' % (where, objrepr))
+                    if extra_line:
+                        sys.stderr.write(extra_line)
                     traceback.print_exception(t, v, tb)
                 """)
             else:
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -144,7 +144,10 @@
         actionflag = self.space.actionflag
         if actionflag.get_ticker() < 0:
             actionflag.action_dispatcher(self, frame)     # slow path
-    bytecode_trace_after_exception._always_inline_ = True
+    bytecode_trace_after_exception._always_inline_ = 'try'
+    # NB. this function is not inlined right now.  backendopt.inline would
+    # need some improvements to handle this case, but it's not really an
+    # issue
 
     def exception_trace(self, frame, operationerr):
         "Trace function called upon OperationError."
diff --git a/pypy/jit/backend/arm/arch.py b/pypy/jit/backend/arm/arch.py
--- a/pypy/jit/backend/arm/arch.py
+++ b/pypy/jit/backend/arm/arch.py
@@ -19,10 +19,10 @@
 static int pypy__arm_int_div(int a, int b) {
     return a/b;
 }
-static uint pypy__arm_uint_div(uint a, uint b) {
+static unsigned int pypy__arm_uint_div(unsigned int a, unsigned int b) {
     return a/b;
 }
-static int pypy__arm_int_mod(uint a, uint b) {
+static int pypy__arm_int_mod(int a, int b) {
     return a % b;
 }
 """])
diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -129,7 +129,7 @@
         self._VCVT(target, source, cond, 0, 1)
 
     def _VCVT(self, target, source, cond, opc2, sz):
-        D = 0x0
+        D = 0
         M = 0
         op = 1
         instr = (cond << 28
@@ -145,6 +145,26 @@
                 | (source & 0xF))
         self.write32(instr)
 
+    def _VCVT_single_double(self, target, source, cond, sz):
+        # double_to_single = (sz == '1');
+        D = 0
+        M = 0
+        instr = (cond << 28
+                | 0xEB7 << 16
+                | 0xAC << 4
+                | D << 22
+                | (target & 0xF) << 12
+                | sz << 8
+                | M << 5
+                | (source & 0xF))
+        self.write32(instr)
+
+    def VCVT_f64_f32(self, target, source, cond=cond.AL):
+        self._VCVT_single_double(target, source, cond, 1)
+
+    def VCVT_f32_f64(self, target, source, cond=cond.AL):
+        self._VCVT_single_double(target, source, cond, 0)
+
     def POP(self, regs, cond=cond.AL):
         instr = self._encode_reg_list(cond << 28 | 0x8BD << 16, regs)
         self.write32(instr)
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -656,7 +656,7 @@
             # must save the register loc_index before it is mutated
             self.mc.PUSH([loc_index.value])
             tmp1 = loc_index
-            tmp2 = arglocs[2]
+            tmp2 = arglocs[-1]  # the last item is a preallocated tmp
             # lr = byteofs
             s = 3 + descr.jit_wb_card_page_shift
             self.mc.MVN_rr(r.lr.value, loc_index.value,
@@ -1446,3 +1446,20 @@
         self.mc.MOV_ri(r.ip.value, 0)
         self.mc.VMOV_cr(res.value, tmp.value, r.ip.value)
         return fcond
+
+    def emit_op_cast_float_to_singlefloat(self, op, arglocs, regalloc, fcond):
+        arg, res = arglocs
+        assert arg.is_vfp_reg()
+        assert res.is_reg()
+        self.mc.VCVT_f64_f32(r.vfp_ip.value, arg.value)
+        self.mc.VMOV_rc(res.value, r.ip.value, r.vfp_ip.value)
+        return fcond
+    
+    def emit_op_cast_singlefloat_to_float(self, op, arglocs, regalloc, fcond):
+        arg, res = arglocs
+        assert res.is_vfp_reg()
+        assert arg.is_reg()
+        self.mc.MOV_ri(r.ip.value, 0)
+        self.mc.VMOV_cr(res.value, arg.value, r.ip.value)
+        self.mc.VCVT_f32_f64(res.value, res.value)
+        return fcond
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -1095,7 +1095,8 @@
         args = op.getarglist()
         arglocs = [self._ensure_value_is_boxed(op.getarg(i), args)
                                                               for i in range(N)]
-        tmp = self.get_scratch_reg(INT)
+        tmp = self.get_scratch_reg(INT, args)
+        assert tmp not in arglocs
         arglocs.append(tmp)
         return arglocs
 
@@ -1245,6 +1246,16 @@
         res = self.vfprm.force_allocate_reg(op.result)
         return [loc, res]
 
+    def prepare_op_cast_float_to_singlefloat(self, op, fcond):
+        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        res = self.force_allocate_reg(op.result)
+        return [loc1, res]
+    
+    def prepare_op_cast_singlefloat_to_float(self, op, fcond):
+        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        res = self.force_allocate_reg(op.result)
+        return [loc1, res]
+
 
 def add_none_argument(fn):
     return lambda self, op, fcond: fn(self, op, None, fcond)
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -12,6 +12,7 @@
     supports_floats = True
     supports_longlong = False # XXX requires an implementation of
                               # read_timestamp that works in user mode
+    supports_singlefloats = True
     
     use_hf_abi = False        # use hard float abi flag
 
diff --git a/pypy/jit/backend/x86/test/test_float.py b/pypy/jit/backend/arm/test/test_float.py
copy from pypy/jit/backend/x86/test/test_float.py
copy to pypy/jit/backend/arm/test/test_float.py
--- a/pypy/jit/backend/x86/test/test_float.py
+++ b/pypy/jit/backend/arm/test/test_float.py
@@ -1,9 +1,9 @@
 
 import py
-from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
+from pypy.jit.backend.arm.test.support import JitARMMixin
 from pypy.jit.metainterp.test.test_float import FloatTests
 
-class TestFloat(Jit386Mixin, FloatTests):
+class TestFloat(JitARMMixin, FloatTests):
     # for the individual tests see
     # ====> ../../../metainterp/test/test_float.py
     pass
diff --git a/pypy/jit/backend/arm/test/test_regalloc.py b/pypy/jit/backend/arm/test/test_regalloc.py
--- a/pypy/jit/backend/arm/test/test_regalloc.py
+++ b/pypy/jit/backend/arm/test/test_regalloc.py
@@ -77,6 +77,17 @@
         return -1
 
 
+def get_zero_division_error(self):
+    # for tests, a random emulated ll_inst will do
+    ll_inst = lltype.malloc(rclass.OBJECT)
+    ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
+                                    immortal=True)
+    _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr)
+    zer_vtable = self.cast_adr_to_int(_zer_error_vtable)
+    zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)
+    return zer_vtable, zer_inst
+
+
 class BaseTestRegalloc(object):
     cpu = CPU(None, None)
     cpu.setup_once()
@@ -96,7 +107,7 @@
     f_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
                                                     EffectInfo.MOST_GENERAL)
 
-    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
+    zero_division_tp, zero_division_value = get_zero_division_error(cpu)
     zd_addr = cpu.cast_int_to_adr(zero_division_tp)
     zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
                                             lltype.Ptr(rclass.OBJECT_VTABLE))
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -413,19 +413,19 @@
     def bh_unicodegetitem(self, string, index):
         return llimpl.do_unicodegetitem(string, index)
 
-    def bh_getarrayitem_gc_i(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_i(self, array, index, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_gc_int(array, index)
-    def bh_getarrayitem_raw_i(self, arraydescr, array, index):
+    def bh_getarrayitem_raw_i(self, array, index, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_raw_int(array, index, arraydescr.ofs)
-    def bh_getarrayitem_gc_r(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_r(self, array, index, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_gc_ptr(array, index)
-    def bh_getarrayitem_gc_f(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_f(self, array, index, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_gc_float(array, index)
-    def bh_getarrayitem_raw_f(self, arraydescr, array, index):
+    def bh_getarrayitem_raw_f(self, array, index, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_getarrayitem_raw_float(array, index)
 
@@ -459,23 +459,23 @@
         assert isinstance(descr, Descr)
         return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs)
 
-    def bh_setinteriorfield_gc_i(self, array, index, descr, value):
+    def bh_setinteriorfield_gc_i(self, array, index, value, descr):
         assert isinstance(descr, Descr)
         return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs,
                                                  value)
-    def bh_setinteriorfield_gc_r(self, array, index, descr, value):
+    def bh_setinteriorfield_gc_r(self, array, index, value, descr):
         assert isinstance(descr, Descr)
         return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs,
                                                  value)
-    def bh_setinteriorfield_gc_f(self, array, index, descr, value):
+    def bh_setinteriorfield_gc_f(self, array, index, value, descr):
         assert isinstance(descr, Descr)
         return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs,
                                                    value)
 
-    def bh_raw_store_i(self, struct, offset, descr, newvalue):
+    def bh_raw_store_i(self, struct, offset, newvalue, descr):
         assert isinstance(descr, Descr)
         return llimpl.do_raw_store_int(struct, offset, descr.ofs, newvalue)
-    def bh_raw_store_f(self, struct, offset, descr, newvalue):
+    def bh_raw_store_f(self, struct, offset, newvalue, descr):
         assert isinstance(descr, Descr)
         return llimpl.do_raw_store_float(struct, offset, newvalue)
     def bh_raw_load_i(self, struct, offset, descr):
@@ -489,7 +489,7 @@
         assert isinstance(sizedescr, Descr)
         return llimpl.do_new(sizedescr.ofs)
 
-    def bh_new_with_vtable(self, sizedescr, vtable):
+    def bh_new_with_vtable(self, vtable, sizedescr):
         assert isinstance(sizedescr, Descr)
         result = llimpl.do_new(sizedescr.ofs)
         llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable)
@@ -500,51 +500,51 @@
         result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
         return heaptracker.adr2int(result_adr)
 
-    def bh_new_array(self, arraydescr, length):
+    def bh_new_array(self, length, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_new_array(arraydescr.ofs, length)
 
-    def bh_arraylen_gc(self, arraydescr, array):
+    def bh_arraylen_gc(self, array, arraydescr):
         assert isinstance(arraydescr, Descr)
         return llimpl.do_arraylen_gc(arraydescr, array)
 
-    def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_i(self, array, index, newvalue, arraydescr):
         assert isinstance(arraydescr, Descr)
         llimpl.do_setarrayitem_gc_int(array, index, newvalue)
 
-    def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_raw_i(self, array, index, newvalue, arraydescr):
         assert isinstance(arraydescr, Descr)
         llimpl.do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs)
 
-    def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_r(self, array, index, newvalue, arraydescr):
         assert isinstance(arraydescr, Descr)
         llimpl.do_setarrayitem_gc_ptr(array, index, newvalue)
 
-    def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_f(self, array, index, newvalue, arraydescr):
         assert isinstance(arraydescr, Descr)
         llimpl.do_setarrayitem_gc_float(array, index, newvalue)
 
-    def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_raw_f(self, array, index, newvalue, arraydescr):
         assert isinstance(arraydescr, Descr)
         llimpl.do_setarrayitem_raw_float(array, index, newvalue)
 
-    def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_i(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
-    def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_r(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
-    def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_f(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue)
 
-    def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_i(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
-    def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_r(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
-    def bh_setfield_raw_f(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_f(self, struct, newvalue, fielddescr):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue)
 
@@ -560,20 +560,20 @@
     def bh_unicodesetitem(self, string, index, newvalue):
         llimpl.do_unicodesetitem(string, index, newvalue)
 
-    def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
-        self._prepare_call(INT, calldescr, args_i, args_r, args_f)
+    def bh_call_i(self, func, args_i, args_r, args_f, calldescr):
+        self._prepare_call(INT, args_i, args_r, args_f, calldescr)
         return llimpl.do_call_int(func)
-    def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
-        self._prepare_call(REF, calldescr, args_i, args_r, args_f)
+    def bh_call_r(self, func, args_i, args_r, args_f, calldescr):
+        self._prepare_call(REF, args_i, args_r, args_f, calldescr)
         return llimpl.do_call_ptr(func)
-    def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
-        self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f)
+    def bh_call_f(self, func, args_i, args_r, args_f, calldescr):
+        self._prepare_call(FLOAT + 'L', args_i, args_r, args_f, calldescr)
         return llimpl.do_call_float(func)
-    def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
-        self._prepare_call('v', calldescr, args_i, args_r, args_f)
+    def bh_call_v(self, func, args_i, args_r, args_f, calldescr):
+        self._prepare_call('v', args_i, args_r, args_f, calldescr)
         llimpl.do_call_void(func)
 
-    def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f):
+    def _prepare_call(self, resulttypeinfo, args_i, args_r, args_f, calldescr):
         assert isinstance(calldescr, Descr)
         assert calldescr.typeinfo in resulttypeinfo
         if args_i is not None:
@@ -644,16 +644,6 @@
         else:
             return ootype.NULL
 
-    def get_overflow_error(self):
-        ll_err = llimpl._get_error(OverflowError)
-        return (ootype.cast_to_object(ll_err.args[0]),
-                ootype.cast_to_object(ll_err.args[1]))
-
-    def get_zero_division_error(self):
-        ll_err = llimpl._get_error(ZeroDivisionError)
-        return (ootype.cast_to_object(ll_err.args[0]),
-                ootype.cast_to_object(ll_err.args[1]))
-
     def do_new_with_vtable(self, clsbox):
         cls = clsbox.getref_base()
         typedescr = self.class_sizes[cls]
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
@@ -83,15 +83,15 @@
         assert isinstance(sizedescr, SizeDescr)
         return self._bh_malloc(sizedescr)
 
-    def gc_malloc_array(self, arraydescr, num_elem):
+    def gc_malloc_array(self, num_elem, arraydescr):
         assert isinstance(arraydescr, ArrayDescr)
-        return self._bh_malloc_array(arraydescr, num_elem)
+        return self._bh_malloc_array(num_elem, arraydescr)
 
     def gc_malloc_str(self, num_elem):
-        return self._bh_malloc_array(self.str_descr, num_elem)
+        return self._bh_malloc_array(num_elem, self.str_descr)
 
     def gc_malloc_unicode(self, num_elem):
-        return self._bh_malloc_array(self.unicode_descr, num_elem)
+        return self._bh_malloc_array(num_elem, self.unicode_descr)
 
     def _record_constptrs(self, op, gcrefs_output_list):
         for i in range(op.numargs()):
@@ -193,7 +193,7 @@
     def _bh_malloc(self, sizedescr):
         return self.malloc_fixedsize(sizedescr.size)
 
-    def _bh_malloc_array(self, arraydescr, num_elem):
+    def _bh_malloc_array(self, num_elem, arraydescr):
         return self.malloc_array(arraydescr.basesize, num_elem,
                                  arraydescr.itemsize,
                                  arraydescr.lendescr.offset)
@@ -802,7 +802,7 @@
                                                type_id, sizedescr.size,
                                                False, False, False)
 
-    def _bh_malloc_array(self, arraydescr, num_elem):
+    def _bh_malloc_array(self, num_elem, arraydescr):
         from pypy.rpython.memory.gctypelayout import check_typeid
         llop1 = self.llop1
         type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid)
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -39,8 +39,6 @@
             self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
                                                              'typeptr',
                                                         translate_support_code)
-        self._setup_prebuilt_error('ovf', OverflowError)
-        self._setup_prebuilt_error('zer', ZeroDivisionError)
         if translate_support_code:
             self._setup_exception_handling_translated()
         else:
@@ -56,21 +54,6 @@
     def setup(self):
         pass
 
-    def _setup_prebuilt_error(self, prefix, Class):
-        if self.rtyper is not None:   # normal case
-            bk = self.rtyper.annotator.bookkeeper
-            clsdef = bk.getuniqueclassdef(Class)
-            ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance(
-                self.rtyper, clsdef)
-        else:
-            # for tests, a random emulated ll_inst will do
-            ll_inst = lltype.malloc(rclass.OBJECT)
-            ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
-                                            immortal=True)
-        setattr(self, '_%s_error_vtable' % prefix,
-                llmemory.cast_ptr_to_adr(ll_inst.typeptr))
-        setattr(self, '_%s_error_inst' % prefix, ll_inst)
-
 
     def _setup_exception_handling_untranslated(self):
         # for running un-translated only, all exceptions occurring in the
@@ -293,27 +276,15 @@
         return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype,
                                                       abiname)
 
-    def get_overflow_error(self):
-        ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
-        ovf_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                          self._ovf_error_inst)
-        return ovf_vtable, ovf_inst
-
-    def get_zero_division_error(self):
-        zer_vtable = self.cast_adr_to_int(self._zer_error_vtable)
-        zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF,
-                                          self._zer_error_inst)
-        return zer_vtable, zer_inst
-
     # ____________________________________________________________
 
-    def bh_arraylen_gc(self, arraydescr, array):
+    def bh_arraylen_gc(self, array, arraydescr):
         assert isinstance(arraydescr, ArrayDescr)
         ofs = arraydescr.lendescr.offset
         return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD]
 
-    @specialize.argtype(2)
-    def bh_getarrayitem_gc_i(self, arraydescr, gcref, itemindex):
+    @specialize.argtype(1)
+    def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr):
         ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -332,7 +303,7 @@
         else:
             raise NotImplementedError("size = %d" % size)
 
-    def bh_getarrayitem_gc_r(self, arraydescr, gcref, itemindex):
+    def bh_getarrayitem_gc_r(self, gcref, itemindex, arraydescr):
         ofs = self.unpack_arraydescr(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -341,8 +312,8 @@
         # --- end of GC unsafe code ---
         return pval
 
-    @specialize.argtype(2)
-    def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex):
+    @specialize.argtype(1)
+    def bh_getarrayitem_gc_f(self, gcref, itemindex, arraydescr):
         ofs = self.unpack_arraydescr(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -351,8 +322,8 @@
         # --- end of GC unsafe code ---
         return fval
 
-    @specialize.argtype(2)
-    def bh_setarrayitem_gc_i(self, arraydescr, gcref, itemindex, newvalue):
+    @specialize.argtype(1)
+    def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr):
         ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -365,7 +336,7 @@
         else:
             raise NotImplementedError("size = %d" % size)
 
-    def bh_setarrayitem_gc_r(self, arraydescr, gcref, itemindex, newvalue):
+    def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr):
         ofs = self.unpack_arraydescr(arraydescr)
         self.gc_ll_descr.do_write_barrier(gcref, newvalue)
         # --- start of GC unsafe code (no GC operation!) ---
@@ -374,8 +345,8 @@
         items[itemindex] = self.cast_gcref_to_int(newvalue)
         # --- end of GC unsafe code ---
 
-    @specialize.argtype(2)
-    def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue):
+    @specialize.argtype(1)
+    def bh_setarrayitem_gc_f(self, gcref, itemindex, newvalue, arraydescr):
         ofs = self.unpack_arraydescr(arraydescr)
         # --- start of GC unsafe code (no GC operation!) ---
         items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -440,7 +411,7 @@
         # --- end of GC unsafe code ---
         return fval
 
-    def bh_setinteriorfield_gc_i(self, gcref, itemindex, descr, value):
+    def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr):
         assert isinstance(descr, InteriorFieldDescr)
         arraydescr = descr.arraydescr
         ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
@@ -458,7 +429,7 @@
         else:
             raise NotImplementedError("size = %d" % fieldsize)
 
-    def bh_setinteriorfield_gc_r(self, gcref, itemindex, descr, newvalue):
+    def bh_setinteriorfield_gc_r(self, gcref, itemindex, newvalue, descr):
         assert isinstance(descr, InteriorFieldDescr)
         arraydescr = descr.arraydescr
         ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
@@ -471,7 +442,7 @@
         items[0] = self.cast_gcref_to_int(newvalue)
         # --- end of GC unsafe code ---
 
-    def bh_setinteriorfield_gc_f(self, gcref, itemindex, descr, newvalue):
+    def bh_setinteriorfield_gc_f(self, gcref, itemindex, newvalue, descr):
         assert isinstance(descr, InteriorFieldDescr)
         arraydescr = descr.arraydescr
         ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
@@ -547,7 +518,7 @@
     bh_getfield_raw_f = _base_do_getfield_f
 
     @specialize.argtype(1)
-    def _base_do_setfield_i(self, struct, fielddescr, newvalue):
+    def _base_do_setfield_i(self, struct, newvalue, fielddescr):
         ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
         # --- start of GC unsafe code (no GC operation!) ---
         fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
@@ -561,7 +532,7 @@
             raise NotImplementedError("size = %d" % size)
 
     @specialize.argtype(1)
-    def _base_do_setfield_r(self, struct, fielddescr, newvalue):
+    def _base_do_setfield_r(self, struct, newvalue, fielddescr):
         ofs = self.unpack_fielddescr(fielddescr)
         assert lltype.typeOf(struct) is not lltype.Signed, (
             "can't handle write barriers for setfield_raw")
@@ -573,7 +544,7 @@
         # --- end of GC unsafe code ---
 
     @specialize.argtype(1)
-    def _base_do_setfield_f(self, struct, fielddescr, newvalue):
+    def _base_do_setfield_f(self, struct, newvalue, fielddescr):
         ofs = self.unpack_fielddescr(fielddescr)
         # --- start of GC unsafe code (no GC operation!) ---
         fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
@@ -588,7 +559,7 @@
     bh_setfield_raw_r = _base_do_setfield_r
     bh_setfield_raw_f = _base_do_setfield_f
 
-    def bh_raw_store_i(self, addr, offset, descr, newvalue):
+    def bh_raw_store_i(self, addr, offset, newvalue, descr):
         ofs, size, sign = self.unpack_arraydescr_size(descr)
         items = addr + offset
         for TYPE, _, itemsize in unroll_basic_sizes:
@@ -597,7 +568,7 @@
                 items[0] = rffi.cast(TYPE, newvalue)
                 break
 
-    def bh_raw_store_f(self, addr, offset, descr, newvalue):
+    def bh_raw_store_f(self, addr, offset, newvalue, descr):
         items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset)
         items[0] = newvalue
 
@@ -617,7 +588,7 @@
     def bh_new(self, sizedescr):
         return self.gc_ll_descr.gc_malloc(sizedescr)
 
-    def bh_new_with_vtable(self, sizedescr, vtable):
+    def bh_new_with_vtable(self, vtable, sizedescr):
         res = self.gc_ll_descr.gc_malloc(sizedescr)
         if self.vtable_offset is not None:
             as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
@@ -629,8 +600,8 @@
         result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
         return heaptracker.adr2int(result_adr)
 
-    def bh_new_array(self, arraydescr, length):
-        return self.gc_ll_descr.gc_malloc_array(arraydescr, length)
+    def bh_new_array(self, length, arraydescr):
+        return self.gc_ll_descr.gc_malloc_array(length, arraydescr)
 
     def bh_newstr(self, length):
         return self.gc_ll_descr.gc_malloc_str(length)
@@ -656,25 +627,25 @@
         dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst)
         rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
 
-    def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_i(self, func, args_i, args_r, args_f, calldescr):
         assert isinstance(calldescr, CallDescr)
         if not we_are_translated():
             calldescr.verify_types(args_i, args_r, args_f, history.INT + 'S')
         return calldescr.call_stub_i(func, args_i, args_r, args_f)
 
-    def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_r(self, func, args_i, args_r, args_f, calldescr):
         assert isinstance(calldescr, CallDescr)
         if not we_are_translated():
             calldescr.verify_types(args_i, args_r, args_f, history.REF)
         return calldescr.call_stub_r(func, args_i, args_r, args_f)
 
-    def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_f(self, func, args_i, args_r, args_f, calldescr):
         assert isinstance(calldescr, CallDescr)
         if not we_are_translated():
             calldescr.verify_types(args_i, args_r, args_f, history.FLOAT + 'L')
         return calldescr.call_stub_f(func, args_i, args_r, args_f)
 
-    def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_v(self, func, args_i, args_r, args_f, calldescr):
         assert isinstance(calldescr, CallDescr)
         if not we_are_translated():
             calldescr.verify_types(args_i, args_r, args_f, history.VOID)
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -33,7 +33,7 @@
     # ---------- gc_malloc_array ----------
     A = lltype.GcArray(lltype.Signed)
     arraydescr = get_array_descr(gc_ll_descr, A)
-    p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
+    p = gc_ll_descr.gc_malloc_array(10, arraydescr)
     assert record == [(arraydescr.basesize +
                        10 * arraydescr.itemsize, p)]
     del record[:]
@@ -357,7 +357,7 @@
     def test_gc_malloc_array(self):
         A = lltype.GcArray(lltype.Signed)
         arraydescr = get_array_descr(self.gc_ll_descr, A)
-        p = self.gc_ll_descr.gc_malloc_array(arraydescr, 10)
+        p = self.gc_ll_descr.gc_malloc_array(10, arraydescr)
         assert self.llop1.record == [("varsize", arraydescr.tid, 10,
                                       repr(arraydescr.basesize),
                                       repr(arraydescr.itemsize),
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -233,11 +233,11 @@
     # lltype specific operations
     # --------------------------
 
-    def bh_getarrayitem_gc_i(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_i(self, array, index, arraydescr):
         raise NotImplementedError
-    def bh_getarrayitem_gc_r(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_r(self, array, index, arraydescr):
         raise NotImplementedError
-    def bh_getarrayitem_gc_f(self, arraydescr, array, index):
+    def bh_getarrayitem_gc_f(self, array, index, arraydescr):
         raise NotImplementedError
 
     def bh_getfield_gc_i(self, struct, fielddescr):
@@ -256,49 +256,49 @@
 
     def bh_new(self, sizedescr):
         raise NotImplementedError
-    def bh_new_with_vtable(self, sizedescr, vtable):
+    def bh_new_with_vtable(self, vtable, sizedescr):
         raise NotImplementedError
-    def bh_new_array(self, arraydescr, length):
+    def bh_new_array(self, length, arraydescr):
         raise NotImplementedError
     def bh_newstr(self, length):
         raise NotImplementedError
     def bh_newunicode(self, length):
         raise NotImplementedError
 
-    def bh_arraylen_gc(self, arraydescr, array):
+    def bh_arraylen_gc(self, array, arraydescr):
         raise NotImplementedError
 
     def bh_classof(self, struct):
         raise NotImplementedError
 
-    def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_i(self, array, index, newvalue, arraydescr):
         raise NotImplementedError
-    def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_r(self, array, index, newvalue, arraydescr):
         raise NotImplementedError
-    def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue):
+    def bh_setarrayitem_gc_f(self, array, index, newvalue, arraydescr):
         raise NotImplementedError
 
-    def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_i(self, struct, newvalue, fielddescr):
         raise NotImplementedError
-    def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_r(self, struct, newvalue, fielddescr):
         raise NotImplementedError
-    def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
+    def bh_setfield_gc_f(self, struct, newvalue, fielddescr):
         raise NotImplementedError
 
-    def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_i(self, struct, newvalue, fielddescr):
         raise NotImplementedError
-    def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_r(self, struct, newvalue, fielddescr):
         raise NotImplementedError
-    def bh_setfield_raw_f(self, struct, fielddescr, newvalue):
+    def bh_setfield_raw_f(self, struct, newvalue, fielddescr):
         raise NotImplementedError
 
-    def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_i(self, func, args_i, args_r, args_f, calldescr):
         raise NotImplementedError
-    def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_r(self, func, args_i, args_r, args_f, calldescr):
         raise NotImplementedError
-    def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_f(self, func, args_i, args_r, args_f, calldescr):
         raise NotImplementedError
-    def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
+    def bh_call_v(self, func, args_i, args_r, args_f, calldescr):
         raise NotImplementedError
 
     def bh_strlen(self, string):
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -511,7 +511,7 @@
         calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char,
                                     EffectInfo.MOST_GENERAL)
         x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value,
-                          calldescr, [ord('A')], None, None)
+                          [ord('A')], None, None, calldescr)
         assert x == ord('B')
         if cpu.supports_floats:
             def func(f, i):
@@ -525,8 +525,8 @@
             calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT,
                                         EffectInfo.MOST_GENERAL)
             x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value,
-                              calldescr,
-                              [42], None, [longlong.getfloatstorage(3.5)])
+                              [42], None, [longlong.getfloatstorage(3.5)],
+                              calldescr)
             assert longlong.getrealfloat(x) == 3.5 - 42
 
     def test_call(self):
@@ -1002,7 +1002,7 @@
                                'void', descr=kdescr)
         f = self.cpu.bh_getinteriorfield_gc_f(a_box.getref_base(), 3, kdescr)
         assert longlong.getrealfloat(f) == 1.5
-        self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, kdescr, longlong.getfloatstorage(2.5))
+        self.cpu.bh_setinteriorfield_gc_f(a_box.getref_base(), 3, longlong.getfloatstorage(2.5), kdescr)
         r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)],
                                    'float', descr=kdescr)
         assert r.getfloat() == 2.5
@@ -1028,7 +1028,7 @@
         for name, TYPE in NUMBER_FIELDS[::-1]:
             vdescr = self.cpu.interiorfielddescrof(A, name)
             self.cpu.bh_setinteriorfield_gc_i(a_box.getref_base(), 3,
-                                              vdescr, -25)
+                                              -25, vdescr)
         for name, TYPE in NUMBER_FIELDS:
             vdescr = self.cpu.interiorfielddescrof(A, name)
             r = self.execute_operation(rop.GETINTERIORFIELD_GC,
@@ -1041,8 +1041,8 @@
                                'void', descr=pdescr)
         r = self.cpu.bh_getinteriorfield_gc_r(a_box.getref_base(), 4, pdescr)
         assert r == s_box.getref_base()
-        self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3, pdescr,
-                                          s_box.getref_base())
+        self.cpu.bh_setinteriorfield_gc_r(a_box.getref_base(), 3,
+                                          s_box.getref_base(), pdescr)
         r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3)],
                                    'ref', descr=pdescr)
         assert r.getref_base() == s_box.getref_base()
@@ -1926,7 +1926,7 @@
         assert s.parent.chr2 == chr(150)
         r = self.cpu.bh_getfield_gc_i(r1.value, descrshort)
         assert r == 1313
-        self.cpu.bh_setfield_gc_i(r1.value, descrshort, 1333)
+        self.cpu.bh_setfield_gc_i(r1.value, 1333, descrshort)
         r = self.cpu.bh_getfield_gc_i(r1.value, descrshort)
         assert r == 1333
         r = self.execute_operation(rop.GETFIELD_GC, [r1], 'int',
@@ -2564,13 +2564,13 @@
         A = lltype.GcArray(lltype.Char)
         descr_A = cpu.arraydescrof(A)
         a = lltype.malloc(A, 5)
-        x = cpu.bh_arraylen_gc(descr_A,
-                               lltype.cast_opaque_ptr(llmemory.GCREF, a))
+        x = cpu.bh_arraylen_gc(lltype.cast_opaque_ptr(llmemory.GCREF, a),
+                               descr_A)
         assert x == 5
         #
         a[2] = 'Y'
         x = cpu.bh_getarrayitem_gc_i(
-            descr_A, lltype.cast_opaque_ptr(llmemory.GCREF, a), 2)
+            lltype.cast_opaque_ptr(llmemory.GCREF, a), 2, descr_A)
         assert x == ord('Y')
         #
         B = lltype.GcArray(lltype.Ptr(A))
@@ -2578,7 +2578,7 @@
         b = lltype.malloc(B, 4)
         b[3] = a
         x = cpu.bh_getarrayitem_gc_r(
-            descr_B, lltype.cast_opaque_ptr(llmemory.GCREF, b), 3)
+            lltype.cast_opaque_ptr(llmemory.GCREF, b), 3, descr_B)
         assert lltype.cast_opaque_ptr(lltype.Ptr(A), x) == a
         if self.cpu.supports_floats:
             C = lltype.GcArray(lltype.Float)
@@ -2586,11 +2586,11 @@
             c[3] = 3.5
             descr_C = cpu.arraydescrof(C)
             x = cpu.bh_getarrayitem_gc_f(
-                descr_C, lltype.cast_opaque_ptr(llmemory.GCREF, c), 3)
+                lltype.cast_opaque_ptr(llmemory.GCREF, c), 3, descr_C)
             assert longlong.getrealfloat(x) == 3.5
             cpu.bh_setarrayitem_gc_f(
-                descr_C, lltype.cast_opaque_ptr(llmemory.GCREF, c), 4,
-                longlong.getfloatstorage(4.5))
+                lltype.cast_opaque_ptr(llmemory.GCREF, c), 4,
+                longlong.getfloatstorage(4.5), descr_C)
             assert c[4] == 4.5
         s = rstr.mallocstr(6)
         x = cpu.bh_strlen(lltype.cast_opaque_ptr(llmemory.GCREF, s))
@@ -2610,8 +2610,7 @@
         assert x == ord('Z')
         #
         cpu.bh_setfield_gc_i(lltype.cast_opaque_ptr(llmemory.GCREF, s),
-                             descrfld_x,
-                             ord('4'))
+                             ord('4'), descrfld_x)
         assert s.x == '4'
         #
         descrfld_y = cpu.fielddescrof(S, 'y')
@@ -2622,7 +2621,7 @@
         #
         s.y = lltype.nullptr(A)
         cpu.bh_setfield_gc_r(lltype.cast_opaque_ptr(llmemory.GCREF, s),
-                             descrfld_y, x)
+                             x, descrfld_y)
         assert s.y == a
         #
         RS = lltype.Struct('S', ('x', lltype.Char))  #, ('y', lltype.Ptr(A)))
@@ -2636,7 +2635,7 @@
         #
         cpu.bh_setfield_raw_i(
             heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)),
-            descrfld_rx, ord('!'))
+            ord('!'), descrfld_rx)
         assert rs.x == '!'
         #
 
@@ -2644,7 +2643,7 @@
             descrfld_z = cpu.fielddescrof(S, 'z')
             cpu.bh_setfield_gc_f(
                 lltype.cast_opaque_ptr(llmemory.GCREF, s),
-                descrfld_z, longlong.getfloatstorage(3.5))
+                longlong.getfloatstorage(3.5), descrfld_z)
             assert s.z == 3.5
             s.z = 3.2
             x = cpu.bh_getfield_gc_f(
@@ -2675,21 +2674,21 @@
         vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
         vtable2_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable2))
         heaptracker.register_known_gctype(cpu, vtable2, rclass.OBJECT)
-        x = cpu.bh_new_with_vtable(descrsize2, vtable2_int)
+        x = cpu.bh_new_with_vtable(vtable2_int, descrsize2)
         lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), x)    # type check
         # well...
         #assert x.getref(rclass.OBJECTPTR).typeptr == vtable2
         #
         arraydescr = cpu.arraydescrof(A)
-        x = cpu.bh_new_array(arraydescr, 7)
+        x = cpu.bh_new_array(7, arraydescr)
         array = lltype.cast_opaque_ptr(lltype.Ptr(A), x)
         assert len(array) == 7
         #
-        cpu.bh_setarrayitem_gc_i(descr_A, x, 5, ord('*'))
+        cpu.bh_setarrayitem_gc_i(x, 5, ord('*'), descr_A)
         assert array[5] == '*'
         #
         cpu.bh_setarrayitem_gc_r(
-            descr_B, lltype.cast_opaque_ptr(llmemory.GCREF, b), 1, x)
+            lltype.cast_opaque_ptr(llmemory.GCREF, b), 1, x, descr_B)
         assert b[1] == array
         #
         x = cpu.bh_newstr(5)
@@ -3029,7 +3028,7 @@
             expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value))
             a[3] = rffi.cast(RESTYPE, value)
             x = cpu.bh_getarrayitem_gc_i(
-                descrarray, lltype.cast_opaque_ptr(llmemory.GCREF, a), 3)
+                lltype.cast_opaque_ptr(llmemory.GCREF, a), 3, descrarray)
             assert x == expected, (
                 "%r: got %r, expected %r" % (RESTYPE, x, expected))
 
@@ -3071,7 +3070,7 @@
             expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value))
             a[3] = rffi.cast(RESTYPE, value)
             a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a))
-            x = cpu.bh_getarrayitem_raw_i(descrarray, a_rawint, 3)
+            x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray)
             assert x == expected, (
                 "%r: got %r, expected %r" % (RESTYPE, x, expected))
             lltype.free(a, flavor='raw')
@@ -3129,7 +3128,7 @@
             calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                              EffectInfo.MOST_GENERAL)
             x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value,
-                                   calldescr, [value], None, None)
+                                   [value], None, None, calldescr)
             assert x == expected, (
                 "%r: got %r, expected %r" % (RESTYPE, x, expected))
 
@@ -3198,7 +3197,7 @@
         calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                          EffectInfo.MOST_GENERAL)
         x = self.cpu.bh_call_f(self.get_funcbox(self.cpu, f).value,
-                               calldescr, None, None, [value])
+                               None, None, [value], calldescr)
         assert x == expected
 
     def test_longlong_result_of_call_compiled(self):
@@ -3257,7 +3256,7 @@
         ivalue = longlong.singlefloat2int(value)
         iexpected = longlong.singlefloat2int(expected)
         x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value,
-                               calldescr, [ivalue], None, None)
+                               [ivalue], None, None, calldescr)
         assert x == iexpected
 
     def test_singlefloat_result_of_call_compiled(self):
diff --git a/pypy/jit/backend/x86/test/test_regalloc.py b/pypy/jit/backend/x86/test/test_regalloc.py
--- a/pypy/jit/backend/x86/test/test_regalloc.py
+++ b/pypy/jit/backend/x86/test/test_regalloc.py
@@ -79,6 +79,18 @@
     def _compute_next_usage(self, v, _):
         return -1
 
+
+def get_zero_division_error(self):
+    # for tests, a random emulated ll_inst will do
+    ll_inst = lltype.malloc(rclass.OBJECT)
+    ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
+                                    immortal=True)
+    _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr)
+    zer_vtable = self.cast_adr_to_int(_zer_error_vtable)
+    zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)
+    return zer_vtable, zer_inst
+
+
 class BaseTestRegalloc(object):
     cpu = CPU(None, None)
     cpu.setup_once()
@@ -89,7 +101,7 @@
                               zero_division_value)
     FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
     raising_fptr = llhelper(FPTR, raising_func)
-    zero_division_tp, zero_division_value = cpu.get_zero_division_error()
+    zero_division_tp, zero_division_value = get_zero_division_error(cpu)
     zd_addr = cpu.cast_int_to_adr(zero_division_tp)
     zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
                                             lltype.Ptr(rclass.OBJECT_VTABLE))
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -316,7 +316,8 @@
         kind = self.callcontrol.guess_call_kind(op)
         return getattr(self, 'handle_%s_indirect_call' % kind)(op)
 
-    def rewrite_call(self, op, namebase, initialargs, args=None):
+    def rewrite_call(self, op, namebase, initialargs, args=None,
+                     calldescr=None):
         """Turn 'i0 = direct_call(fn, i1, i2, ref1, ref2)'
            into 'i0 = xxx_call_ir_i(fn, descr, [i1,i2], [ref1,ref2])'.
            The name is one of '{residual,direct}_call_{r,ir,irf}_{i,r,f,v}'."""
@@ -332,6 +333,8 @@
         if 'i' in kinds: sublists.append(lst_i)
         if 'r' in kinds: sublists.append(lst_r)
         if 'f' in kinds: sublists.append(lst_f)
+        if calldescr is not None:
+            sublists.append(calldescr)
         return SpaceOperation('%s_%s_%s' % (namebase, kinds, reskind),
                               initialargs + sublists, op.result)
 
@@ -360,7 +363,7 @@
         of 'residual_call_xxx' are the function to call, and its calldescr."""
         calldescr = self.callcontrol.getcalldescr(op)
         op1 = self.rewrite_call(op, 'residual_call',
-                                [op.args[0], calldescr] + extraargs)
+                                [op.args[0]] + extraargs, calldescr=calldescr)
         if may_call_jitcodes or self.callcontrol.calldescr_canraise(calldescr):
             op1 = [op1, SpaceOperation('-live-', [], None)]
         return op1
@@ -547,7 +550,7 @@
             # XXX only strings or simple arrays for now
             ARRAY = op.args[0].value
             arraydescr = self.cpu.arraydescrof(ARRAY)
-            return SpaceOperation('new_array', [arraydescr, op.args[2]],
+            return SpaceOperation('new_array', [op.args[2], arraydescr],
                                   op.result)
 
     def rewrite_op_free(self, op):
@@ -579,8 +582,8 @@
             kind = getkind(op.result.concretetype)
             return [SpaceOperation('-live-', [], None),
                     SpaceOperation('getarrayitem_vable_%s' % kind[0],
-                                   [v_base, arrayfielddescr, arraydescr,
-                                    op.args[1]], op.result)]
+                                   [v_base, op.args[1], arrayfielddescr,
+                                    arraydescr], op.result)]
         # normal case follows
         pure = ''
         immut = ARRAY._immutable_field(None)
@@ -590,7 +593,7 @@
         kind = getkind(op.result.concretetype)
         return SpaceOperation('getarrayitem_%s_%s%s' % (ARRAY._gckind,
                                                         kind[0], pure),
-                              [op.args[0], arraydescr, op.args[1]],
+                              [op.args[0], op.args[1], arraydescr],
                               op.result)
 
     def rewrite_op_setarrayitem(self, op):
@@ -603,12 +606,12 @@
             kind = getkind(op.args[2].concretetype)
             return [SpaceOperation('-live-', [], None),
                     SpaceOperation('setarrayitem_vable_%s' % kind[0],
-                                   [v_base, arrayfielddescr, arraydescr,
-                                    op.args[1], op.args[2]], None)]
+                                   [v_base, op.args[1], op.args[2],
+                                    arrayfielddescr, arraydescr], None)]
         arraydescr = self.cpu.arraydescrof(ARRAY)
         kind = getkind(op.args[2].concretetype)
         return SpaceOperation('setarrayitem_%s_%s' % (ARRAY._gckind, kind[0]),
-                              [op.args[0], arraydescr, op.args[1], op.args[2]],
+                              [op.args[0], op.args[1], op.args[2], arraydescr],
                               None)
 
     def rewrite_op_getarraysize(self, op):
@@ -702,14 +705,14 @@
             kind = getkind(RESULT)[0]
             return [SpaceOperation('-live-', [], None),
                     SpaceOperation('setfield_vable_%s' % kind,
-                                   [v_inst, descr, v_value], None)]
+                                   [v_inst, v_value, descr], None)]
         self.check_field_access(v_inst.concretetype.TO)
         argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc')
         descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
                                       c_fieldname.value)
         kind = getkind(RESULT)[0]
         return SpaceOperation('setfield_%s_%s' % (argname, kind),
-                              [v_inst, descr, v_value],
+                              [v_inst, v_value, descr],
                               None)
 
     def rewrite_op_getsubstruct(self, op):
@@ -877,7 +880,7 @@
         assert kind != 'r'
         descr = self.cpu.arraydescrof(rffi.CArray(T))
         return SpaceOperation('raw_store_%s' % kind,
-                              [op.args[0], op.args[1], descr, op.args[2]],
+                              [op.args[0], op.args[1], op.args[2], descr],
                               None)
 
     def rewrite_op_raw_load(self, op):
@@ -1314,7 +1317,7 @@
     def promote_greens(self, args, jitdriver):
         ops = []
         num_green_args = len(jitdriver.greens)
-        assert len(args) == num_green_args + len(jitdriver.reds)
+        assert len(args) == num_green_args + jitdriver.numreds
         for v in args[:num_green_args]:
             if isinstance(v, Variable) and v.concretetype is not lltype.Void:
                 kind = getkind(v.concretetype)
@@ -1455,8 +1458,8 @@
             v_posindex = Variable('posindex')
             v_posindex.concretetype = lltype.Signed
             op0 = SpaceOperation('-live-', [], None)
-            op1 = SpaceOperation(checkname, [args[0],
-                                             descr, args[1]], v_posindex)
+            op1 = SpaceOperation(checkname, [args[0], args[1],
+                                             descr], v_posindex)
             return v_posindex, [op0, op1]
 
     def _prepare_void_list_getset(self, op):
@@ -1491,7 +1494,7 @@
             v = Variable('new_length')
             v.concretetype = lltype.Signed
             ops.append(SpaceOperation('int_force_ge_zero', [v_length], v))
-        ops.append(SpaceOperation('new_array', [arraydescr, v], op.result))
+        ops.append(SpaceOperation('new_array', [v, arraydescr], op.result))
         return ops
 
     def do_fixed_list_len(self, op, args, arraydescr):
@@ -1513,15 +1516,15 @@
             kind = getkind(op.result.concretetype)
             return [SpaceOperation('-live-', [], None),
                     SpaceOperation('getarrayitem_vable_%s' % kind[0],
-                                   [v_base, arrayfielddescr, arraydescr,
-                                    args[1]], op.result)]
+                                   [v_base, args[1], arrayfielddescr,
+                                    arraydescr], op.result)]
         v_index, extraop = self._prepare_list_getset(op, arraydescr, args,
                                                      'check_neg_index')
         extra = getkind(op.result.concretetype)[0]
         if pure:
             extra += '_pure'
         op = SpaceOperation('getarrayitem_gc_%s' % extra,
-                            [args[0], arraydescr, v_index], op.result)
+                            [args[0], v_index, arraydescr], op.result)
         return extraop + [op]
 
     def do_fixed_list_getitem_foldable(self, op, args, arraydescr):
@@ -1534,13 +1537,13 @@
             kind = getkind(args[2].concretetype)
             return [SpaceOperation('-live-', [], None),
                     SpaceOperation('setarrayitem_vable_%s' % kind[0],
-                                   [v_base, arrayfielddescr, arraydescr,
-                                    args[1], args[2]], None)]
+                                   [v_base, args[1], args[2],
+                                    arrayfielddescr, arraydescr], None)]
         v_index, extraop = self._prepare_list_getset(op, arraydescr, args,
                                                      'check_neg_index')
         kind = getkind(args[2].concretetype)[0]
         op = SpaceOperation('setarrayitem_gc_%s' % kind,
-                            [args[0], arraydescr, v_index, args[2]], None)
+                            [args[0], v_index, args[2], arraydescr], None)
         return extraop + [op]
 
     def do_fixed_list_ll_arraycopy(self, op, args, arraydescr):
@@ -1558,16 +1561,16 @@
                              itemsdescr, structdescr):
         v_length = self._get_initial_newlist_length(op, args)
         return SpaceOperation('newlist',
-                              [structdescr, lengthdescr, itemsdescr,
-                               arraydescr, v_length],
+                              [v_length, structdescr, lengthdescr, itemsdescr,
+                               arraydescr],
                               op.result)
 
     def do_resizable_newlist_hint(self, op, args, arraydescr, lengthdescr,
                                   itemsdescr, structdescr):
         v_hint = self._get_initial_newlist_length(op, args)
         return SpaceOperation('newlist_hint',
-                              [structdescr, lengthdescr, itemsdescr,
-                               arraydescr, v_hint],
+                              [v_hint, structdescr, lengthdescr, itemsdescr,
+                               arraydescr],
                               op.result)
 
     def do_resizable_list_getitem(self, op, args, arraydescr, lengthdescr,
@@ -1576,7 +1579,7 @@
                                                  'check_resizable_neg_index')
         kind = getkind(op.result.concretetype)[0]
         op = SpaceOperation('getlistitem_gc_%s' % kind,
-                            [args[0], itemsdescr, arraydescr, v_index],
+                            [args[0], v_index, itemsdescr, arraydescr],
                             op.result)
         return extraop + [op]
 
@@ -1586,8 +1589,8 @@
                                                  'check_resizable_neg_index')
         kind = getkind(args[2].concretetype)[0]
         op = SpaceOperation('setlistitem_gc_%s' % kind,
-                            [args[0], itemsdescr, arraydescr,
-                             v_index, args[2]], None)
+                            [args[0], v_index, args[2],
+                             itemsdescr, arraydescr], None)
         return extraop + [op]
 
     def do_resizable_list_len(self, op, args, arraydescr, lengthdescr,
@@ -1618,8 +1621,8 @@
             self.callcontrol.callinfocollection.add(oopspecindex,
                                                     calldescr, func)
         op1 = self.rewrite_call(op, 'residual_call',
-                                [op.args[0], calldescr],
-                                args=args)
+                                [op.args[0]],
+                                args=args, calldescr=calldescr)
         if self.callcontrol.calldescr_canraise(calldescr):
             op1 = [op1, SpaceOperation('-live-', [], None)]
         return op1
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -78,28 +78,32 @@
     link = split_block(None, portalblock, 0, greens_v + reds_v)
     return link.target
 
+def sort_vars(args_v):
+    from pypy.jit.metainterp.history import getkind
+    _kind2count = {'int': 1, 'ref': 2, 'float': 3}
+    return sorted(args_v, key=lambda v: _kind2count[getkind(v.concretetype)])
+
 def decode_hp_hint_args(op):
     # Returns (list-of-green-vars, list-of-red-vars) without Voids.
     # Both lists must be sorted: first INT, then REF, then FLOAT.
     assert op.opname == 'jit_marker'
     jitdriver = op.args[1].value
     numgreens = len(jitdriver.greens)
-    numreds = len(jitdriver.reds)
+    assert jitdriver.numreds is not None
+    numreds = jitdriver.numreds
     greens_v = op.args[2:2+numgreens]
     reds_v = op.args[2+numgreens:]
     assert len(reds_v) == numreds
     #
     def _sort(args_v, is_green):
-        from pypy.jit.metainterp.history import getkind
         lst = [v for v in args_v if v.concretetype is not lltype.Void]
         if is_green:
             assert len(lst) == len(args_v), (
                 "not supported so far: 'greens' variables contain Void")
-        _kind2count = {'int': 1, 'ref': 2, 'float': 3}
-        lst2 = sorted(lst, key=lambda v: _kind2count[getkind(v.concretetype)])
         # a crash here means that you have to reorder the variable named in
         # the JitDriver.  Indeed, greens and reds must both be sorted: first
         # all INTs, followed by all REFs, followed by all FLOATs.
+        lst2 = sort_vars(lst)
         assert lst == lst2
         return lst
     #
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -371,7 +371,7 @@
                 return 4
 
         self.encoding_test(f, [65], """
-            residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+            residual_call_ir_v $<* fn g>, I[%i0], R[], <Descr>
             -live-
             catch_exception L1
             int_return $4
@@ -430,16 +430,16 @@
                 foo.sideeffect = 5
 
         self.encoding_test(f, [65], """
-        residual_call_ir_v $<* fn get_exception>, <Descr>, I[%i0], R[]
+        residual_call_ir_v $<* fn get_exception>, I[%i0], R[], <Descr>
         -live-
         catch_exception L1
-        setfield_gc_i $<* struct test.Foo>, <Descr>, $5
+        setfield_gc_i $<* struct test.Foo>, $5, <Descr>
         void_return
         ---
         L1:
         last_exception -> %i1
         last_exc_value -> %r0
-        setfield_gc_i $<* struct test.Foo>, <Descr>, $5
+        setfield_gc_i $<* struct test.Foo>, $5, <Descr>
         -live-
         raise %r0
         """, transform=True)
@@ -470,7 +470,7 @@
             except ZeroDivisionError:
                 return -42
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+            residual_call_ir_i $<* fn int_floordiv_ovf_zer>, I[%i0, %i1], R[], <Descr> -> %i2
             -live-
             catch_exception L1
             int_return %i2
@@ -497,7 +497,7 @@
                 return 42
         # XXX so far, this really produces a int_mod_ovf_zer...
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+            residual_call_ir_i $<* fn int_mod_ovf_zer>, I[%i0, %i1], R[], <Descr> -> %i2
             -live-
             catch_exception L1
             int_return %i2
@@ -551,7 +551,7 @@
             except Exception:
                 return 42 + j
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[] -> %i2
+            residual_call_ir_i $<* fn g>, I[%i0, %i1], R[], <Descr> -> %i2
             -live- %i1, %i2
             catch_exception L1
             int_return %i2
@@ -572,7 +572,7 @@
             except Exception:
                 return 42 + j
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn cannot_raise>, <Descr>, I[%i0, %i1], R[] -> %i2
+            residual_call_ir_i $<* fn cannot_raise>, I[%i0, %i1], R[], <Descr> -> %i2
             int_return %i2
         """, transform=True, liveness=True)
 
@@ -620,18 +620,18 @@
             keepalive_until_here(q)
             return x
         self.encoding_test(f, [5], """
-            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+            residual_call_r_r $<* fn g>, R[], <Descr> -> %r0
             -live-
-            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+            residual_call_r_r $<* fn g>, R[], <Descr> -> %r1
             -live-
             -live- %r0
             -live- %r1
             int_return %i0
         """, transform=True)
         self.encoding_test(f, [5], """
-            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+            residual_call_r_r $<* fn g>, R[], <Descr> -> %r0
             -live- %i0, %r0
-            residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+            residual_call_r_r $<* fn g>, R[], <Descr> -> %r1
             -live- %i0, %r0, %r1
             -live- %i0, %r0, %r1
             -live- %i0, %r1
@@ -676,7 +676,7 @@
         self.encoding_test(f, [], """
             new_with_vtable <Descr> -> %r0
             virtual_ref %r0 -> %r1
-            residual_call_r_r $<* fn jit_force_virtual>, <Descr>, R[%r1] -> %r2
+            residual_call_r_r $<* fn jit_force_virtual>, R[%r1], <Descr> -> %r2
             ref_return %r2
         """, transform=True, cc=FakeCallControlWithVRefInfo())
 
@@ -687,9 +687,9 @@
             array[2] = 5
             return array[2] + len(array)
         self.encoding_test(f, [], """
-            new_array <Descr>, $5 -> %r0
-            setarrayitem_gc_i %r0, <Descr>, $2, $5
-            getarrayitem_gc_i %r0, <Descr>, $2 -> %i0
+            new_array $5, <Descr> -> %r0
+            setarrayitem_gc_i %r0, $2, $5, <Descr>
+            getarrayitem_gc_i %r0, $2, <Descr> -> %i0
             arraylen_gc %r0, <Descr> -> %i1
             int_add %i0, %i1 -> %i2
             int_return %i2


More information about the pypy-commit mailing list