Commits

Philip Jenvey committed 45b18e9 Merge

merge default

  • Participants
  • Parent commits 8dc61b6, a4a4556
  • Branches py3k

Comments (0)

Files changed (84)

File pypy/doc/coding-guide.rst

 
 + methods and other class attributes do not change after startup
 + single inheritance is fully supported
-+ simple mixins somewhat work too, but the mixed in class needs a
-  ``_mixin_ = True`` class attribute. isinstance checks against the
-  mixin type will fail when translated.
++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class
+  body to copy the whole content of a class `M`.  This can be used
+  to implement mixins: functions and staticmethods are duplicated
+  (the other class attributes are just copied unmodified).
 
 + classes are first-class objects too
 

File pypy/doc/getting-started-python.rst

      zlib-devel bzip2-devel ncurses-devel expat-devel \
      openssl-devel gc-devel python-sphinx python-greenlet
 
+   On SLES11:
+
+     $ sudo zypper install gcc make python-devel pkg-config \
+     zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
+     libexpat-devel libffi-devel python-curses
+
    The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones.
 
    * ``pkg-config`` (to help us locate libffi files)

File pypy/doc/whatsnew-head.rst

 .. branch: dotviewer-linewidth
 .. branch: reflex-support
 .. branch: numpypy-inplace-op
+.. branch: rewritten-loop-logging

File pypy/doc/windows.rst

 The following text gives some hints about how to translate the PyPy
 interpreter.
 
+PyPy supports only being translated as a 32bit program, even on
+64bit Windows.  See at the end of this page for what is missing
+for a full 64bit translation.
+
 To build pypy-c you need a C compiler.  Microsoft Visual Studio is
 preferred, but can also use the mingw32 port of gcc.
 
 INCLUDE, LIB and PATH (for DLLs) environment variables appropriately.
 
 Abridged method (for -Ojit builds using Visual Studio 2008)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Download the versions of all the external packages
 from 
 https://bitbucket.org/pypy/pypy/downloads/local.zip
     nmake -f makefile.msc
     
 The sqlite3 database library
-~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract
 it into a directory under the base directory. Also get 
 http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll
 into the bin directory, and the sqlite3.def into the sources directory.
 Now build the import library so cffi can use the header and dll::
+
     lib /DEF:sqlite3.def" /OUT:sqlite3.lib"
     copy sqlite3.lib path\to\libs
 
 March 2012, --cc is not a valid option for pytest.py. However if you set an
 environment variable CC to the compliter exe, testing will use it.
 
-.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
+.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
 .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds
 .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29   
 .. _`libffi source files`: http://sourceware.org/libffi/
 .. _`RPython translation toolchain`: translation.html
+
+
+What is missing for a full 64-bit translation
+---------------------------------------------
+
+The main blocker is that we assume that the integer type of RPython is
+large enough to (occasionally) contain a pointer value cast to an
+integer.  The simplest fix is to make sure that it is so, but it will
+give the following incompatibility between CPython and PyPy on Win64:
+  
+CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1``
+
+PyPy: ``sys.maxint == sys.maxsize == 2**64-1``
+
+...and, correspondingly, PyPy supports ints up to the larger value of
+sys.maxint before they are converted to ``long``.  The first decision
+that someone needs to make is if this incompatibility is reasonable.
+
+Assuming that it is, the first thing to do is probably to hack *CPython*
+until it fits this model: replace the field in PyIntObject with a ``long
+long`` field, and change the value of ``sys.maxint``.  This might just
+work, even if half-brokenly: I'm sure you can crash it because of the
+precision loss that undoubtedly occurs everywhere, but try not to. :-)
+
+Such a hacked CPython is what you'll use in the next steps.  We'll call
+it CPython64/64.
+
+It is probably not too much work if the goal is only to get a translated
+PyPy executable, and to run all tests before transaction.  But you need
+to start somewhere, and you should start with some tests in
+rpython/translator/c/test/, like ``test_standalone.py`` and
+``test_newgc.py``: try to have them pass on top of CPython64/64.
+
+Keep in mind that this runs small translations, and some details may go
+wrong.  The most obvious one is to check that it produces C files that
+use the integer type ``Signed`` --- but what is ``Signed`` defined to?
+It should be equal to ``long`` on every other platforms, but on Win64 it
+should be something like ``long long``.
+
+What is more generally needed is to review all the C files in
+rpython/translator/c/src for the word ``long``, because this means a
+32-bit integer even on Win64.  Replace it with ``Signed`` most of the
+times.  You can replace one with the other without breaking anything on
+any other platform, so feel free to.
+
+Then, these two C types have corresponding RPython types: ``rffi.LONG``
+and ``lltype.Signed`` respectively.  The first should really correspond
+to the C ``long``.  Add tests that check that integers casted to one
+type or the other really have 32 and 64 bits respectively, on Win64.
+
+Once these basic tests work, you need to review ``rpython/rlib/`` for
+usages of ``rffi.LONG`` versus ``lltype.Signed``.  The goal would be to
+fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as
+always run on top of CPython64/64.  Note that there was some early work
+done in ``rpython/rlib/rarithmetic`` with the goal of running all the
+tests on Win64 on the regular CPython, but I think by now that it's a
+bad idea.  Look only at CPython64/64.
+
+The major intermediate goal is to get a translation of PyPy with ``-O2``
+with a minimal set of modules, starting with ``--no-allworkingmodules``;
+you need to use CPython64/64 to run this translation too.  Check
+carefully the warnings of the C compiler at the end.  I think that MSVC
+is "nice" in the sense that by default a lot of mismatches of integer
+sizes are reported as warnings.
+
+Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed``
+issues.  At some time during this review, we get a working translated
+PyPy on Windows 64 that includes all ``--translationmodules``, i.e.
+everything needed to run translations.  When we are there, the hacked
+CPython64/64 becomes much less important, because we can run future
+translations on top of this translated PyPy.  As soon as we get there,
+please *distribute* the translated PyPy.  It's an essential component
+for anyone else that wants to work on Win64!  We end up with a strange
+kind of dependency --- we need a translated PyPy in order to translate a
+PyPy ---, but I believe it's ok here, as Windows executables are
+supposed to never be broken by newer versions of Windows.
+
+Happy hacking :-)

File pypy/interpreter/buffer.py

 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import compute_hash
+from rpython.rlib.objectmodel import compute_hash, import_from_mixin
 from rpython.rlib.rstring import StringBuilder
 
 
 # ____________________________________________________________
 
 class SubBufferMixin(object):
