Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r69455:0746a182b067 Date: 2014-02-26 10:34 +0200 http://bitbucket.org/pypy/pypy/changeset/0746a182b067/
Log: merge diff --git a/lib-python/2.7/threading.py b/lib-python/2.7/threading.py --- a/lib-python/2.7/threading.py +++ b/lib-python/2.7/threading.py @@ -246,7 +246,14 @@ else: # PyPy patch: use _py3k_acquire() if timeout > 0: - gotit = waiter._py3k_acquire(True, timeout) + try: + gotit = waiter._py3k_acquire(True, timeout) + except OverflowError: + # bah, in Python 3, acquire(True, timeout) raises + # OverflowError if the timeout is too huge. For + # forward-compatibility reasons we do the same. + waiter.acquire() + gotit = True else: gotit = waiter.acquire(False) if not gotit: diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -14,6 +14,8 @@ _immutable_fields_ = ['size?', 'name', 'name_position'] # note that 'size' is not strictly immutable, because it can change # from -1 to the real value in the W_CTypeStruct subclass. + # XXX this could be improved with an elidable method get_size() + # that raises in case it's still -1... cast_anything = False is_primitive_integer = False diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -159,7 +159,7 @@ subentry = ProfilerSubEntry(entry.frame) self.calls[entry] = subentry return subentry - return None + raise class ProfilerContext(object): def __init__(self, profobj, entry): @@ -181,8 +181,11 @@ entry._stop(tt, it) if profobj.subcalls and self.previous: caller = jit.promote(self.previous.entry) - subentry = caller._get_or_make_subentry(entry, False) - if subentry is not None: + try: + subentry = caller._get_or_make_subentry(entry, False) + except KeyError: + pass + else: subentry._stop(tt, it) @@ -308,7 +311,7 @@ entry = ProfilerEntry(f_code) self.data[f_code] = entry return entry - return None + raise @jit.elidable def _get_or_make_builtin_entry(self, key, make=True): @@ -319,7 +322,7 @@ entry = ProfilerEntry(self.space.wrap(key)) self.builtin_data[key] = entry return entry - return None + raise def _enter_call(self, f_code): # we have a superb gc, no point in freelist :) @@ -332,8 +335,11 @@ if context is None: return self = jit.promote(self) - entry = self._get_or_make_entry(f_code, False) - if entry is not None: + try: + entry = self._get_or_make_entry(f_code, False) + except KeyError: + pass + else: context._stop(self, entry) self.current_context = context.previous @@ -347,8 +353,11 @@ if context is None: return self = jit.promote(self) - entry = self._get_or_make_builtin_entry(key, False) - if entry is not None: + try: + entry = self._get_or_make_builtin_entry(key, False) + except KeyError: + pass + else: context._stop(self, entry) self.current_context = context.previous diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -532,7 +532,8 @@ if w_dtype is dtype.w_box_type: return dtype if space.isinstance_w(w_dtype, space.w_type): - raise oefmt(space.w_NotImplementedError, "object dtype not implemented") + raise oefmt(space.w_NotImplementedError, + "cannot create dtype with type '%N'", w_dtype) raise oefmt(space.w_TypeError, "data type not understood") W_Dtype.typedef = TypeDef("dtype", @@ -587,10 +588,8 @@ except ValueError: raise oefmt(space.w_TypeError, "data type not understood") if char == NPY.CHARLTR: - char = NPY.STRINGLTR - size = 1 - - if char == NPY.STRINGLTR: + return new_string_dtype(space, 1, NPY.CHARLTR) + elif char == NPY.STRINGLTR: return new_string_dtype(space, size) elif char == NPY.UNICODELTR: return new_unicode_dtype(space, size) @@ -599,13 +598,13 @@ assert False -def new_string_dtype(space, size): +def new_string_dtype(space, size, char=NPY.STRINGLTR): return W_Dtype( types.StringType(), elsize=size, num=NPY.STRING, kind=NPY.STRINGLTR, - char=NPY.STRINGLTR, + char=char, w_box_type=space.gettypefor(interp_boxes.W_StringBox), ) diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -1448,9 +1448,10 @@ # scalars and strings w/o __array__ method isstr = space.isinstance_w(w_object, space.w_str) if not issequence_w(space, w_object) or isstr: - if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): - dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) - return W_NDimArray.new_scalar(space, dtype, w_object) + if dtype is None or dtype.char != NPY.CHARLTR: + if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): + dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) + return W_NDimArray.new_scalar(space, dtype, w_object) if space.is_none(w_order): order = 'C' diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -452,7 +452,7 @@ assert np.dtype(o).str == '|O8' else: exc = raises(NotImplementedError, "np.dtype(o)") - assert exc.value[0] == 'object dtype not implemented' + assert exc.value[0] == "cannot create dtype with type '%s'" % o.__name__ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): @@ -891,6 +891,11 @@ assert dtype('void').byteorder == '|' assert dtype((int, 2)).byteorder == '|' assert dtype(np.generic).str == '|V0' + d = dtype(np.character) + assert d.num == 18 + assert d.char == 'S' + assert d.kind == 'S' + assert d.str == '|S0' def test_dtype_str(self): from numpypy import dtype @@ -1055,9 +1060,15 @@ assert isinstance(u, unicode) def test_character_dtype(self): + import numpy as np from numpypy import array, character x = array([["A", "B"], ["C", "D"]], character) assert (x == [["A", "B"], ["C", "D"]]).all() + d = np.dtype('c') + assert d.num == 18 + assert d.char == 'c' + assert d.kind == 'S' + assert d.str == '|S1' class AppTestRecordDtypes(BaseNumpyAppTest): spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"]) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1697,16 +1697,12 @@ assert exc.value[0] == "data-type must not be 0-sized" assert a.view('S4') == '\x03' a = array('abc1', dtype='c') - import sys - if '__pypy__' in sys.builtin_module_names: - raises(ValueError, a.view, 'S4') - raises(ValueError, a.view, [('a', 'i2'), ('b', 'i2')]) - else: - assert a.view('S4') == 'abc1' - b = a.view([('a', 'i2'), ('b', 'i2')]) - assert b.shape == (1,) - assert b[0][0] == 25185 - assert b[0][1] == 12643 + assert (a == ['a', 'b', 'c', '1']).all() + assert a.view('S4') == 'abc1' + b = a.view([('a', 'i2'), ('b', 'i2')]) + assert b.shape == (1,) + assert b[0][0] == 25185 + assert b[0][1] == 12643 a = array([(1, 2)], dtype=[('a', 'int64'), ('b', 'int64')])[0] assert a.shape == () assert a.view('S16') == '\x01' + '\x00' * 7 + '\x02' diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -6,8 +6,9 @@ from _pytest.assertion import newinterpret except ImportError: # e.g. Python 2.5 newinterpret = None -from pypy.tool.jitlogparser.parser import SimpleParser, Function, TraceForOpcode -from pypy.tool.jitlogparser.storage import LoopStorage +from rpython.tool.jitlogparser.parser import (SimpleParser, Function, + TraceForOpcode) +from rpython.tool.jitlogparser.storage import LoopStorage def find_ids_range(code): diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -3,7 +3,7 @@ import types import subprocess import py -from lib_pypy import disassembler +from rpython.tool import disassembler from rpython.tool.udir import udir from rpython.tool import logparser from rpython.jit.tool.jitoutput import parse_prof @@ -129,7 +129,7 @@ class TestOpMatcher_(object): def match(self, src1, src2, **kwds): - from pypy.tool.jitlogparser.parser import SimpleParser + from rpython.tool.jitlogparser.parser import SimpleParser loop = SimpleParser.parse_from_input(src1) matcher = OpMatcher(loop.operations) try: diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py --- a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py +++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py @@ -4,7 +4,7 @@ from rpython.tool.logparser import extract_category from rpython.jit.backend.tool.viewcode import ObjdumpNotFound -from pypy.tool.jitlogparser.parser import (import_log, parse_log_counts, +from rpython.tool.jitlogparser.parser import (import_log, parse_log_counts, mangle_descr) from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC 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 @@ -622,7 +622,6 @@ sys.maxint == 2147483647) -@jit.elidable def _string_to_int_or_long(space, w_source, string, base=10): w_longval = None value = 0 diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py --- a/rpython/jit/codewriter/call.py +++ b/rpython/jit/codewriter/call.py @@ -241,6 +241,21 @@ else: extraeffect = EffectInfo.EF_CANNOT_RAISE # + # check that the result is really as expected + if loopinvariant: + if extraeffect != EffectInfo.EF_LOOPINVARIANT: + from rpython.jit.codewriter.policy import log; log.WARNING( + "in operation %r: this calls a _jit_loop_invariant_ function," + " but this contradicts other sources (e.g. it can have random" + " effects)" % (op,)) + if elidable: + if extraeffect not in (EffectInfo.EF_ELIDABLE_CANNOT_RAISE, + EffectInfo.EF_ELIDABLE_CAN_RAISE): + from rpython.jit.codewriter.policy import log; log.WARNING( + "in operation %r: this calls an _elidable_function_," + " but this contradicts other sources (e.g. it can have random" + " effects)" % (op,)) + # effectinfo = effectinfo_from_writeanalyze( self.readwrite_analyzer.analyze(op, self.seen), self.cpu, extraeffect, oopspecindex, can_invalidate, call_release_gil_target, diff --git a/rpython/jit/codewriter/test/test_call.py b/rpython/jit/codewriter/test/test_call.py --- a/rpython/jit/codewriter/test/test_call.py +++ b/rpython/jit/codewriter/test/test_call.py @@ -248,3 +248,26 @@ op = block.operations[-1] call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() + +def test_no_random_effects_for_rotateLeft(): + from rpython.jit.backend.llgraph.runner import LLGraphCPU + from rpython.rlib.rarithmetic import r_uint + + if r_uint.BITS == 32: + py.test.skip("64-bit only") + + from rpython.rlib.rmd5 import _rotateLeft + def f(n, m): + return _rotateLeft(r_uint(n), m) + + rtyper = support.annotate(f, [7, 9]) + jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) + cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) + res = cc.find_all_graphs(FakePolicy()) + + [f_graph] = [x for x in res if x.func is f] + [block, _] = list(f_graph.iterblocks()) + op = block.operations[-1] + call_descr = cc.getcalldescr(op) + assert not call_descr.extrainfo.has_random_effects() + assert call_descr.extrainfo.check_is_elidable() diff --git a/rpython/jit/metainterp/test/test_list.py b/rpython/jit/metainterp/test/test_list.py --- a/rpython/jit/metainterp/test/test_list.py +++ b/rpython/jit/metainterp/test/test_list.py @@ -287,6 +287,48 @@ assert res == 5 self.check_resops(call=0) + def test_list_mul_virtual(self): + class Foo: + def __init__(self, l): + self.l = l + l[0] = self + + myjitdriver = JitDriver(greens = [], reds = ['y']) + def f(y): + while y > 0: + myjitdriver.jit_merge_point(y=y) + Foo([None] * 5) + y -= 1 + return 42 + + self.meta_interp(f, [5]) + self.check_resops({'int_sub': 2, + 'int_gt': 2, + 'guard_true': 2, + 'jump': 1}) + + def test_list_mul_unsigned_virtual(self): + from rpython.rlib.rarithmetic import r_uint + + class Foo: + def __init__(self, l): + self.l = l + l[0] = self + + myjitdriver = JitDriver(greens = [], reds = ['y']) + def f(y): + while y > 0: + myjitdriver.jit_merge_point(y=y) + Foo([None] * r_uint(5)) + y -= 1 + return 42 + + self.meta_interp(f, [5]) + self.check_resops({'int_sub': 2, + 'int_gt': 2, + 'guard_true': 2, + 'jump': 1}) + class TestLLtype(ListTests, LLJitMixin): def test_listops_dont_invalidate_caches(self): diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -709,5 +709,4 @@ result = ovfcheck(result + digit) except OverflowError: raise ParseStringOverflowError(p) - - +string_to_int._elidable_function_ = True diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -116,12 +116,14 @@ # default case: # invoke the around-handlers only for "not too small" external calls; # sandboxsafe is a hint for "too-small-ness" (e.g. math functions). - invoke_around_handlers = not sandboxsafe + # Also, _nowrapper functions cannot release the GIL, by default. + invoke_around_handlers = not sandboxsafe and not _nowrapper if random_effects_on_gcobjs not in (False, True): random_effects_on_gcobjs = ( invoke_around_handlers or # because it can release the GIL has_callback) # because the callback can do it + assert not (elidable_function and random_effects_on_gcobjs) funcptr = lltype.functionptr(ext_type, name, external='C', compilation_info=compilation_info, diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py --- a/rpython/rtyper/test/test_rlist.py +++ b/rpython/rtyper/test/test_rlist.py @@ -1619,3 +1619,17 @@ rgc.ll_arraycopy = old_arraycopy # assert 2 <= res <= 10 + + def test_alloc_and_set(self): + def fn(i): + lst = [0] * r_uint(i) + return lst + t, rtyper, graph = self.gengraph(fn, [int]) + block = graph.startblock + seen = 0 + for op in block.operations: + if op.opname in ['cast_int_to_uint', 'cast_uint_to_int']: + continue + assert op.opname == 'direct_call' + seen += 1 + assert seen == 1 diff --git a/lib_pypy/disassembler.py b/rpython/tool/disassembler.py rename from lib_pypy/disassembler.py rename to rpython/tool/disassembler.py diff --git a/pypy/tool/jitlogparser/__init__.py b/rpython/tool/jitlogparser/__init__.py rename from pypy/tool/jitlogparser/__init__.py rename to rpython/tool/jitlogparser/__init__.py diff --git a/pypy/tool/jitlogparser/module_finder.py b/rpython/tool/jitlogparser/module_finder.py rename from pypy/tool/jitlogparser/module_finder.py rename to rpython/tool/jitlogparser/module_finder.py diff --git a/pypy/tool/jitlogparser/parser.py b/rpython/tool/jitlogparser/parser.py rename from pypy/tool/jitlogparser/parser.py rename to rpython/tool/jitlogparser/parser.py diff --git a/pypy/tool/jitlogparser/storage.py b/rpython/tool/jitlogparser/storage.py rename from pypy/tool/jitlogparser/storage.py rename to rpython/tool/jitlogparser/storage.py --- a/pypy/tool/jitlogparser/storage.py +++ b/rpython/tool/jitlogparser/storage.py @@ -5,8 +5,8 @@ import py import os -from lib_pypy.disassembler import dis -from pypy.tool.jitlogparser.module_finder import gather_all_code_objs +from rpython.tool.disassembler import dis +from rpython.tool.jitlogparser.module_finder import gather_all_code_objs class LoopStorage(object): def __init__(self, extrapath=None): diff --git a/pypy/tool/jitlogparser/test/__init__.py b/rpython/tool/jitlogparser/test/__init__.py rename from pypy/tool/jitlogparser/test/__init__.py rename to rpython/tool/jitlogparser/test/__init__.py diff --git a/pypy/tool/jitlogparser/test/logtest.log b/rpython/tool/jitlogparser/test/logtest.log rename from pypy/tool/jitlogparser/test/logtest.log rename to rpython/tool/jitlogparser/test/logtest.log diff --git a/pypy/tool/jitlogparser/test/logtest2.log b/rpython/tool/jitlogparser/test/logtest2.log rename from pypy/tool/jitlogparser/test/logtest2.log rename to rpython/tool/jitlogparser/test/logtest2.log diff --git a/pypy/tool/jitlogparser/test/test_modulefinder.py b/rpython/tool/jitlogparser/test/test_modulefinder.py rename from pypy/tool/jitlogparser/test/test_modulefinder.py rename to rpython/tool/jitlogparser/test/test_modulefinder.py --- a/pypy/tool/jitlogparser/test/test_modulefinder.py +++ b/rpython/tool/jitlogparser/test/test_modulefinder.py @@ -1,5 +1,5 @@ import py -from pypy.tool.jitlogparser.module_finder import gather_all_code_objs +from rpython.tool.jitlogparser.module_finder import gather_all_code_objs import re, sys def setup_module(mod): diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/rpython/tool/jitlogparser/test/test_parser.py rename from pypy/tool/jitlogparser/test/test_parser.py rename to rpython/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/rpython/tool/jitlogparser/test/test_parser.py @@ -1,8 +1,8 @@ -from pypy.tool.jitlogparser.parser import (SimpleParser, TraceForOpcode, - Function, adjust_bridges, - import_log, split_trace, Op, - parse_log_counts) -from pypy.tool.jitlogparser.storage import LoopStorage +from rpython.tool.jitlogparser.parser import (SimpleParser, TraceForOpcode, + Function, adjust_bridges, + import_log, split_trace, Op, + parse_log_counts) +from rpython.tool.jitlogparser.storage import LoopStorage import py, sys from rpython.jit.backend.detect_cpu import autodetect diff --git a/pypy/tool/jitlogparser/test/test_storage.py b/rpython/tool/jitlogparser/test/test_storage.py rename from pypy/tool/jitlogparser/test/test_storage.py rename to rpython/tool/jitlogparser/test/test_storage.py --- a/pypy/tool/jitlogparser/test/test_storage.py +++ b/rpython/tool/jitlogparser/test/test_storage.py @@ -1,5 +1,5 @@ import py -from pypy.tool.jitlogparser.storage import LoopStorage +from rpython.tool.jitlogparser.storage import LoopStorage def test_load_codes(): tmppath = py.test.ensuretemp('load_codes') diff --git a/pypy/tool/jitlogparser/test/x.py b/rpython/tool/jitlogparser/test/x.py rename from pypy/tool/jitlogparser/test/x.py rename to rpython/tool/jitlogparser/test/x.py diff --git a/rpython/translator/transform.py b/rpython/translator/transform.py --- a/rpython/translator/transform.py +++ b/rpython/translator/transform.py @@ -30,7 +30,7 @@ # [a] * b # --> # c = newlist(a) -# d = mul(c, int b) +# d = mul(c, b) # --> # d = alloc_and_set(b, a) @@ -44,8 +44,7 @@ len(op.args) == 1): length1_lists[op.result] = op.args[0] elif (op.opname == 'mul' and - op.args[0] in length1_lists and - self.gettype(op.args[1]) is int): + op.args[0] in length1_lists): new_op = SpaceOperation('alloc_and_set', (op.args[1], length1_lists[op.args[0]]), op.result) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit