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