-    _mixin_ = True
-
     def __init__(self, buffer, offset, size):
         self.buffer = buffer
         self.offset = offset
                           # out of bounds
         return self.buffer.getslice(self.offset + start, self.offset + stop, step, size)
 
-class SubBuffer(SubBufferMixin, Buffer):
-    pass
+class SubBuffer(Buffer):
+    import_from_mixin(SubBufferMixin)
 
-class RWSubBuffer(SubBufferMixin, RWBuffer):
+class RWSubBuffer(RWBuffer):
+    import_from_mixin(SubBufferMixin)
 
     def setitem(self, index, char):
         self.buffer.setitem(self.offset + index, char)

File pypy/module/__pypy__/test/test_signal.py

                     _thread.interrupt_main()
                     for i in range(10):
                         print('x')
-                        time.sleep(0.1)
+                        time.sleep(0.25)
             except BaseException as e:
                 interrupted.append(e)
             finally:
                 for j in range(10):
                     if len(done): break
                     print('.')
-                    time.sleep(0.1)
+                    time.sleep(0.25)
                 print('main thread loop done')
                 assert len(done) == 1
                 assert len(interrupted) == 1
 
         def subthread():
             try:
-                time.sleep(0.25)
+                time.sleep(0.5)
                 with __pypy__.thread.signals_enabled:
                     _thread.interrupt_main()
             except BaseException as e:

File pypy/module/array/interp_array.py

 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.objectmodel import keepalive_until_here
 from rpython.rtyper.lltypesystem import lltype, rffi
-
+from pypy.objspace.std.floatobject import W_FloatObject
 
 @unwrap_spec(typecode=str)
 def w_array(space, w_cls, typecode, __args__):
 
 
 class TypeCode(object):
-    def __init__(self, itemtype, unwrap, canoverflow=False, signed=False):
+    def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'):
         self.itemtype = itemtype
         self.bytes = rffi.sizeof(itemtype)
         self.arraytype = lltype.Array(itemtype, hints={'nolength': True})
         self.signed = signed
         self.canoverflow = canoverflow
         self.w_class = None
+        self.method = method
 
         if self.canoverflow:
             assert self.bytes <= rffi.sizeof(rffi.ULONG)
 
 
 types = {
-    'u': TypeCode(lltype.UniChar,     'unicode_w'),
+    'u': TypeCode(lltype.UniChar,     'unicode_w', method=''),
     'b': TypeCode(rffi.SIGNEDCHAR,    'int_w', True, True),
     'B': TypeCode(rffi.UCHAR,         'int_w', True),
     'h': TypeCode(rffi.SHORT,         'int_w', True, True),
                                                     # rbigint.touint() which
                                                     # corresponds to the
                                                     # C-type unsigned long
-    'f': TypeCode(lltype.SingleFloat, 'float_w'),
-    'd': TypeCode(lltype.Float,       'float_w'),
+    'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'),
+    'd': TypeCode(lltype.Float,       'float_w', method='__float__'),
     }
 for k, v in types.items():
     v.typecode = k
         def item_w(self, w_item):
             space = self.space
             unwrap = getattr(space, mytype.unwrap)
-            item = unwrap(w_item)
+            try:
+                item = unwrap(w_item)
+            except OperationError, e:
+                if isinstance(w_item, W_FloatObject): # Odd special case from cpython
+                    raise
+                if mytype.method != '' and e.match(space, space.w_TypeError):
+                    try:
+                        item = unwrap(space.call_method(w_item, mytype.method))
+                    except OperationError:
+                        msg = 'array item must be ' + mytype.unwrap[:-2]
+                        raise OperationError(space.w_TypeError, space.wrap(msg))                        
+                else:
+                    raise
             if mytype.unwrap == 'bigint_w':
                 try:
                     item = item.touint()

File pypy/module/array/test/test_array.py

             raises(TypeError, a.__setitem__, Silly())
             raises(TypeError, a.__setitem__, OldSilly())
             
+        a = array('c', 'hi')
+        a[0] = 'b'
+        assert a[0] == 'b'
+            
+        a = array('u', u'hi')
+        a[0] = u'b'
+        assert a[0] == u'b'
+        
     def test_bytearray(self):
         a = self.array('u', 'hi')
         b = self.array('u')

File pypy/module/micronumpy/interp_dtype.py

             name='string',
             char='S',
             w_box_type = space.gettypefor(interp_boxes.W_StringBox),
-            alternate_constructors=[space.w_str],
+            alternate_constructors=[space.w_str, space.gettypefor(interp_boxes.W_CharacterBox)],
             aliases=["str"],
         )
         self.w_unicodedtype = W_Dtype(

File pypy/module/micronumpy/test/test_dtypes.py

         from numpypy import unicode_
         assert isinstance(unicode_(3), str)
 
+    def test_character_dtype(self):
+        from numpypy import array, character
+        x = array([["A", "B"], ["C", "D"]], character)
+        assert (x == [["A", "B"], ["C", "D"]]).all()
+
 class AppTestRecordDtypes(BaseNumpyAppTest):
     spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
     def test_create(self):

File pypy/module/micronumpy/test/test_numarray.py

         a = numpy.arange(10.).reshape((5, 2))[::2]
         assert (loads(dumps(a)) == a).all()
 
+    def test_string_filling(self):
+        import numpypy as numpy
+        a = numpy.empty((10,10), dtype='c1')
+        a.fill(12)
+        assert (a == '1').all()
+
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
         import numpypy

File pypy/module/micronumpy/test/test_ufuncs.py

 
     def test_rint(self):
         from numpypy import array, complex, rint, isnan
+        import sys
 
         nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf')
 
         assert rint(complex(inf, 1.5)) == complex(inf, 2.)
         assert rint(complex(0.5, inf)) == complex(0., inf)
 
+        assert rint(sys.maxint) > 0.0
+
     def test_sign(self):
         from numpypy import array, sign, dtype
 

File pypy/module/micronumpy/types.py

         return min(v1, v2)
 
     @simple_unary_op
-    def rint(self, v):
-        if isfinite(v):
-            return rfloat.round_double(v, 0, half_even=True)
-        else:
-            return v
-
-    @simple_unary_op
     def ones_like(self, v):
         return 1
 
     def zeros_like(self, v):
         return 0
 
+    @raw_unary_op
+    def rint(self, v):
+        float64 = Float64()
+        return float64.rint(float64.box(v))
 
 class NonNativePrimitive(Primitive):
     _mixin_ = True
         else:
             return v1 + v2
 
+    @simple_unary_op
+    def rint(self, v):
+        x = float(v)
+        if isfinite(x):
+            import math
+            y = math.floor(x)
+            r = x - y
+
+            if r > 0.5:
+                y += 1.0
+
+            if r == 0.5:
+                r = y - 2.0 * math.floor(0.5 * y)
+                if r == 1.0:
+                    y += 1.0
+            return y
+        else:
+            return x
+
 class NonNativeFloat(NonNativePrimitive, Float):
     _mixin_ = True
 
             arr.storage[i] = arg[i]
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
 
-    @jit.unroll_safe
     def store(self, arr, i, offset, box):
         assert isinstance(box, interp_boxes.W_StringBox)
         # XXX simplify to range(box.dtype.get_size()) ?
+        return self._store(arr.storage, i, offset, box)
+
+    @jit.unroll_safe
+    def _store(self, storage, i, offset, box):
+        assert isinstance(box, interp_boxes.W_StringBox)
         for k in range(min(self.size, box.arr.size-offset)):
-            arr.storage[k + i] = box.arr.storage[k + offset]
+            storage[k + i] = box.arr.storage[k + offset]
 
     def read(self, arr, i, offset, dtype=None):
         if dtype is None:
             arr.storage[j] = '\x00'
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
 
+    def fill(self, storage, width, box, start, stop, offset):
+        from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArrayNotOwning
+        for i in xrange(start, stop, width):
+            self._store(storage, i, offset, box)
+
 NonNativeStringType = StringType
 
 class UnicodeType(BaseType, BaseStringType):

File pypy/module/posix/interp_posix.py

File contents unchanged.

File pypy/objspace/descroperation.py

         greens=['w_type'], reds='auto')
 
 class DescrOperation(object):
-    _mixin_ = True
+    # This is meant to be a *mixin*.
 
     def is_data_descr(space, w_obj):
         return space.lookup(w_obj, '__set__') is not None
         elif _arity == 2 and len(_specialnames) == 2:
             #print "binop", _specialnames
             _impl_maker = _make_binop_impl
-        elif _arity == 1 and len(_specialnames) == 1:
+        elif _arity == 1 and len(_specialnames) == 1 and _name != 'int':
             #print "unaryop", _specialnames
             _impl_maker = _make_unaryop_impl
         if _impl_maker:
             setattr(DescrOperation,_name,_impl_maker(_symbol,_specialnames))
-        elif _name not in ['is_', 'id','type','issubtype',
+        elif _name not in ['is_', 'id','type','issubtype', 'int',
                            # not really to be defined in DescrOperation
                            'ord', 'unichr', 'unicode']:
             raise Exception, "missing def for operation %s" % _name

File pypy/objspace/std/builtinshortcut.py

                 w_obj = w_res
 
         # general case fallback
-        return DescrOperation.is_true(space, w_obj)
+        return _DescrOperation_is_true(space, w_obj)
 
+    _DescrOperation_is_true = DescrOperation.is_true.im_func
     space.is_true = is_true

File pypy/objspace/std/bytearrayobject.py

 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std import stringobject
 from pypy.objspace.std.bytearraytype import new_bytearray
-from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.longobject import W_LongObject
 from pypy.objspace.std.model import W_Object, registerimplementation
 from pypy.objspace.std.multimethod import FailedToImplement
 
 def len__Bytearray(space, w_bytearray):
     result = len(w_bytearray.data)
-    return wrapint(space, result)
+    return space.newint(result)
 
 def ord__Bytearray(space, w_bytearray):
     if len(w_bytearray.data) != 1:

File pypy/objspace/std/dictmultiobject.py

             return _all_contained_in(space, self, w_other)
         return space.w_False
 
-    def descr_ne(self, space, w_other):
-        if not _is_set_like(w_other):
-            return space.w_NotImplemented
-        return space.not_(space.eq(self, w_other))
+    descr_ne = negate(descr_eq)
 
     def descr_lt(self, space, w_other):
         if not _is_set_like(w_other):

File pypy/objspace/std/intobject.py

+"""The builtin int implementation
+
+In order to have the same behavior running on CPython, and after RPython
+translation this module uses rarithmetic.ovfcheck to explicitly check
+for overflows, something CPython does not do anymore.
+"""
+
+from rpython.rlib import jit
+from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int, ovfcheck, r_uint
+from rpython.rlib.rbigint import rbigint
+
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std import newformat
-from pypy.objspace.std.inttype import wrapint, W_AbstractIntObject
-from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.inttype import W_AbstractIntObject
+from pypy.objspace.std.model import W_Object, registerimplementation
 from pypy.objspace.std.multimethod import FailedToImplementArgs
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.register_all import register_all
-from rpython.rlib import jit
-from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint, is_valid_int
-from rpython.rlib.rbigint import rbigint
 
-"""
-In order to have the same behavior running
-on CPython, and after RPython translation we use ovfcheck
-from rarithmetic to explicitly check for overflows,
-something CPython does not do anymore.
-"""
 
 class W_IntObject(W_AbstractIntObject):
     __slots__ = 'intval'
 
 #    from pypy.objspace.std.inttype import int_typedef as typedef
 
-    def __init__(w_self, intval):
+    def __init__(self, intval):
         assert is_valid_int(intval)
-        w_self.intval = intval
+        self.intval = intval
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%d)" % (w_self.__class__.__name__, w_self.intval)
+    def __repr__(self):
+        """representation for debugging purposes"""
+        return "%s(%d)" % (self.__class__.__name__, self.intval)
 
-    def unwrap(w_self, space):
-        return int(w_self.intval)
+    def unwrap(self, space):
+        return int(self.intval)
     int_w = unwrap
 
-    def uint_w(w_self, space):
-        intval = w_self.intval
+    def uint_w(self, space):
+        intval = self.intval
         if intval < 0:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("cannot convert negative integer to unsigned"))
+            raise OperationError(
+                space.w_ValueError,
+                space.wrap("cannot convert negative integer to unsigned"))
         else:
             return r_uint(intval)
 
-    def bigint_w(w_self, space):
-        return rbigint.fromint(w_self.intval)
+    def bigint_w(self, space):
+        return rbigint.fromint(self.intval)
 
     def float_w(self, space):
         return float(self.intval)
         if space.is_w(space.type(self), space.w_int):
             return self
         a = self.intval
-        return wrapint(space, a)
+        return space.newint(a)
 
 #registerimplementation(W_IntObject)
 
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer addition"))
-    return wrapint(space, z)
+    return space.newint(z)
 
 def sub__Int_Int(space, w_int1, w_int2):
     x = w_int1.intval
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer substraction"))
-    return wrapint(space, z)
+    return space.newint(z)
 
 def mul__Int_Int(space, w_int1, w_int2):
     x = w_int1.intval
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer multiplication"))
-    return wrapint(space, z)
+    return space.newint(z)
 
 def floordiv__Int_Int(space, w_int1, w_int2):
     x = w_int1.intval
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer division"))
-    return wrapint(space, z)
+    return space.newint(z)
 div__Int_Int = floordiv__Int_Int
 
 def truediv__Int_Int(space, w_int1, w_int2):
     x = float(w_int1.intval)
     y = float(w_int2.intval)
     if y == 0.0:
