Author: Richard Plangger <planri...@gmail.com>
Branch: memoryview-attributes
Changeset: r86455:4ec423c97a35
Date: 2016-08-24 09:10 +0200
http://bitbucket.org/pypy/pypy/changeset/4ec423c97a35/

Log:    merge default

diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py
--- a/lib_pypy/cffi/recompiler.py
+++ b/lib_pypy/cffi/recompiler.py
@@ -515,7 +515,7 @@
                                                     tovar, errcode)
             return
         #
-        elif isinstance(tp, (model.StructOrUnion, model.EnumType)):
+        elif isinstance(tp, model.StructOrUnionOrEnum):
             # a struct (not a struct pointer) as a function argument
             self._prnt('  if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)'
                       % (tovar, self._gettypenum(tp), fromvar))
@@ -572,7 +572,7 @@
         elif isinstance(tp, model.ArrayType):
             return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
                 var, self._gettypenum(model.PointerType(tp.item)))
-        elif isinstance(tp, model.StructType):
+        elif isinstance(tp, model.StructOrUnion):
             if tp.fldnames is None:
                 raise TypeError("'%s' is used as %s, but is opaque" % (
                     tp._get_c_name(), context))
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -308,7 +308,7 @@
         elif isinstance(tp, model.ArrayType):
             return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
                 var, self._gettypenum(model.PointerType(tp.item)))
-        elif isinstance(tp, model.StructType):
+        elif isinstance(tp, model.StructOrUnion):
             if tp.fldnames is None:
                 raise TypeError("'%s' is used as %s, but is opaque" % (
                     tp._get_c_name(), context))
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
@@ -144,3 +144,9 @@
 ``type.__dict__`` now returns a ``dict_proxy`` object, like on CPython.
 Previously it returned what looked like a regular dict object (but it
 was already read-only).
+
+
+.. branch: const-fold-we-are-jitted
+
+Reduce the size of the generated C code by constant-folding ``we_are_jitted``
+in non-jitcode.
diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -590,6 +590,8 @@
                                                     "decode", w_fs_encoding)
                 except OperationError as e:
                     # fall back to the original byte string
+                    if e.async(space):
+                        raise
                     result_w[i] = w_bytes
             return space.newlist(result_w)
         else:
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py 
b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
@@ -423,7 +423,7 @@
         guard_false(i114, descr=...)
         --TICK--
         i123 = arraylen_gc(p67, descr=<ArrayP .>)
-        i119 = call_i(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, 
descr=<Calli . i EF=5 OS=110>)
+        i119 = call_i(ConstClass(_ll_1_raw_malloc_varsize_zero__Signed), 6, 
descr=<Calli . i EF=5 OS=110>)
         check_memory_error(i119)
         raw_store(i119, 0, i160, descr=<ArrayS 2>)
         raw_store(i119, 2, i160, descr=<ArrayS 2>)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -1963,3 +1963,21 @@
                        ffi, "test_function_returns_opaque", "?")
     assert str(e.value) == ("function foo: 'struct a' is used as result type,"
                             " but is opaque")
+
+def test_function_returns_union():
+    ffi = FFI()
+    ffi.cdef("union u1 { int a, b; }; union u1 f1(int);")
+    lib = verify(ffi, "test_function_returns_union", """
+        union u1 { int a, b; };
+        static union u1 f1(int x) { union u1 u; u.b = x; return u; }
+    """)
+    assert lib.f1(51).a == 51
+
+def test_function_returns_partial_struct():
+    ffi = FFI()
+    ffi.cdef("struct a { int a; ...; }; struct a f1(int);")
+    lib = verify(ffi, "test_function_returns_partial_struct", """
+        struct a { int b, a, c; };
+        static struct a f1(int x) { struct a s = {0}; s.a = x; return s; }
+    """)
+    assert lib.f1(52).a == 52
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -466,8 +466,6 @@
     def descr_getbuffer(self, space, w_flags):
         #from pypy.objspace.std.bufferobject import W_Buffer
         #return W_Buffer(StringBuffer(self._value))
-        # XXX handle flags, figure out why returning a W_Buffer
-        #     makes upstream ctypes tests fail
         return self
 
     charbuf_w = str_w
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -362,11 +362,10 @@
         return _new_int(space, w_inttype, w_x, w_base)
 
     def descr_hash(self, space):
-        # unlike CPython, we don't special-case the value -1 in most of
-        # our hash functions, so there is not much sense special-casing
-        # it here either.  Make sure this is consistent with the hash of
-        # floats and longs.
-        return self.int(space)
+        # For compatibility with CPython, we special-case -1
+        h = self.intval
+        h -= (h == -1)  # No explicit condition, to avoid JIT bridges
+        return wrapint(space, h)
 
     def _int(self, space):
         return self.int(space)
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -130,7 +130,12 @@
 
     descr_repr = _make_descr_unaryop('repr')
     descr_str = _make_descr_unaryop('str')
