Author: Richard Plangger <planri...@gmail.com>
Branch: ppc-vsx-support
Changeset: r85597:fb6cdfd34d1b
Date: 2016-07-07 13:58 +0200
http://bitbucket.org/pypy/pypy/changeset/fb6cdfd34d1b/

Log:    merge default

diff --git a/pypy/module/_cffi_backend/ctypestruct.py 
b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -90,7 +90,7 @@
         self.force_lazy_struct()
         space = self.space
         try:
-            cfield = self._fields_dict[fieldname]
+            cfield = self._getcfield_const(fieldname)
         except KeyError:
             raise OperationError(space.w_KeyError, space.wrap(fieldname))
         if cfield.bitshift >= 0:
diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -129,6 +129,7 @@
     return str(soname)
 
 def freeze_refcnts(self):
+    rawrefcount._dont_free_any_more()
     return #ZZZ
     state = self.space.fromcache(RefcountState)
     self.frozen_refcounts = {}
diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -835,7 +835,7 @@
     data before the other iterator, it is faster to use list() instead
     of tee()
 
-    Equivalent to :
+    If iter(iterable) has no method __copy__(), this is equivalent to:
 
     def tee(iterable, n=2):
         def gen(next, data={}, cnt=[0]):
@@ -848,17 +848,22 @@
                 yield item
         it = iter(iterable)
         return tuple([gen(it.next) for i in range(n)])