-        raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division"))
+        raise FailedToImplementArgs(space.w_ZeroDivisionError,
+                                    space.wrap("float division"))
     return space.wrap(x / y)
 
 def mod__Int_Int(space, w_int1, w_int2):
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer modulo"))
-    return wrapint(space, z)
+    return space.newint(z)
 
 def divmod__Int_Int(space, w_int1, w_int2):
     x = w_int1.intval
     except OverflowError:
         raise FailedToImplementArgs(space.w_OverflowError,
                                 space.wrap("integer negation"))
-    return wrapint(space, x)
+    return space.newint(x)
 get_negint = neg__Int
 
 
 def invert__Int(space, w_int1):
     x = w_int1.intval
     a = ~x
-    return wrapint(space, a)
+    return space.newint(a)
 
 def lshift__Int_Int(space, w_int1, w_int2):
     a = w_int1.intval
         except OverflowError:
             raise FailedToImplementArgs(space.w_OverflowError,
                                     space.wrap("integer left shift"))
-        return wrapint(space, c)
+        return space.newint(c)
     if b < 0:
         raise OperationError(space.w_ValueError,
                              space.wrap("negative shift count"))
                 a = 0
     else:
         a = a >> b
-    return wrapint(space, a)
+    return space.newint(a)
 
 def and__Int_Int(space, w_int1, w_int2):
     a = w_int1.intval
     b = w_int2.intval
     res = a & b
-    return wrapint(space, res)
+    return space.newint(res)
 
 def xor__Int_Int(space, w_int1, w_int2):
     a = w_int1.intval
     b = w_int2.intval
     res = a ^ b
-    return wrapint(space, res)
+    return space.newint(res)
 
 def or__Int_Int(space, w_int1, w_int2):
     a = w_int1.intval
     b = w_int2.intval
     res = a | b
-    return wrapint(space, res)
+    return space.newint(res)
 
 def pos__Int(self, space):
     return self.int(space)
     return space.newfloat(x)
 
 def getnewargs__Int(space, w_int1):
-    return space.newtuple([wrapint(space, w_int1.intval)])
+    return space.newtuple([space.newint(w_int1.intval)])
 
 
 register_all(vars())

File pypy/objspace/std/listobject.py

 from pypy.objspace.std import slicetype
 from pypy.objspace.std.floatobject import W_FloatObject
 from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.iterobject import (W_FastListIterObject,
     W_ReverseSeqIterObject)
 from pypy.objspace.std.sliceobject import W_SliceObject
 
     def descr_len(self, space):
         result = self.length()
-        return wrapint(space, result)
+        return space.newint(result)
 
     def descr_iter(self, space):
         return W_FastListIterObject(self)

File pypy/objspace/std/longobject.py

+"""The builtin long implementation"""
+
 import sys
+
+from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rbigint import SHIFT, _widen_digit, rbigint
+
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std import model, newformat
-from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.longtype import W_AbstractLongObject, long_typedef
+from pypy.objspace.std.model import W_Object, registerimplementation
+from pypy.objspace.std.multimethod import FailedToImplementArgs
+from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.noneobject import W_NoneObject
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib.rbigint import SHIFT, _widen_digit, rbigint
-from pypy.objspace.std.longtype import long_typedef, W_AbstractLongObject
 
 HASH_BITS = 61 if sys.maxsize > 2 ** 31 - 1 else 31
 HASH_MODULUS = 2 ** HASH_BITS - 1
 
+
 class W_LongObject(W_AbstractLongObject):
     """This is a wrapper of rbigint."""
     _immutable_fields_ = ['num']
 
     typedef = long_typedef
 
-    def __init__(w_self, l):
-        w_self.num = l # instance of rbigint
+    def __init__(self, l):
+        self.num = l # instance of rbigint
 
     def fromint(space, intval):
         return W_LongObject(rbigint.fromint(intval))
     fromrarith_int._annspecialcase_ = "specialize:argtype(0)"
     fromrarith_int = staticmethod(fromrarith_int)
 
-    def int_w(w_self, space):
+    def int_w(self, space):
         try:
-            return w_self.num.toint()
+            return self.num.toint()
         except OverflowError:
             raise OperationError(space.w_OverflowError, space.wrap(
                 "long int too large to convert to int"))
 
-    def uint_w(w_self, space):
+    def uint_w(self, space):
         try:
-            return w_self.num.touint()
+            return self.num.touint()
         except ValueError:
             raise OperationError(space.w_ValueError, space.wrap(
                 "cannot convert negative integer to unsigned int"))
             raise OperationError(space.w_OverflowError, space.wrap(
                 "long int too large to convert to unsigned int"))
 
-    def bigint_w(w_self, space):
-        return w_self.num
+    def bigint_w(self, space):
+        return self.num
 
     def float_w(self, space):
         return self.tofloat(space)
             sys.maxint == 2147483647)
 
 # binary ops
