[pypy-commit] pypy default: merge

fijal noreply at buildbot.pypy.org
Wed Feb 26 09:35:19 CET 2014


Author: Maciej Fijalkowski <fijall at 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)
 
 
- at 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)


More information about the pypy-commit mailing list