+
+    If iter(iterable) has a __copy__ method, though, we just return
+    a tuple t = (iterable, t[0].__copy__(), t[1].__copy__(), ...).
     """
     if n < 0:
         raise oefmt(space.w_ValueError, "n must be >= 0")
 
-    if isinstance(w_iterable, W_TeeIterable):     # optimization only
-        chained_list = w_iterable.chained_list
-        w_iterator = w_iterable.w_iterator
+    if space.findattr(w_iterable, space.wrap("__copy__")) is not None:
+        # In this case, we don't instantiate any W_TeeIterable.
+        # We just rely on doing repeated __copy__().  This case
+        # includes the situation where w_iterable is already
+        # a W_TeeIterable itself.
         iterators_w = [w_iterable] * n
         for i in range(1, n):
-            iterators_w[i] = space.wrap(W_TeeIterable(space, w_iterator,
-                                                      chained_list))
+            w_iterable = space.call_method(w_iterable, "__copy__")
+            iterators_w[i] = w_iterable
     else:
         w_iterator = space.iter(w_iterable)
         chained_list = TeeChainedListNode()
@@ -891,6 +896,11 @@
         self.chained_list = chained_list.next
         return w_obj
 
+    def copy_w(self):
+        space = self.space
+        tee_iter = W_TeeIterable(space, self.w_iterator, self.chained_list)
+        return space.wrap(tee_iter)
+
 def W_TeeIterable___new__(space, w_subtype, w_iterable):
     # Obscure and undocumented function.  PyPy only supports w_iterable
     # being a W_TeeIterable, because the case where it is a general
@@ -906,6 +916,7 @@
         __new__ = interp2app(W_TeeIterable___new__),
         __iter__ = interp2app(W_TeeIterable.iter_w),
         next     = interp2app(W_TeeIterable.next_w),
+        __copy__ = interp2app(W_TeeIterable.copy_w),
         __weakref__ = make_weakref_descr(W_TeeIterable),
         )
 W_TeeIterable.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -702,6 +702,48 @@
         x = d.next()
         assert x == 'b'
 
+    def test_tee_defines_copy(self):
+        import itertools
+        a, b = itertools.tee('abc')
+        c = b.__copy__()
+        assert list(a) == ['a', 'b', 'c']
+        assert list(b) == ['a', 'b', 'c']
+        assert list(c) == ['a', 'b', 'c']
+        a, = itertools.tee('abc', 1)
+        x = a.next()
+        assert x == 'a'
+        b = a.__copy__()
+        x = a.next()
+        assert x == 'b'
+        x = b.next()
+        assert x == 'b'
+
+    def test_tee_function_uses_copy(self):
+        import itertools
+        class MyIterator(object):
+            def __iter__(self):
+                return self
+            def next(self):
+                raise NotImplementedError
+            def __copy__(self):
+                return iter('def')
+        my = MyIterator()
+        a, = itertools.tee(my, 1)
+        assert a is my
+        a, b = itertools.tee(my)
+        assert a is my
+        assert b is not my
+        assert list(b) == ['d', 'e', 'f']
+        # this gives AttributeError because it tries to call
+        # my.__copy__().__copy__() and there isn't one
+        raises(AttributeError, itertools.tee, my, 3)
+
+    def test_tee_function_empty(self):
+        import itertools
+        assert itertools.tee('abc', 0) == ()
+        a, = itertools.tee('abc', 1)
+        assert itertools.tee(a, 0) == ()
+
 
 class AppTestItertools26:
     spaceconfig = dict(usemodules=['itertools'])
diff --git a/rpython/jit/backend/zarch/assembler.py 
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -317,7 +317,7 @@
         self._push_fp_regs_to_jitframe(mc)
 
 
-        # First argument is SPP (= r31), which is the jitframe
+        # First argument is SPP, which is the jitframe
         mc.LGR(r.r2, r.SPP)
 
         # no need to move second argument (frame_depth),
@@ -385,14 +385,12 @@
         # signature of these cond_call_slowpath functions:
         #   * on entry, r11 contains the function to call
         #   * r2, r3, r4, r5 contain arguments for the call
-        #   * r0 is the gcmap
+        #   * gcmap is pushed
         #   * the old value of these regs must already be stored in the 
jitframe
         #   * on exit, all registers are restored from the jitframe
 
         mc = InstrBuilder()
         self.mc = mc
-        ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap')
-        mc.STG(r.SCRATCH2, l.addr(ofs2,r.SPP))
         mc.store_link()
         mc.push_std_frame()
 
@@ -502,7 +500,6 @@
         # r.RSZ is loaded from [r1], to make the caller's store a no-op here
         mc.load(r.RSZ, r.r1, 0)
         #
-        self.pop_gcmap(mc) # push_gcmap(store=True) done by the caller
         mc.restore_link()
         mc.BCR(c.ANY, r.r14)
         self.mc = None
diff --git a/rpython/jit/backend/zarch/opassembler.py 
b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -387,8 +387,7 @@
                 if reg in self._COND_CALL_SAVE_REGS]
         self._push_core_regs_to_jitframe(self.mc, should_be_saved)
 
-        # load gc map into unusual location: r0
-        self.load_gcmap(self.mc, r.SCRATCH2, regalloc.get_gcmap())
+        self.push_gcmap(self.mc, regalloc.get_gcmap())
         #
         # load the 0-to-4 arguments into these registers, with the address of
         # the function to call into r11
diff --git a/rpython/jit/backend/zarch/test/test_runner.py 
b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -26,4 +26,4 @@
 
     add_loop_instructions = "lg; lgr; larl; agr; cgfi; jge; j;$"
     bridge_loop_instructions = "lg; cgfi; jnl; lghi; " \
-                               "(lgfi|iilf);( iihf;)? (lgfi|iilf);( iihf;)? 
basr; larl; (lgfi|iilf);( iihf;)? br;$"
+                               "(lgfi|iilf);( iihf;)? (lgfi|iilf);( iihf;)? 
stg; basr; larl; (lgfi|iilf);( iihf;)? br;$"
diff --git a/rpython/jit/metainterp/optimizeopt/intdiv.py 
b/rpython/jit/metainterp/optimizeopt/intdiv.py
--- a/rpython/jit/metainterp/optimizeopt/intdiv.py
+++ b/rpython/jit/metainterp/optimizeopt/intdiv.py
@@ -1,5 +1,5 @@
 from rpython.rlib.rarithmetic import LONG_BIT, intmask, r_uint
-from rpython.rlib.rbigint import rbigint, ONERBIGINT
+
 
 from rpython.jit.metainterp.history import ConstInt
 from rpython.jit.metainterp.resoperation import ResOperation, rop
@@ -17,10 +17,19 @@
     while (r_uint(1) << (i+1)) < r_uint(m):
         i += 1
 
-    # k = 2**(64+i) // m + 1, computed manually using rbigint
-    #                         because that's the easiest
-    k1 = ONERBIGINT.lshift(LONG_BIT + i).floordiv(rbigint.fromint(m))
-    k = k1.touint() + r_uint(1)
+    # quotient = 2**(64+i) // m
+    high_word_dividend = r_uint(1) << i
+    quotient = r_uint(0)
+    for bit in range(LONG_BIT-1, -1, -1):
+        t = quotient + (r_uint(1) << bit)
+        # check: is 't * m' small enough to be < 2**(64+i), or not?
+        # note that we're really computing (2**(64+i)-1) // m, but the result
+        # is the same, because powers of two are not multiples of m.
+        if unsigned_mul_high(t, r_uint(m)) < high_word_dividend:
+            quotient = t     # yes, small enough
+
+    # k = 2**(64+i) // m + 1
+    k = quotient + r_uint(1)
 
     assert k != r_uint(0)
     # Proof that k < 2**64 holds in all cases, even with the "+1":
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to