-for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod', 'divmod', 'lshift']:
+for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod',
+               'divmod', 'lshift']:
     exec compile("""
 def %(opname)s_ovr__Int_Int(space, w_int1, w_int2):
     if recover_with_smalllong(space) and %(opname)r != 'truediv':

File pypy/objspace/std/objspace.py

 from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rarithmetic import base_int, widen, is_valid_int
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, import_from_mixin
 from rpython.rlib import jit
 
 # Object imports
 from pypy.objspace.std.stringtype import wrapstr
 from pypy.objspace.std.unicodetype import wrapunicode
 
-class StdObjSpace(ObjSpace, DescrOperation):
+class StdObjSpace(ObjSpace):
     """The standard object space, implementing a general-purpose object
     library in Restricted Python."""
+    import_from_mixin(DescrOperation)
 
     def initialize(self):
         "NOT_RPYTHON: only for initializing the space."
                                  self.wrap("Expected tuple of length 3"))
         return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
 
+    _DescrOperation_is_true = is_true
+    _DescrOperation_getattr = getattr
+
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
         if type(w_obj) is W_BoolObject:
             return w_obj.boolval
-        return DescrOperation.is_true(self, w_obj)
+        return self._DescrOperation_is_true(w_obj)
 
     def getattr(self, w_obj, w_name):
         if not self.config.objspace.std.getattributeshortcut:
-            return DescrOperation.getattr(self, w_obj, w_name)
+            return self._DescrOperation_getattr(w_obj, w_name)
         # an optional shortcut for performance
 
         w_type = self.type(w_obj)

File pypy/objspace/std/stringobject.py

 from pypy.interpreter.buffer import StringBuffer
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std import slicetype
-from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.longobject import W_LongObject
 from pypy.objspace.std.model import W_Object, registerimplementation
 from pypy.objspace.std.multimethod import FailedToImplement
 
 def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end):
     u_self, u_start, u_end = _convert_idx_params(space, w_self, w_start, w_end)
-    return wrapint(space, u_self.count(w_arg._value, u_start, u_end))
+    return space.newint(u_self.count(w_arg._value, u_start, u_end))
 
 def _suffix_to_str(space, w_suffix, funcname):
     try:
 def hash__String(space, w_str):
     s = w_str._value
     x = compute_hash(s)
-    return wrapint(space, x)
+    return space.newint(x)
 
 def lt__String_String(space, w_str1, w_str2):
     s1 = w_str1._value

File pypy/objspace/std/tupleobject.py

 from pypy.interpreter.gateway import (
     WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
 from pypy.objspace.std import slicetype
-from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.util import negate
 
     def descr_len(self, space):
         result = self.length()
-        return wrapint(space, result)
+        return space.newint(result)
 
     def descr_iter(self, space):
         from pypy.objspace.std import iterobject

File pypy/objspace/std/util.py

         tmp = f(self, space, w_other)
         if tmp is space.w_NotImplemented:
             return space.w_NotImplemented
-        elif tmp is space.w_False:
-            return space.w_True
-        else:
-            return space.w_False
+        return space.newbool(tmp is space.w_False)
     _negator.func_name = 'negate-%s' % f.func_name
     return _negator
 

File pypy/tool/gcdump.py

         for obj in self.walk(a):
             self.add_object_summary(obj[2], obj[3])
 
-    def load_typeids(self, filename):
+    def load_typeids(self, filename_or_iter):
         self.typeids = Stat.typeids.copy()
-        for num, line in enumerate(open(filename)):
+        if isinstance(filename_or_iter, str):
+            iter = open(filename_or_iter)
+        else:
+            iter = filename_or_iter
+        for num, line in enumerate(iter):
             if num == 0:
                 continue
+            if not line:
+                continue
             words = line.split()
             if words[0].startswith('member'):
                 del words[0]
         typeid_name = os.path.join(os.path.dirname(sys.argv[1]), 'typeids.txt')
     if os.path.isfile(typeid_name):
         stat.load_typeids(typeid_name)
+    else:
+        import zlib, gc
+        stat.load_typeids(zlib.decompress(gc.get_typeids_z()).split("\n"))
     #
     stat.print_summary()

File pypy/tool/jitlogparser/parser.py

             data = r.data.encode('hex')       # backward compatibility
             dumps[name] = (world.backend_name, r.addr, data)
     loops = []
-    for entry in extract_category(log, 'jit-log-opt'):
+    cat = extract_category(log, 'jit-log-opt')
+    if not cat:
+        extract_category(log, 'jit-log-rewritten')
+    if not cat:
+        extract_category(log, 'jit-log-noopt')        
+    for entry in cat:
         parser = ParserCls(entry, None, {}, 'lltype', None,
                            nonstrict=True)
         loop = parser.parse()

File rpython/annotator/test/test_annrpython.py

         s = a.build_types(f, [])
         assert s.const == 2
 
+    def test_import_from_mixin(self):
+        class M(object):
+            def f(self):
+                return self.a
+        class I(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, i):
+                self.a = i
+        class S(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, s):
+                self.a = s
+        def f(n):
+            return (I(n).f(), S("a" * n).f())
+
+        assert f(3) == (3, "aaa")
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert isinstance(s.items[0], annmodel.SomeInteger)
+        assert isinstance(s.items[1], annmodel.SomeString)
+
     def test___class___attribute(self):
         class Base(object): pass
         class A(Base): pass

File rpython/jit/backend/arm/assembler.py

             self.mc.BL(self.stack_check_slowpath, c=c.HI)      # call if ip > lr
 
     # cpu interface
-    def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
+    def assemble_loop(self, logger, loopname, inputargs, operations, looptoken,
+                      log):
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         looptoken.compiled_loop_token = clt
         clt._debug_nbargs = len(inputargs)
                     'loop.asm')
 
         ops_offset = self.mc.ops_offset
+        if logger is not None:
+            logger.log_loop(inputargs, operations, 0, "rewritten",
+                            name=loopname, ops_offset=ops_offset)
         self.teardown()
 
         debug_start("jit-backend-addr")
             frame_depth = max(frame_depth, target_frame_depth)
         return frame_depth
 
-    def assemble_bridge(self, faildescr, inputargs, operations,
-                                                    original_loop_token, log):
+    def assemble_bridge(self, logger, faildescr, inputargs, operations,
+                        original_loop_token, log):
         if not we_are_translated():
             # Arguments should be unique
             assert len(set(inputargs)) == len(inputargs)
                           frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
         self.fixup_target_tokens(rawstart)
         self.update_frame_depth(frame_depth)
+        if logger:
+            logger.log_bridge(inputargs, operations, "rewritten",
+                              ops_offset=ops_offset)
         self.teardown()
 
         debug_bridge(descr_number, rawstart, codeendpos)

File rpython/jit/backend/arm/opassembler.py

         # Write code equivalent to write_barrier() in the GC: it checks
         # a flag in the object at arglocs[0], and if set, it calls a
         # helper piece of assembler.  The latter saves registers as needed
-        # and call the function jit_remember_young_pointer() from the GC.
+        # and call the function remember_young_pointer() from the GC.
         if we_are_translated():
             cls = self.cpu.gc_ll_descr.has_write_barrier_class()
             assert cls is not None and isinstance(descr, cls)

File rpython/jit/backend/arm/runner.py

     def finish_once(self):
         self.assembler.finish_once()
 
-    def compile_loop(self, inputargs, operations, looptoken,
+    def compile_loop(self, logger, inputargs, operations, looptoken,
                                                     log=True, name=''):
-        return self.assembler.assemble_loop(name, inputargs, operations,
-                                                    looptoken, log=log)
+        return self.assembler.assemble_loop(logger, name, inputargs, operations,
+                                            looptoken, log=log)
 
-    def compile_bridge(self, faildescr, inputargs, operations,
+    def compile_bridge(self, logger, faildescr, inputargs, operations,
                                        original_loop_token, log=True):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
-        return self.assembler.assemble_bridge(faildescr, inputargs, operations,
-                                                original_loop_token, log=log)
+        return self.assembler.assemble_bridge(logger, faildescr, inputargs,
+                                              operations,
+                                              original_loop_token, log=log)
 
     def clear_latest_values(self, count):
         setitem = self.assembler.fail_boxes_ptr.setitem

File rpython/jit/backend/arm/test/test_generated.py

         looptoken = JitCellToken()
         operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
         operations[3].setfailargs([v9, v6, v10, v2, v8, v5, v1, v4])
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 0
         operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
         operations[-1].setfailargs([v7, v1, v2])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 105
         operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6])
 
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
         operations[5].setfailargs([])
         operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == -29
         looptoken = JitCellToken()
         operations[5].setfailargs([])
         operations[-1].setfailargs([v1, v4, v10, v8, v7, v3])
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 1073741824
         operations[9].setfailargs([v10, v13])
         operations[-1].setfailargs([v8, v10, v6, v3, v2, v9])
         args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12]
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
         assert cpu.get_int_value(deadframe, 0) == 12
         operations[8].setfailargs([v5, v9])
         operations[-1].setfailargs([v4, v10, v6, v5, v9, v7])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
         operations[-2].setfailargs([v9, v4, v10, v11, v14])
         operations[-1].setfailargs([v10, v8, v1, v6, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
         operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8])
         operations[-1].setfailargs([v1, v2, v9])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
         operations[2].setfailargs([v10, v3, v6, v11, v9, v2])
         operations[-1].setfailargs([v8, v2, v10, v6, v7, v9, v5, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
         operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9])
         operations[4].setfailargs([v14])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1

File rpython/jit/backend/arm/test/test_regalloc2.py

     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, 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)
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, 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
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, 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
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, inputargs, operations, looptoken)
     args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8]
     deadframe = cpu.execute_token(looptoken, *args)
     assert cpu.get_int_value(deadframe, 0) == 0

File rpython/jit/backend/arm/test/test_runner.py

             ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)),
             ]
         operations[-2].setfailargs(out)
-        cpu.compile_loop(inp, operations, looptoken)
+        cpu.compile_loop(None, inp, operations, looptoken)
         args = [i for i in range(1, 15)]
         deadframe = self.cpu.execute_token(looptoken, *args)
         output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)]
         i1 = int_sub(i0, 1)
         finish(i1)
         ''')
-        self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2)
-        self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3)
-        self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1)
+        self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2)
+        self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3)
+        self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1)
         df = self.cpu.execute_token(lt1, 10)
         assert self.cpu.get_int_value(df, 0) == 7
 
             ops = "".join(ops)
             loop = parse(ops)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
             ARGS = [lltype.Signed] * numargs
             RES = lltype.Signed
             args = [i+1 for i in range(numargs)]
         try:
             self.cpu.assembler.set_debug(True)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
+            self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken)
             self.cpu.execute_token(looptoken, 0)
             # check debugging info
             struct = self.cpu.assembler.loop_run_counters[0]
         faildescr = BasicFailDescr(2)
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
-        info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
         ops2 = """
         [i0, f1]
         i1 = same_as(i0)
         """
         loop2 = parse(ops2, self.cpu, namespace=locals())
         looptoken2 = JitCellToken()
-        info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2)
+        info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2)
 
         deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5))
         res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0))

File rpython/jit/backend/llgraph/runner.py

         self.stats = stats or MiniStats()
         self.vinfo_for_tests = kwds.get('vinfo_for_tests', None)
 
-    def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+    def compile_loop(self, logger, inputargs, operations, looptoken, log=True,
+                     name=''):
         clt = model.CompiledLoopToken(self, looptoken.number)
         looptoken.compiled_loop_token = clt
         lltrace = LLTrace(inputargs, operations)
         clt._llgraph_alltraces = [lltrace]
         self._record_labels(lltrace)
 
-    def compile_bridge(self, faildescr, inputargs, operations,
+    def compile_bridge(self, logger, faildescr, inputargs, operations,
                        original_loop_token, log=True):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
     def execute_force_token(self, _):
         return self
 
-    def execute_cond_call_gc_wb(self, descr, a, b):
+    def execute_cond_call_gc_wb(self, descr, a):
         py.test.skip("cond_call_gc_wb not supported")
 
-    def execute_cond_call_gc_wb_array(self, descr, a, b, c):
+    def execute_cond_call_gc_wb_array(self, descr, a, b):
         py.test.skip("cond_call_gc_wb_array not supported")
 
     def execute_keepalive(self, descr, x):

File rpython/jit/backend/llsupport/gc.py

         """ Allocate a new frame, overwritten by tests
         """
         frame = jitframe.JITFRAME.allocate(frame_info)
-        llop.gc_assume_young_pointers(lltype.Void, frame)
+        llop.gc_writebarrier(lltype.Void, frame)
         return frame
 
 class JitFrameDescrs:
 
     def _check_valid_gc(self):
         # we need the hybrid or minimark GC for rgc._make_sure_does_not_move()
-        # to work.  Additionally, 'hybrid' is missing some stuff like
-        # jit_remember_young_pointer() for now.
+        # to work.  'hybrid' could work but isn't tested with the JIT.
         if self.gcdescr.config.translation.gc not in ('minimark',):
             raise NotImplementedError("--gc=%s not implemented with the JIT" %
                                       (self.gcdescr.config.translation.gc,))

File rpython/jit/backend/llsupport/llmodel.py

                 new_frame.jf_savedata = frame.jf_savedata
                 new_frame.jf_guard_exc = frame.jf_guard_exc
                 # all other fields are empty
-                llop.gc_assume_young_pointers(lltype.Void, new_frame)
+                llop.gc_writebarrier(lltype.Void, new_frame)
                 return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame)
             except Exception, e:
                 print "Unhandled exception", e, "in realloc_frame"

File rpython/jit/backend/llsupport/rewrite.py

      - Add COND_CALLs to the write barrier before SETFIELD_GC and
        SETARRAYITEM_GC operations.
 
-    recent_mallocs contains a dictionary of variable -> None. If a variable
-    is in the dictionary, next setfields can be called without a write barrier,
-    because the variable got allocated after the last potentially collecting
-    resop
+    'write_barrier_applied' contains a dictionary of variable -> None.
+    If a variable is in the dictionary, next setfields can be called without
+    a write barrier.  The idea is that an object that was freshly allocated
+    or already write_barrier'd don't need another write_barrier if there
+    was no potentially collecting resop inbetween.
     """
 
     _previous_size = -1
         self.cpu = cpu
         self.newops = []
         self.known_lengths = {}
-        self.recent_mallocs = {}
+        self.write_barrier_applied = {}
 
     def rewrite(self, operations):
         # we can only remember one malloc since the next malloc can possibly
     def emitting_an_operation_that_can_collect(self):
         # must be called whenever we emit an operation that can collect:
         # forgets the previous MALLOC_NURSERY, if any; and empty the
-        # set 'recent_mallocs', so that future SETFIELDs will generate
+        # set 'write_barrier_applied', so that future SETFIELDs will generate
         # a write barrier as usual.
         self._op_malloc_nursery = None
-        self.recent_mallocs.clear()
+        self.write_barrier_applied.clear()
 
     def _gen_call_malloc_gc(self, args, v_result, descr):
         """Generate a CALL_MALLOC_GC with the given args."""
         self.emitting_an_operation_that_can_collect()
         op = ResOperation(rop.CALL_MALLOC_GC, args, v_result, descr)
         self.newops.append(op)
-        # mark 'v_result' as freshly malloced
-        self.recent_mallocs[v_result] = None
+        # mark 'v_result' as freshly malloced, so not needing a write barrier
+        self.write_barrier_applied[v_result] = None
 
     def gen_malloc_fixedsize(self, size, typeid, v_result):
         """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, ...).
                           [ConstInt(kind), ConstInt(itemsize), v_length],
                           v_result, descr=arraydescr)
         self.newops.append(op)
-        self.recent_mallocs[v_result] = None
+        self.write_barrier_applied[v_result] = None
         return True
 
     def gen_malloc_nursery_varsize_frame(self, sizebox, v_result):
                           v_result)
 
         self.newops.append(op)
-        self.recent_mallocs[v_result] = None
+        self.write_barrier_applied[v_result] = None
 
     def gen_malloc_nursery(self, size, v_result):
         """Try to generate or update a CALL_MALLOC_NURSERY.
         self.newops.append(op)
         self._previous_size = size
         self._v_last_malloced_nursery = v_result
-        self.recent_mallocs[v_result] = None
+        self.write_barrier_applied[v_result] = None
         return True
 
     def gen_initialize_tid(self, v_newgcobj, tid):
 
     def handle_write_barrier_setfield(self, op):
         val = op.getarg(0)
-        # no need for a write barrier in the case of previous malloc
-        if val not in self.recent_mallocs:
+        if val not in self.write_barrier_applied:
             v = op.getarg(1)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
-                self.gen_write_barrier(op.getarg(0), v)
-                op = op.copy_and_change(rop.SETFIELD_RAW)
+                self.gen_write_barrier(val)
+                #op = op.copy_and_change(rop.SETFIELD_RAW)
         self.newops.append(op)
 
     def handle_write_barrier_setinteriorfield(self, op):
         val = op.getarg(0)
-        # no need for a write barrier in the case of previous malloc
-        if val not in self.recent_mallocs:
+        if val not in self.write_barrier_applied:
             v = op.getarg(2)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
-                self.gen_write_barrier(op.getarg(0), v)
-                op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
+                self.gen_write_barrier(val)
+                #op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
         self.newops.append(op)
 
     def handle_write_barrier_setarrayitem(self, op):
         val = op.getarg(0)
-        # no need for a write barrier in the case of previous malloc
-        if val not in self.recent_mallocs:
+        if val not in self.write_barrier_applied:
             v = op.getarg(2)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
-                self.gen_write_barrier_array(op.getarg(0),
-                                             op.getarg(1), v)
-                op = op.copy_and_change(rop.SETARRAYITEM_RAW)
+                self.gen_write_barrier_array(val, op.getarg(1))
+                #op = op.copy_and_change(rop.SETARRAYITEM_RAW)
         self.newops.append(op)
 
-    def gen_write_barrier(self, v_base, v_value):
+    def gen_write_barrier(self, v_base):
         write_barrier_descr = self.gc_ll_descr.write_barrier_descr
-        args = [v_base, v_value]
+        args = [v_base]
         self.newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
                                         descr=write_barrier_descr))