-    descr_hash = _make_descr_unaryop('hash')
+
+    def descr_hash(self, space):
+        h = self.asbigint().hash()
+        h -= (h == -1)
+        return space.newint(h)
+
     descr_oct = _make_descr_unaryop('oct')
     descr_hex = _make_descr_unaryop('hex')
 
@@ -387,12 +392,12 @@
     def _make_generic_descr_binop(opname):
         if opname not in COMMUTATIVE_OPS:
             raise Exception("Not supported")
-            
+
         methname = opname + '_' if opname in ('and', 'or') else opname
         descr_rname = 'descr_r' + opname
         op = getattr(rbigint, methname)
         intop = getattr(rbigint, "int_" + methname)
-        
+
         @func_renamer('descr_' + opname)
         def descr_binop(self, space, w_other):
             if isinstance(w_other, W_AbstractIntObject):
@@ -412,7 +417,7 @@
             return W_LongObject(op(w_other.asbigint(), self.num))
 
         return descr_binop, descr_rbinop
-        
+
     descr_add, descr_radd = _make_generic_descr_binop('add')
     descr_sub, descr_rsub = _make_generic_descr_binop_noncommutative('sub')
     descr_mul, descr_rmul = _make_generic_descr_binop('mul')
@@ -454,12 +459,12 @@
         except OverflowError:   # b too big
             raise oefmt(space.w_OverflowError, "shift count too large")
         return W_LongObject(self.num.lshift(shift))
-        
+
     def _int_lshift(self, space, w_other):
         if w_other < 0:
             raise oefmt(space.w_ValueError, "negative shift count")
         return W_LongObject(self.num.lshift(w_other))
-        
+
     descr_lshift, descr_rlshift = _make_descr_binop(_lshift, _int_lshift)
 
     def _rshift(self, space, w_other):
@@ -470,7 +475,7 @@
         except OverflowError:   # b too big # XXX maybe just return 0L instead?
             raise oefmt(space.w_OverflowError, "shift count too large")
         return newlong(space, self.num.rshift(shift))
-        
+
     def _int_rshift(self, space, w_other):
         if w_other < 0:
             raise oefmt(space.w_ValueError, "negative shift count")
@@ -485,7 +490,7 @@
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
         return newlong(space, z)
-        
+
     def _floordiv(self, space, w_other):
         try:
             z = self.num.floordiv(w_other.asbigint())
@@ -505,7 +510,7 @@
             raise oefmt(space.w_ZeroDivisionError,
                         "long division or modulo by zero")
         return newlong(space, z)
-        
+
     def _int_mod(self, space, w_other):
         try:
             z = self.num.int_mod(w_other)
diff --git a/pypy/objspace/std/test/test_intobject.py 
b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -295,7 +295,11 @@
         assert self.space.unwrap(result) == hex(x)
 
 
-class AppTestInt:
+class AppTestInt(object):
+    def test_hash(self):
+        assert hash(-1) == (-1).__hash__() == -2
+        assert hash(-2) == (-2).__hash__() == -2
+
     def test_conjugate(self):
         assert (1).conjugate() == 1
         assert (-1).conjugate() == -1
@@ -454,11 +458,11 @@
                 return None
         inst = a()
         raises(TypeError, int, inst)
-        assert inst.ar == True 
+        assert inst.ar == True
 
         class b(object):
-            pass 
-        raises((AttributeError,TypeError), int, b()) 
+            pass
+        raises((AttributeError,TypeError), int, b())
 
     def test_special_long(self):
         class a(object):
diff --git a/pypy/objspace/std/test/test_longobject.py 
b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -228,7 +228,7 @@
     def test_hash(self):
         # ints have the same hash as equal longs
         for i in range(-4, 14):
-            assert hash(i) == hash(long(i))
+            assert hash(i) == hash(long(i)) == long(i).__hash__()
         # might check too much -- it's ok to change the hashing algorithm
         assert hash(123456789L) == 123456789
         assert hash(1234567890123456789L) in (
diff --git a/rpython/config/translationoption.py 
b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -261,6 +261,9 @@
                    "stack based virtual machines (only for backends that 
support it)",
                    default=True),
         BoolOption("storesink", "Perform store sinking", default=True),
+        BoolOption("replace_we_are_jitted",
+                   "Replace we_are_jitted() calls by False",
+                   default=False, cmdline=None),
         BoolOption("none",
                    "Do not run any backend optimizations",
                    requires=[('translation.backendopt.inline', False),
diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -833,9 +833,6 @@
         result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
         return heaptracker.adr2int(result_adr)
 
-    def bh_new_raw_buffer(self, size):
-        return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
-
     # vector operations
     vector_arith_code = """
     def bh_vec_{0}_{1}(self, vx, vy, count):
diff --git a/rpython/jit/backend/llsupport/llmodel.py 
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -757,9 +757,6 @@
             self.write_int_at_mem(res, self.vtable_offset, WORD, 
sizedescr.get_vtable())
         return res
 
-    def bh_new_raw_buffer(self, size):
-        return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
-
     def bh_classof(self, struct):
         struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
         result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -229,8 +229,6 @@
         raise NotImplementedError
     def bh_newunicode(self, length):
         raise NotImplementedError
-    def bh_new_raw_buffer(self, size):
-        raise NotImplementedError
 
     def bh_arraylen_gc(self, array, arraydescr):
         raise NotImplementedError
diff --git a/rpython/jit/codewriter/support.py 
b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -582,6 +582,14 @@
                 return lltype.malloc(ARRAY, n, flavor='raw', zero=zero,
                                      add_memory_pressure=add_memory_pressure,
                                      track_allocation=track_allocation)
+            name = '_ll_1_raw_malloc_varsize'
+            if zero:
+                name += '_zero'
+            if add_memory_pressure:
+                name += '_mpressure'
+            if not track_allocation:
+                name += '_notrack'
+            _ll_1_raw_malloc_varsize.func_name = name
             return _ll_1_raw_malloc_varsize
         return build_ll_1_raw_malloc_varsize
 
@@ -610,6 +618,14 @@
                 return lltype.malloc(STRUCT, flavor='raw', zero=zero,
                                      add_memory_pressure=add_memory_pressure,
                                      track_allocation=track_allocation)
+            name = '_ll_0_raw_malloc_fixedsize'
+            if zero:
+                name += '_zero'
+            if add_memory_pressure:
+                name += '_mpressure'
+            if not track_allocation:
+                name += '_notrack'
+            _ll_0_raw_malloc_fixedsize.func_name = name
             return _ll_0_raw_malloc_fixedsize
         return build_ll_0_raw_malloc_fixedsize
 
diff --git a/rpython/jit/metainterp/optimizeopt/info.py 
b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -367,8 +367,9 @@
 
 class RawBufferPtrInfo(AbstractRawPtrInfo):
     buffer = None
-    
-    def __init__(self, cpu, size=-1):
+
+    def __init__(self, cpu, func, size=-1):
+        self.func = func
         self.size = size
         if self.size != -1:
             self.buffer = RawBuffer(cpu, None)
@@ -425,7 +426,8 @@
     @specialize.argtype(1)
     def visitor_dispatch_virtual_type(self, visitor):
         buffer = self._get_buffer()
-        return visitor.visit_vrawbuffer(self.size,
+        return visitor.visit_vrawbuffer(self.func,
+                                        self.size,
                                         buffer.offsets[:],
                                         buffer.descrs[:])
 
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1770,7 +1770,7 @@
     def test_virtual_raw_malloc_basic(self):
         ops = """
         [i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)   # 12345 = malloc func
         guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr)
@@ -1787,7 +1787,7 @@
         ops = """
         [i1]
         i5 = int_mul(10, 1)
-        i2 = call_i('malloc', i5, descr=raw_malloc_descr)
+        i2 = call_i(12345, i5, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr)
@@ -1803,7 +1803,7 @@
     def test_virtual_raw_malloc_force(self):
         ops = """
         [i1]
-        i2 = call_i('malloc', 20, descr=raw_malloc_descr)
+        i2 = call_i(12345, 20, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr_char)
         setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
@@ -1817,7 +1817,7 @@
         expected = """
         [i1]
         label(i1)
-        i2 = call_i('malloc', 20, descr=raw_malloc_descr)
+        i2 = call_i(12345, 20, descr=raw_malloc_descr)
         check_memory_error(i2)
         raw_store(i2, 0, i1, descr=rawarraydescr_char)
         raw_store(i2, 1, 123, descr=rawarraydescr_char)
@@ -1832,7 +1832,7 @@
     def test_virtual_raw_malloc_invalid_write_force(self):
         ops = """
         [i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         label(i1) # we expect the buffer to be forced *after* the label
@@ -1843,7 +1843,7 @@
         expected = """
         [i1]
         label(i1)
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i2)
         raw_store(i2, 0, i1, descr=rawarraydescr)
         setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
@@ -1855,7 +1855,7 @@
     def test_virtual_raw_malloc_invalid_read_force(self):
         ops = """
         [i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         label(i1) # we expect the buffer to be forced *after* the label
@@ -1866,7 +1866,7 @@
         expected = """
         [i1]
         label(i1)
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i2)
         raw_store(i2, 0, i1, descr=rawarraydescr)
         i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr_char)
@@ -1878,7 +1878,7 @@
     def test_virtual_raw_slice(self):
         ops = """
         [i0, i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
         i3 = int_add(i2, 1) # get a slice of the original buffer
@@ -1898,7 +1898,7 @@
     def test_virtual_raw_slice_of_a_raw_slice(self):
         ops = """
         [i0, i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         i3 = int_add(i2, 1) # get a slice of the original buffer
         i4 = int_add(i3, 1) # get a slice of a slice
@@ -1916,7 +1916,7 @@
     def test_virtual_raw_slice_force(self):
         ops = """
         [i0, i1]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
         i3 = int_add(i2, 1) # get a slice of the original buffer
@@ -1929,7 +1929,7 @@
         [i0, i1]
         label(i0, i1)
         # these ops are generated by VirtualRawBufferValue._really_force
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i2)
         raw_store(i2, 0, 42, descr=rawarraydescr_char)
         raw_store(i2, 5, 4242, descr=rawarraydescr_char)
@@ -1946,7 +1946,7 @@
         i1 = getarrayitem_raw_i(i0, 0, descr=rawarraydescr)
         i2 = int_add(i1, 1)
         call_n('free', i0, descr=raw_free_descr)
-        i3 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i3 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i3, 0, i2, descr=rawarraydescr)
         label(i2)
@@ -1958,7 +1958,7 @@
         i2 = int_add(i1, 1)
         call_n('free', i0, descr=raw_free_descr)
         label(i2)
-        i3 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i3 = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i3)
         raw_store(i3, 0, i2, descr=rawarraydescr)
         jump(i3)
@@ -1968,7 +1968,7 @@
     def test_virtual_raw_store_raw_load(self):
         ops = """
         [i1]
-        i0 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i0 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         raw_store(i0, 0, i1, descr=rawarraydescr)
         i2 = raw_load_i(i0, 0, descr=rawarraydescr)
@@ -1986,7 +1986,7 @@
     def test_virtual_raw_store_getarrayitem_raw(self):
         ops = """
         [f1]
-        i0 = call_i('malloc', 16, descr=raw_malloc_descr)
+        i0 = call_i(12345, 16, descr=raw_malloc_descr)
         guard_no_exception() []
         raw_store(i0, 8, f1, descr=rawarraydescr_float)
         f2 = getarrayitem_raw_f(i0, 1, descr=rawarraydescr_float)
@@ -2004,7 +2004,7 @@
     def test_virtual_setarrayitem_raw_raw_load(self):
         ops = """
         [f1]
-        i0 = call_i('malloc', 16, descr=raw_malloc_descr)
+        i0 = call_i(12345, 16, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i0, 1, f1, descr=rawarraydescr_float)
         f2 = raw_load_f(i0, 8, descr=rawarraydescr_float)
@@ -2022,7 +2022,7 @@
     def test_virtual_raw_buffer_forced_but_slice_not_forced(self):
         ops = """
         [f1]
-        i0 = call_i('malloc', 16, descr=raw_malloc_descr)
+        i0 = call_i(12345, 16, descr=raw_malloc_descr)
         guard_no_exception() []
         i1 = int_add(i0, 8)
         escape_n(i0)
@@ -2031,7 +2031,7 @@
         """
         expected = """
         [f1]
-        i0 = call_i('malloc', 16, descr=raw_malloc_descr)
+        i0 = call_i(12345, 16, descr=raw_malloc_descr)
         check_memory_error(i0)
         escape_n(i0)
         i1 = int_add(i0, 8)
@@ -8886,7 +8886,7 @@
     def test_resume_forced_raw_ptr(self):
         ops = """
         [i0]
-        i = call_i('malloc', 10, descr=raw_malloc_descr)
+        i = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         is = int_add(i, 8)
         escape_n(i)
@@ -8898,7 +8898,7 @@
         """
         expected = """
         [i0]
-        i = call_i('malloc', 10, descr=raw_malloc_descr)
+        i = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i)
         escape_n(i)
         i1 = int_add(i0, 1)
@@ -8966,7 +8966,7 @@
     def test_pending_setfield_delayed_malloc(self):
         ops = """
         [i0, p0]
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         setarrayitem_raw(i2, 0, 13, descr=rawarraydescr)
         setfield_gc(p0, i2, descr=valuedescr)
@@ -8988,14 +8988,14 @@
     def test_raw_buffer_ptr_info_intbounds_bug(self):
         ops = """
         []
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         guard_no_exception() []
         guard_value(i2, 12345) []
         jump()
         """
         expected = """
         []
-        i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+        i2 = call_i(12345, 10, descr=raw_malloc_descr)
         check_memory_error(i2)
         guard_value(i2, 12345) []
         jump()
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py 
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -45,7 +45,8 @@
         return opinfo
 
     def make_virtual_raw_memory(self, size, source_op):
-        opinfo = info.RawBufferPtrInfo(self.optimizer.cpu, size)
+        func = source_op.getarg(0).getint()
+        opinfo = info.RawBufferPtrInfo(self.optimizer.cpu, func, size)
         newop = self.replace_op_with(source_op, source_op.getopnum(),
                                      args=[source_op.getarg(0), 
ConstInt(size)])
         newop.set_forwarded(opinfo)
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -364,8 +364,8 @@
     def visit_varraystruct(self, arraydescr, size, fielddescrs):
         return VArrayStructInfo(arraydescr, size, fielddescrs)
 
-    def visit_vrawbuffer(self, size, offsets, descrs):
-        return VRawBufferInfo(size, offsets, descrs)
+    def visit_vrawbuffer(self, func, size, offsets, descrs):
+        return VRawBufferInfo(func, size, offsets, descrs)
 
     def visit_vrawslice(self, offset):
         return VRawSliceInfo(offset)
@@ -703,7 +703,8 @@
 
 class VRawBufferInfo(VAbstractRawInfo):
 
-    def __init__(self, size, offsets, descrs):
+    def __init__(self, func, size, offsets, descrs):
+        self.func = func
         self.size = size
         self.offsets = offsets
         self.descrs = descrs
@@ -711,7 +712,7 @@
     @specialize.argtype(1)
     def allocate_int(self, decoder, index):
         length = len(self.fieldnums)
-        buffer = decoder.allocate_raw_buffer(self.size)
+        buffer = decoder.allocate_raw_buffer(self.func, self.size)
         decoder.virtuals_cache.set_int(index, buffer)
         for i in range(len(self.offsets)):
             offset = self.offsets[i]
@@ -1130,9 +1131,13 @@
                                                            lengthbox)
         return self.metainterp.execute_new_array(arraydescr, lengthbox)
 
-    def allocate_raw_buffer(self, size):
+    def allocate_raw_buffer(self, func, size):
         cic = self.metainterp.staticdata.callinfocollection
-        calldescr, func = 
cic.callinfo_for_oopspec(EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR)
+        calldescr, _ = 
cic.callinfo_for_oopspec(EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR)
+        # Can't use 'func' from callinfo_for_oopspec(), because we have
+        # several variants (zero/non-zero, memory-pressure or not, etc.)
+        # and we have to pick the correct one here; that's why we save
+        # it in the VRawBufferInfo.
         return self.metainterp.execute_and_record_varargs(
             rop.CALL_I, [ConstInt(func), ConstInt(size)], calldescr)
 
@@ -1461,10 +1466,11 @@
     def allocate_string(self, length):
         return self.cpu.bh_newstr(length)
 
-    def allocate_raw_buffer(self, size):
-        buffer = self.cpu.bh_new_raw_buffer(size)
-        adr = llmemory.cast_ptr_to_adr(buffer)
-        return llmemory.cast_adr_to_int(adr, "symbolic")
+    def allocate_raw_buffer(self, func, size):
+        from rpython.jit.codewriter import heaptracker
+        cic = self.callinfocollection
+        calldescr, _ = 
cic.callinfo_for_oopspec(EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR)
+        return self.cpu.bh_call_i(func, [size], None, None, calldescr)
 
     def string_setitem(self, str, index, charnum):
         char = self.decode_int(charnum)
diff --git a/rpython/jit/metainterp/walkvirtual.py 
b/rpython/jit/metainterp/walkvirtual.py
--- a/rpython/jit/metainterp/walkvirtual.py
+++ b/rpython/jit/metainterp/walkvirtual.py
@@ -17,7 +17,7 @@
     def visit_varraystruct(self, arraydescr, fielddescrs):
         raise NotImplementedError("abstract base class")
 
-    def visit_vrawbuffer(self, size, offsets, descrs):
+    def visit_vrawbuffer(self, func, size, offsets, descrs):
         raise NotImplementedError("abstract base class")
 
     def visit_vrawslice(self, offset):
diff --git a/rpython/jit/metainterp/warmspot.py 
b/rpython/jit/metainterp/warmspot.py
--- a/rpython/jit/metainterp/warmspot.py
+++ b/rpython/jit/metainterp/warmspot.py
@@ -452,7 +452,8 @@
                               merge_if_blocks=True,
                               constfold=True,
                               remove_asserts=True,
-                              really_remove_asserts=True)
+                              really_remove_asserts=True,
+                              replace_we_are_jitted=False)
 
     def prejit_optimizations_minimal_inline(self, policy, graphs):
         from rpython.translator.backendopt.inline import auto_inline_graphs
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -799,8 +799,8 @@
                            rffi.cast(size_t, map_size),
                            rffi.cast(rffi.INT, use_flag))
     else:
-        def madvice_free(addr, map_size):
-            "No madvice() on this platform"
+        def madvise_free(addr, map_size):
+            "No madvise() on this platform"
 
 elif _MS_WINDOWS:
     def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -250,6 +250,7 @@
     OFF_T_SIZE = rffi_platform.SizeOf('off_t')
 
     HAVE_UTIMES = rffi_platform.Has('utimes')
+    HAVE_D_TYPE = rffi_platform.Has('DT_UNKNOWN')
     UTIMBUF = rffi_platform.Struct('struct %sutimbuf' % UNDERSCORE_ON_WIN32,
                                    [('actime', rffi.INT),
                                     ('modtime', rffi.INT)])
@@ -603,23 +604,34 @@
     class CConfig:
         _compilation_info_ = eci
         DIRENT = rffi_platform.Struct('struct dirent',
-            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))])
+            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))]
+            + [('d_type', rffi.INT)] if HAVE_D_TYPE else [])
+        if HAVE_D_TYPE:
+            DT_UNKNOWN = rffi_platform.ConstantInteger('DT_UNKNOWN')
+            DT_REG     = rffi_platform.ConstantInteger('DT_REG')
+            DT_DIR     = rffi_platform.ConstantInteger('DT_DIR')
+            DT_LNK     = rffi_platform.ConstantInteger('DT_LNK')
 
     DIRP = rffi.COpaquePtr('DIR')
-    config = rffi_platform.configure(CConfig)
-    DIRENT = config['DIRENT']
+    dirent_config = rffi_platform.configure(CConfig)
+    DIRENT = dirent_config['DIRENT']
     DIRENTP = lltype.Ptr(DIRENT)
     c_opendir = external('opendir',
         [rffi.CCHARP], DIRP, save_err=rffi.RFFI_SAVE_ERRNO)
     c_fdopendir = external('fdopendir',
         [rffi.INT], DIRP, save_err=rffi.RFFI_SAVE_ERRNO)
+    c_rewinddir = external('rewinddir',
+        [DIRP], lltype.Void, releasegil=False)
     # XXX macro=True is hack to make sure we get the correct kind of
     # dirent struct (which depends on defines)
     c_readdir = external('readdir', [DIRP], DIRENTP,
                          macro=True, save_err=rffi.RFFI_FULL_ERRNO_ZERO)
-    c_closedir = external('closedir', [DIRP], rffi.INT)
+    c_closedir = external('closedir', [DIRP], rffi.INT, releasegil=False)
+    c_dirfd = external('dirfd', [DIRP], rffi.INT, releasegil=False)
+else:
+    dirent_config = {}
 
-def _listdir(dirp):
+def _listdir(dirp, rewind=False):
     result = []
     while True:
         direntp = c_readdir(dirp)
@@ -630,6 +642,8 @@
         name = rffi.charp2str(namep)
         if name != '.' and name != '..':
             result.append(name)
+    if rewind:
+        c_rewinddir(dirp)
     c_closedir(dirp)
     if error:
         raise OSError(error, "readdir failed")
@@ -640,12 +654,16 @@
     Like listdir(), except that the directory is specified as an open
     file descriptor.
 
-    Note: fdlistdir() closes the file descriptor.
+    Note: fdlistdir() closes the file descriptor.  To emulate the
+    Python 3.x 'os.opendir(dirfd)', you must first duplicate the
+    file descriptor.
     """
     dirp = c_fdopendir(dirfd)
     if not dirp:
-        raise OSError(get_saved_errno(), "opendir failed")
-    return _listdir(dirp)
+        error = get_saved_errno()
+        c_close(dirfd)
+        raise OSError(error, "opendir failed")
+    return _listdir(dirp, rewind=True)
 
 @replace_os_function('listdir')
 @specialize.argtype(0)
@@ -1782,12 +1800,7 @@
 # Support for f... and ...at families of POSIX functions
 
 class CConfig:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=['sys/stat.h',
-                  'sys/time.h',
-                  'unistd.h',
-                  'fcntl.h'],
-    )
+    _compilation_info_ = eci
     for _name in """faccessat fchdir fchmod fchmodat fchown fchownat fexecve
             fdopendir fpathconf fstat fstatat fstatvfs ftruncate
             futimens futimes futimesat linkat chflags lchflags lchmod lchown
diff --git a/rpython/rlib/rposix_scandir.py b/rpython/rlib/rposix_scandir.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rposix_scandir.py
@@ -0,0 +1,52 @@
+from rpython.rlib import rposix
+from rpython.rlib.objectmodel import specialize
+from rpython.rtyper.lltypesystem import lltype, rffi
+
+
+@specialize.argtype(0)
+def opendir(path):
+    path = rposix._as_bytes0(path)
+    return opendir_bytes(path)
+
+def opendir_bytes(path):
+    dirp = rposix.c_opendir(path)
+    if not dirp:
+        raise OSError(rposix.get_saved_errno(), "opendir failed")
+    return dirp
+
+def closedir(dirp):
+    rposix.c_closedir(dirp)
+
+NULL_DIRP = lltype.nullptr(rposix.DIRP.TO)
+
+def nextentry(dirp):
+    """Read the next entry and returns an opaque object.
+    Use the methods has_xxx() and get_xxx() to read from that
+    opaque object.  The opaque object is valid until the next
+    time nextentry() or closedir() is called.  This may raise
+    OSError, or return a NULL pointer when exhausted.  Note
+    that this doesn't filter out the "." and ".." entries.
+    """
+    direntp = rposix.c_readdir(dirp)
+    if direntp:
+        error = rposix.get_saved_errno()
+        if error:
+            raise OSError(error, "readdir failed")
+    return direntp
+
+def has_name_bytes(direntp):
+    return True
+
+def get_name_bytes(direntp):
+    namep = rffi.cast(rffi.CCHARP, direntp.c_d_name)
+    return rffi.charp2str(namep)
+
+DT_UNKNOWN = rposix.dirent_config.get('DT_UNKNOWN', 0)
+DT_REG = rposix.dirent_config.get('DT_REG', 255)
+DT_DIR = rposix.dirent_config.get('DT_DIR', 255)
+DT_LNK = rposix.dirent_config.get('DT_LNK', 255)
+
+def get_known_type(direntp):
+    if rposix.HAVE_D_TYPE:
+        return rffi.getintfield(direntp, 'c_d_type')
+    return DT_UNKNOWN
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -90,6 +90,9 @@
         CodeClass._vmprof_unique_id = 0     # default value: "unknown"
         immut = CodeClass.__dict__.get('_immutable_fields_', [])
         CodeClass._immutable_fields_ = list(immut) + ['_vmprof_unique_id']
+        attrs = CodeClass.__dict__.get('_attrs_', None)
+        if attrs is not None:
+            CodeClass._attrs_ = list(attrs) + ['_vmprof_unique_id']
         self._code_classes.add(CodeClass)
         #
         class WeakCodeObjectList(RWeakListMixin):
@@ -189,7 +192,7 @@
 
         def decorated_function(*args):
             unique_id = get_code_fn(*args)._vmprof_unique_id
-            unique_id = rffi.cast(lltype.Signed, unique_id) 
+            unique_id = rffi.cast(lltype.Signed, unique_id)
             # ^^^ removes the "known non-negative" hint for annotation
             if not jit.we_are_jitted():
                 x = enter_code(unique_id)
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -552,6 +552,14 @@
     # Note: fdlistdir() always closes dirfd
     assert result == ['file']
 
+@rposix_requires('fdlistdir')
+def test_fdlistdir_rewinddir(tmpdir):
+    tmpdir.join('file').write('text')
+    dirfd = os.open(str(tmpdir), os.O_RDONLY)
+    result1 = rposix.fdlistdir(os.dup(dirfd))
+    result2 = rposix.fdlistdir(dirfd)
+    assert result1 == result2 == ['file']
+
 @rposix_requires('symlinkat')
 def test_symlinkat(tmpdir):
     tmpdir.join('file').write('text')
diff --git a/rpython/rlib/test/test_rposix_scandir.py 
b/rpython/rlib/test/test_rposix_scandir.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/test/test_rposix_scandir.py
@@ -0,0 +1,21 @@
+import sys, os
+import py
+from rpython.rlib import rposix_scandir
+
+
+class TestScanDir(object):
+
+    @py.test.mark.skipif("sys.platform == 'win32'")   # XXX
+    def test_name_bytes(self):
+        scan = rposix_scandir.opendir('/')
+        found = []
+        while True:
+            p = rposix_scandir.nextentry(scan)
+            if not p:
+                break
+            assert rposix_scandir.has_name_bytes(p)
+            found.append(rposix_scandir.get_name_bytes(p))
+        rposix_scandir.closedir(scan)
+        found.remove('.')
+        found.remove('..')
+        assert sorted(found) == sorted(os.listdir('/'))
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -648,6 +648,7 @@
 
     @staticmethod
     @jit.elidable
+    @signature(types.any(), types.any(), types.int(), types.int(), 
returns=types.int())
     def ll_rfind_char(s, ch, start, end):
         if end > len(s.chars):
             end = len(s.chars)
diff --git a/rpython/translator/backendopt/all.py 
b/rpython/translator/backendopt/all.py
--- a/rpython/translator/backendopt/all.py
+++ b/rpython/translator/backendopt/all.py
@@ -2,6 +2,7 @@
 from rpython.translator.backendopt import inline
 from rpython.translator.backendopt.malloc import remove_mallocs
 from rpython.translator.backendopt.constfold import constant_fold_graph
+from rpython.translator.backendopt.constfold import replace_we_are_jitted
 from rpython.translator.backendopt.stat import print_statistics
 from rpython.translator.backendopt.merge_if_blocks import merge_if_blocks
 from rpython.translator import simplify
@@ -36,6 +37,7 @@
     # inline_threshold, mallocs
     # merge_if_blocks, constfold, heap2stack
     # clever_malloc_removal, remove_asserts
+    # replace_we_are_jitted
 
     config = translator.config.translation.backendopt.copy(as_default=True)
     config.set(**kwds)
@@ -49,6 +51,10 @@
         print "before optimizations:"
         print_statistics(translator.graphs[0], translator, "per-graph.txt")
 
+    if config.replace_we_are_jitted:
+        for graph in graphs:
+            replace_we_are_jitted(graph)
+
     if config.remove_asserts:
         constfold(config, graphs)
         remove_asserts(translator, graphs)
diff --git a/rpython/translator/backendopt/constfold.py 
b/rpython/translator/backendopt/constfold.py
--- a/rpython/translator/backendopt/constfold.py
+++ b/rpython/translator/backendopt/constfold.py
@@ -276,3 +276,25 @@
             rewire_links(splitblocks, graph)
         if not diffused and not splitblocks:
             break # finished
+
+def replace_symbolic(graph, symbolic, value):
+    result = False
+    for block in graph.iterblocks():
+        for op in block.operations:
+            for i, arg in enumerate(op.args):
+                if isinstance(arg, Constant) and arg.value is symbolic:
+                    op.args[i] = value
+                    result = True
+        if block.exitswitch is symbolic:
+            block.exitswitch = value
+            result = True
+    return result
+
+def replace_we_are_jitted(graph):
+    from rpython.rlib import jit
+    replacement = Constant(0)
+    replacement.concretetype = lltype.Signed
+    did_replacement = replace_symbolic(graph, jit._we_are_jitted, replacement)
+    if did_replacement:
+        constant_fold_graph(graph)
+    return did_replacement
diff --git a/rpython/translator/backendopt/test/test_all.py 
b/rpython/translator/backendopt/test/test_all.py
--- a/rpython/translator/backendopt/test/test_all.py
+++ b/rpython/translator/backendopt/test/test_all.py
@@ -289,3 +289,19 @@
         llinterp = LLInterpreter(t.rtyper)
         res = llinterp.eval_graph(later_graph, [10])
         assert res == 1
+
+    def test_replace_we_are_jitted(self):
+        from rpython.rlib import jit
+        def f():
+            if jit.we_are_jitted():
+                return 1
+            return 2 + jit.we_are_jitted()
+
+        t = self.translateopt(f, [])
+        graph = graphof(t, f)
+        # by default, replace_we_are_jitted is off
+        assert graph.startblock.operations[0].args[0].value is 
jit._we_are_jitted
+
+        t = self.translateopt(f, [], replace_we_are_jitted=True)
+        graph = graphof(t, f)
+        assert graph.startblock.exits[0].args[0].value == 2
diff --git a/rpython/translator/backendopt/test/test_constfold.py 
b/rpython/translator/backendopt/test/test_constfold.py
--- a/rpython/translator/backendopt/test/test_constfold.py
+++ b/rpython/translator/backendopt/test/test_constfold.py
@@ -7,6 +7,7 @@
 from rpython.rtyper import rclass
 from rpython.rlib import objectmodel
 from rpython.translator.backendopt.constfold import constant_fold_graph
+from rpython.translator.backendopt.constfold import replace_we_are_jitted
 from rpython.conftest import option
 
 def get_graph(fn, signature):
@@ -343,3 +344,18 @@
     merge_if_blocks.merge_if_blocks_once(graph)
     constant_fold_graph(graph)
     check_graph(graph, [], 66, t)
+
+def test_replace_we_are_jitted():
+    from rpython.rlib import jit
+    def fn():
+        if jit.we_are_jitted():
+            return 1
+        return 2 + jit.we_are_jitted()
+    graph, t = get_graph(fn, [])
+    result = replace_we_are_jitted(graph)
+    assert result
+    checkgraph(graph)
+    # check shape of graph
+    assert len(graph.startblock.operations) == 0
+    assert graph.startblock.exitswitch is None
+    assert graph.startblock.exits[0].target.exits[0].args[0].value == 2
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -381,7 +381,7 @@
         """ Run all backend optimizations - lltype version
         """
         from rpython.translator.backendopt.all import backend_optimizations
-        backend_optimizations(self.translator)
+        backend_optimizations(self.translator, replace_we_are_jitted=True)
 
 
     STACKCHECKINSERTION = 'stackcheckinsertion_lltype'
diff --git a/rpython/translator/test/test_interactive.py 
b/rpython/translator/test/test_interactive.py
--- a/rpython/translator/test/test_interactive.py
+++ b/rpython/translator/test/test_interactive.py
@@ -78,3 +78,15 @@
     dll = ctypes.CDLL(str(t.driver.c_entryp))
     f = dll.pypy_g_f
     assert f(2, 3) == 5
+
+def test_check_that_driver_uses_replace_we_are_jitted():
+    from rpython.rlib import jit
+    def f():
+        if jit.we_are_jitted():
+            return 1
+        return 2 + jit.we_are_jitted()
+
+    t = Translation(f, [])
+    t.backendopt()
+    graph = t.driver.translator.graphs[0]
+    assert graph.startblock.exits[0].args[0].value == 2
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to