+        self.write_barrier_applied[v_base] = None
 
-    def gen_write_barrier_array(self, v_base, v_index, v_value):
+    def gen_write_barrier_array(self, v_base, v_index):
         write_barrier_descr = self.gc_ll_descr.write_barrier_descr
         if write_barrier_descr.has_write_barrier_from_array(self.cpu):
             # If we know statically the length of 'v', and it is not too
             length = self.known_lengths.get(v_base, LARGE)
             if length >= LARGE:
                 # unknown or too big: produce a write_barrier_from_array
-                args = [v_base, v_index, v_value]
+                args = [v_base, v_index]
                 self.newops.append(
                     ResOperation(rop.COND_CALL_GC_WB_ARRAY, args, None,
                                  descr=write_barrier_descr))
+                # a WB_ARRAY is not enough to prevent any future write
+                # barriers, so don't add to 'write_barrier_applied'!
                 return
         # fall-back case: produce a write_barrier
-        self.gen_write_barrier(v_base, v_value)
+        self.gen_write_barrier(v_base)
 
     def round_up_for_allocation(self, size):
         if not self.gc_ll_descr.round_up:

File rpython/jit/backend/llsupport/test/test_gc.py

         rewriter = gc.GcRewriterAssembler(gc_ll_descr, None)
         newops = rewriter.newops
         v_base = BoxPtr()
-        v_value = BoxPtr()
-        rewriter.gen_write_barrier(v_base, v_value)
+        rewriter.gen_write_barrier(v_base)
         assert llop1.record == []
         assert len(newops) == 1
         assert newops[0].getopnum() == rop.COND_CALL_GC_WB
         assert newops[0].getarg(0) == v_base
-        assert newops[0].getarg(1) == v_value
         assert newops[0].result is None
         wbdescr = newops[0].getdescr()
         assert is_valid_int(wbdescr.jit_wb_if_flag)

File rpython/jit/backend/llsupport/test/test_gc_integration.py

                         'checkdescr': checkdescr,
                         'fielddescr': cpu.fielddescrof(S, 'x')})
         token = JitCellToken()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         p0 = lltype.malloc(S, zero=True)
         p1 = lltype.malloc(S)
         p2 = lltype.malloc(S)
             'calldescr': checkdescr,
         })
         token = JitCellToken()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         S = self.S
         s = lltype.malloc(S)
         cpu.execute_token(token, 1, s)
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(20)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         arg = longlong.getfloatstorage(2.3)
         frame = cpu.execute_token(token, arg)
         ofs = cpu.get_baseofs_of_frame_field()
         cpu.gc_ll_descr.collections = [[0, sizeof.size]]
         cpu.gc_ll_descr.init_nursery(2 * sizeof.size)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = cpu.execute_token(token)
         # now we should be able to track everything from the frame
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame)
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)]
         frame = cpu.execute_token(token, 1, *args)
         frame = rffi.cast(JITFRAMEPTR, frame)
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
                                        cpu.execute_token(token, 1, a))
 
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
                                        cpu.execute_token(token, 1, a))
         assert getmap(frame).count('1') == 4

File rpython/jit/backend/llsupport/test/test_regalloc_integration.py

         loop = self.parse(ops, namespace=namespace)
         self.loop = loop
         looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
         arguments = []
         for arg in args:
             if isinstance(arg, int):
         assert ([box.type for box in bridge.inputargs] ==
                 [box.type for box in guard_op.getfailargs()])
         faildescr = guard_op.getdescr()
-        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
+        self.cpu.compile_bridge(None, faildescr, bridge.inputargs,
+                                bridge.operations,
                                 loop._jitcelltoken)
         return bridge
 
         '''
         self.interpret(ops, [0, 0, 3, 0])
         assert self.getints(3) == [1, -3, 10]
-        
+
     def test_compare_memory_result_survives(self):
         ops = '''
         [i0, i1, i2, i3]
 
 
 class TestRegallocCompOps(BaseTestRegalloc):
-    
+
     def test_cmp_op_0(self):
         ops = '''
         [i0, i3]
 class TestRegAllocCallAndStackDepth(BaseTestRegalloc):
     def setup_class(cls):
         py.test.skip("skip for now, not sure what do we do")
-    
+
     def expected_frame_depth(self, num_call_args, num_pushed_input_args=0):
         # Assumes the arguments are all non-float
         if not self.cpu.IS_64_BIT:
         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)        
+        i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
         guard_false(i5) [i11, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
         '''
         loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9])
 
         ops = '''
         [i2, i0, i1]
-        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)        
+        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
         guard_false(i0, descr=fdescr2) [i3, i0]
         '''
         bridge = self.attach_bridge(ops, loop, -2)
 
         ops = '''
         [i2]
-        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)        
+        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)
         guard_false(i3, descr=fdescr2) [i3]
         '''
         bridge = self.attach_bridge(ops, loop, -2)

File rpython/jit/backend/llsupport/test/test_rewrite.py

             jump()
         """, """
             [p1, p2]
-            cond_call_gc_wb(p1, p2, descr=wbdescr)
-            setfield_raw(p1, p2, descr=tzdescr)
+            cond_call_gc_wb(p1, descr=wbdescr)
+            setfield_gc(p1, p2, descr=tzdescr)
             jump()
         """)
 
             jump()
         """, """
             [p1, i2, p3]
-            cond_call_gc_wb(p1, p3, descr=wbdescr)
-            setarrayitem_raw(p1, i2, p3, descr=cdescr)
+            cond_call_gc_wb(p1, descr=wbdescr)
+            setarrayitem_gc(p1, i2, p3, descr=cdescr)
             jump()
         """)
 
             setfield_gc(p1, 8111, descr=tiddescr)
             setfield_gc(p1, 129, descr=clendescr)
             call(123456)
-            cond_call_gc_wb(p1, p3, descr=wbdescr)
-            setarrayitem_raw(p1, i2, p3, descr=cdescr)
+            cond_call_gc_wb(p1, descr=wbdescr)
+            setarrayitem_gc(p1, i2, p3, descr=cdescr)
             jump()
         """)
 
             setfield_gc(p1, 8111, descr=tiddescr)
             setfield_gc(p1, 130, descr=clendescr)
             call(123456)
-            cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
-            setarrayitem_raw(p1, i2, p3, descr=cdescr)
+            cond_call_gc_wb_array(p1, i2, descr=wbdescr)
+            setarrayitem_gc(p1, i2, p3, descr=cdescr)
             jump()
         """)
 
             jump()
         """, """
             [p1, i2, p3]
-            cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
-            setarrayitem_raw(p1, i2, p3, descr=cdescr)
+            cond_call_gc_wb_array(p1, i2, descr=wbdescr)
+            setarrayitem_gc(p1, i2, p3, descr=cdescr)
             jump()
         """)
 
             setfield_gc(p1, 8111, descr=tiddescr)
             setfield_gc(p1, 5, descr=clendescr)
             label(p1, i2, p3)
-            cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
-            setarrayitem_raw(p1, i2, p3, descr=cdescr)
+            cond_call_gc_wb_array(p1, i2, descr=wbdescr)
+            setarrayitem_gc(p1, i2, p3, descr=cdescr)
             jump()
         """)
 
             jump(p1, p2)
         """, """
             [p1, p2]
-            cond_call_gc_wb(p1, p2, descr=wbdescr)
-            setinteriorfield_raw(p1, 0, p2, descr=interiorzdescr)
+            cond_call_gc_wb(p1, descr=wbdescr)
+            setinteriorfield_gc(p1, 0, p2, descr=interiorzdescr)
             jump(p1, p2)
         """, interiorzdescr=interiorzdescr)
 
             p1 = call_malloc_nursery_varsize(1, 1, i0, \
                                 descr=strdescr)
             setfield_gc(p1, i0, descr=strlendescr)
-            cond_call_gc_wb(p0, p1, descr=wbdescr)
-            setfield_raw(p0, p1, descr=tzdescr)
+            cond_call_gc_wb(p0, descr=wbdescr)
+            setfield_gc(p0, p1, descr=tzdescr)
             jump()
         """)
 
             p0 = call_malloc_nursery(%(tdescr.size)d)
             setfield_gc(p0, 5678, descr=tiddescr)
             label(p0, p1)
-            cond_call_gc_wb(p0, p1, descr=wbdescr)
-            setfield_raw(p0, p1, descr=tzdescr)
+            cond_call_gc_wb(p0, descr=wbdescr)
+            setfield_gc(p0, p1, descr=tzdescr)
             jump()
         """)
 
+    def test_multiple_writes(self):
+        self.check_rewrite("""
+            [p0, p1, p2]
+            setfield_gc(p0, p1, descr=tzdescr)
+            setfield_gc(p0, p2, descr=tzdescr)
+            jump(p1, p2, p0)
+        """, """
+            [p0, p1, p2]
+            cond_call_gc_wb(p0, descr=wbdescr)
+            setfield_gc(p0, p1, descr=tzdescr)
+            setfield_gc(p0, p2, descr=tzdescr)
+            jump(p1, p2, p0)
+        """)
+
     def test_rewrite_call_assembler(self):
         self.check_rewrite("""
         [i0, f0]

File rpython/jit/backend/llsupport/test/test_runner.py