Author: Richard Plangger <planri...@gmail.com> Branch: vecopt-merge Changeset: r79896:fde3bd5b3b48 Date: 2015-09-29 16:07 +0200 http://bitbucket.org/pypy/pypy/changeset/fde3bd5b3b48/
Log: merged default diff too long, truncating to 2000 out of 6994 lines diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -92,6 +92,8 @@ if sys.platform == "win32": module_suggests["cpyext"].append(("translation.shared", True)) + +# NOTE: this dictionary is not used any more module_import_dependencies = { # no _rawffi if importing rpython.rlib.clibffi raises ImportError # or CompilationError or py.test.skip.Exception @@ -108,6 +110,7 @@ } def get_module_validator(modname): + # NOTE: this function is not used any more if modname in module_import_dependencies: modlist = module_import_dependencies[modname] def validator(config): diff --git a/pypy/doc/extending.rst b/pypy/doc/extending.rst --- a/pypy/doc/extending.rst +++ b/pypy/doc/extending.rst @@ -5,8 +5,8 @@ with any external library. Right now, there are the following possibilities of providing -third-party modules for the PyPy python interpreter (in order of -usefulness): +third-party modules for the PyPy python interpreter (in order, from most +directly useful to most messy to use with PyPy): * Write them in pure Python and use CFFI_. diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -67,7 +67,7 @@ The other commands of ``setup.py`` are available too, like ``build``. .. _PyPI: https://pypi.python.org/pypi -.. _`use virtualenv (as documented here)`: getting-started.html#installing-using-virtualenv +.. _`use virtualenv (as documented here)`: install.html#installing-using-virtualenv Module xyz does not work in the sandboxed PyPy? diff --git a/pypy/doc/jit-hooks.rst b/pypy/doc/jit-hooks.rst --- a/pypy/doc/jit-hooks.rst +++ b/pypy/doc/jit-hooks.rst @@ -5,19 +5,8 @@ understanding what's pypy's JIT doing while running your program. There are three functions related to that coming from the ``pypyjit`` module: -.. function:: set_optimize_hook(callable) - Set a compiling hook that will be called each time a loop is optimized, - but before assembler compilation. This allows adding additional - optimizations on Python level. - - The callable will be called with the ``pypyjit.JitLoopInfo`` object. - Refer to it's documentation for details. - - Result value will be the resulting list of operations, or None - - -.. function:: set_compile_hook(callable) +.. function:: set_compile_hook(callable, operations=True) Set a compiling hook that will be called each time a loop is compiled. @@ -28,6 +17,9 @@ inside the jit hook is itself jitted, it will get compiled, but the jit hook won't be called for that. + if operations=False, no list of operations will be available. Useful + if the hook is supposed to be very lighweight. + .. function:: set_abort_hook(hook) Set a hook (callable) that will be called each time there is tracing @@ -66,3 +58,25 @@ * ``loop_run_times`` - counters for number of times loops are run, only works when ``enable_debug`` is called. + +.. class:: JitLoopInfo + + A class containing information about the compiled loop. Usable attributes: + + * ``operations`` - list of operations, if requested + + * ``jitdriver_name`` - the name of jitdriver associated with this loop + + * ``greenkey`` - a key at which the loop got compiled (e.g. code position, + is_being_profiled, pycode tuple for python jitdriver) + + * ``loop_no`` - loop cardinal number + + * ``bridge_no`` - id of the fail descr + + * ``type`` - "entry bridge", "loop" or "bridge" + + * ``asmaddr`` - an address in raw memory where assembler resides + + * ``asmlen`` - length of raw memory with assembler associated + 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 @@ -22,6 +22,28 @@ .. branch: missing_openssl_include Fix for missing headers in OpenBSD, already applied in downstream ports +.. branch: gc-more-incremental +Remove a source of non-incremental-ness in the GC: now +external_malloc() no longer runs gc_step_until() any more. If there +is a currently-running major collection, we do only so many steps +before returning. This number of steps depends on the size of the +allocated object. It is controlled by tracking the general progress +of these major collection steps and the size of old objects that +keep adding up between them. + +.. branch: remember-tracing-counts +Reenable jithooks + +.. branch: detect_egd2 + +.. branch: shadowstack-no-move-2 +Issue #2141: fix a crash on Windows and OS/X and ARM when running +at least 20 threads. + +.. branch: numpy-ctypes + +Add support for ndarray.ctypes property. + .. branch: vecopt .. branch: vecopt-merge diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -341,8 +341,8 @@ def jitpolicy(self, driver): from pypy.module.pypyjit.policy import PyPyJitPolicy - #from pypy.module.pypyjit.hooks import pypy_hooks - return PyPyJitPolicy()#pypy_hooks) + from pypy.module.pypyjit.hooks import pypy_hooks + return PyPyJitPolicy(pypy_hooks) def get_entry_point(self, config): from pypy.tool.lib_pypy import import_from_lib_pypy diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -5,6 +5,7 @@ from __future__ import with_statement import operator from __pypy__ import resizelist_hint, newlist_hint +from __pypy__ import specialized_zip_2_lists # ____________________________________________________________ @@ -217,11 +218,16 @@ in length to the length of the shortest argument sequence.""" l = len(sequences) if l == 2: + # A very fast path if the two sequences are lists + seq0 = sequences[0] + seq1 = sequences[1] + try: + return specialized_zip_2_lists(seq0, seq1) + except TypeError: + pass # This is functionally the same as the code below, but more # efficient because it unrolls the loops over 'sequences'. # Only for two arguments, which is the most common case. - seq0 = sequences[0] - seq1 = sequences[1] iter0 = iter(seq0) iter1 = iter(seq1) hint = min(100000000, # max 100M diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -83,6 +83,7 @@ 'newdict' : 'interp_dict.newdict', 'reversed_dict' : 'interp_dict.reversed_dict', 'strategy' : 'interp_magic.strategy', # dict,set,list + 'specialized_zip_2_lists' : 'interp_magic.specialized_zip_2_lists', 'set_debug' : 'interp_magic.set_debug', 'locals_to_fast' : 'interp_magic.locals_to_fast', 'save_module_content_for_future_reload': diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -147,3 +147,7 @@ @unwrap_spec(w_module=MixedModule) def save_module_content_for_future_reload(space, w_module): w_module.save_module_content_for_future_reload() + +def specialized_zip_2_lists(space, w_list1, w_list2): + from pypy.objspace.std.specialisedtupleobject import specialized_zip_2_lists + return specialized_zip_2_lists(space, w_list1, w_list2) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -7,6 +7,7 @@ from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib import jit from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rfficache from pypy.interpreter.error import oefmt from pypy.module._cffi_backend import cdataobj, misc @@ -125,12 +126,25 @@ cdata[0] = value +# XXX explicitly use an integer type instead of lltype.UniChar here, +# because for now the latter is defined as unsigned by RPython (even +# though it may be signed when 'wchar_t' is written to C). +WCHAR_INT = {(2, False): rffi.USHORT, + (4, False): rffi.UINT, + (4, True): rffi.INT}[rffi.sizeof(lltype.UniChar), + rfficache.signof_c_type('wchar_t')] +WCHAR_INTP = rffi.CArrayPtr(WCHAR_INT) + class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar): _attrs_ = [] + if rffi.r_wchar_t.SIGN: + def write_raw_integer_data(self, w_cdata, value): + w_cdata.write_raw_signed_data(value) + def cast_to_int(self, cdata): - unichardata = rffi.cast(rffi.CWCHARP, cdata) - return self.space.wrap(ord(unichardata[0])) + unichardata = rffi.cast(WCHAR_INTP, cdata) + return self.space.wrap(unichardata[0]) def convert_to_object(self, cdata): unichardata = rffi.cast(rffi.CWCHARP, cdata) diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -241,20 +241,26 @@ res = libssl_RAND_status() return space.wrap(res) - @unwrap_spec(path=str) - def RAND_egd(space, path): - """RAND_egd(path) -> bytes + if HAVE_OPENSSL_RAND_EGD: + @unwrap_spec(path=str) + def RAND_egd(space, path): + """RAND_egd(path) -> bytes - Queries the entropy gather daemon (EGD) on socket path. Returns number - of bytes read. Raises socket.sslerror if connection to EGD fails or - if it does provide enough data to seed PRNG.""" - with rffi.scoped_str2charp(path) as socket_path: - bytes = libssl_RAND_egd(socket_path) - if bytes == -1: - raise ssl_error(space, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG") - return space.wrap(bytes) + Queries the entropy gather daemon (EGD) on socket path. Returns number + of bytes read. Raises socket.sslerror if connection to EGD fails or + if it does provide enough data to seed PRNG.""" + with rffi.scoped_str2charp(path) as socket_path: + bytes = libssl_RAND_egd(socket_path) + if bytes == -1: + raise ssl_error(space, + "EGD connection failed or EGD did not return " + "enough data to seed the PRNG") + return space.wrap(bytes) + else: + # Dummy func for platforms missing RAND_egd(). Most likely LibreSSL. + @unwrap_spec(path=str) + def RAND_egd(space, path): + raise ssl_error(space, "RAND_egd unavailable") class _SSLSocket(W_Root): diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -36,7 +36,8 @@ assert isinstance(_ssl.OPENSSL_VERSION_INFO, tuple) assert len(_ssl.OPENSSL_VERSION_INFO) == 5 assert isinstance(_ssl.OPENSSL_VERSION, str) - assert 'openssl' in _ssl.OPENSSL_VERSION.lower() + lower_version = _ssl.OPENSSL_VERSION.lower() + assert 'openssl' in lower_version or "libressl" in lower_version assert isinstance(_ssl.ALERT_DESCRIPTION_ACCESS_DENIED, int) @@ -69,8 +70,9 @@ def test_sslwrap(self): import _ssl, _socket, sys, gc - if sys.platform == 'darwin' or 'freebsd' in sys.platform: - skip("hangs indefinitely on OSX & FreeBSD (also on CPython)") + if sys.platform == 'darwin' or 'freebsd' in sys.platform or \ + 'openbsd' in sys.platform: + skip("hangs indefinitely on OSX & BSD (also on CPython)") s = _socket.socket() if sys.version_info < (2, 7, 9): ss = _ssl.sslwrap(s, 0) diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -34,6 +34,7 @@ i += 1 _, size = struct.unpack("ll", s[i:i + 2 * WORD]) i += 2 * WORD + size * struct.calcsize("P") + i += WORD # thread id elif s[i] == '\x02': i += 1 _, size = struct.unpack("ll", s[i:i + 2 * WORD]) diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -844,6 +844,18 @@ b.byteswap() assert a != b + def test_unicode_ord_positive(self): + import sys + if sys.maxunicode == 0xffff: + skip("test for 32-bit unicodes") + a = self.array('u', '\xff\xff\xff\xff') + assert len(a) == 1 + assert repr(a[0]) == "u'\Uffffffff'" + if sys.maxint == 2147483647: + assert ord(a[0]) == -1 + else: + assert ord(a[0]) == 4294967295 + def test_weakref(self): import weakref a = self.array('c', 'Hi!') 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 @@ -2,6 +2,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from rpython.rlib import jit class W_Count(W_Root): @@ -322,6 +323,11 @@ """) +islice_ignore_items_driver = jit.JitDriver(name='islice_ignore_items', + greens=['tp'], + reds=['num', 'w_islice', + 'w_iterator']) + class W_ISlice(W_Root): def __init__(self, space, w_iterable, w_startstop, args_w): self.iterable = space.iter(w_iterable) @@ -407,11 +413,18 @@ raise def _ignore_items(self, num): - if self.iterable is None: + w_iterator = self.iterable + if w_iterator is None: raise OperationError(self.space.w_StopIteration, self.space.w_None) + + tp = self.space.type(w_iterator) while True: + islice_ignore_items_driver.jit_merge_point(tp=tp, + num=num, + w_islice=self, + w_iterator=w_iterator) try: - self.space.next(self.iterable) + self.space.next(w_iterator) except OperationError as e: if e.match(self.space, self.space.w_StopIteration): self.iterable = None 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 @@ -1085,3 +1085,18 @@ assert list(itertools.islice(c2, 3)) == expected c3 = pickle.loads(pickle.dumps(c)) assert list(itertools.islice(c3, 3)) == expected + + def test_islice_attack(self): + import itertools + class Iterator(object): + first = True + def __iter__(self): + return self + def next(self): + if self.first: + self.first = False + list(islice) + return 52 + myiter = Iterator() + islice = itertools.islice(myiter, 5, 8) + raises(StopIteration, islice.next) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -9,6 +9,7 @@ 'ndarray': 'ndarray.W_NDimArray', 'dtype': 'descriptor.W_Dtype', 'flatiter': 'flatiter.W_FlatIterator', + 'flagsobj': 'flagsobj.W_FlagsObject', '_reconstruct' : 'ndarray._reconstruct', 'scalar' : 'ctors.build_scalar', diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -1,6 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, oefmt from rpython.tool.pairtype import extendabletype +from rpython.rlib.rarithmetic import ovfcheck from pypy.module.micronumpy import support from pypy.module.micronumpy import constants as NPY @@ -44,9 +45,9 @@ raise oefmt(space.w_ValueError, "sequence too large; must be smaller than %d", NPY.MAXDIMS) try: - support.product(shape) * dtype.elsize + ovfcheck(support.product_check(shape) * dtype.elsize) except OverflowError as e: - raise oefmt(space.w_ValueError, "array is too big") + raise oefmt(space.w_ValueError, "array is too big.") strides, backstrides = calc_strides(shape, dtype.base, order) impl = concrete.ConcreteArray(shape, dtype.base, order, strides, backstrides, zero=zero) @@ -68,9 +69,9 @@ raise oefmt(space.w_ValueError, "sequence too large; must be smaller than %d", NPY.MAXDIMS) try: - totalsize = support.product(shape) * isize + totalsize = ovfcheck(support.product_check(shape) * isize) except OverflowError as e: - raise oefmt(space.w_ValueError, "array is too big") + raise oefmt(space.w_ValueError, "array is too big.") if storage_bytes > 0 : if totalsize > storage_bytes: raise OperationError(space.w_TypeError, space.wrap( @@ -116,12 +117,14 @@ return W_NDimArray(impl) @staticmethod - def new_slice(space, offset, strides, backstrides, shape, parent, orig_arr, dtype=None): + def new_slice(space, offset, strides, backstrides, shape, parent, w_arr, dtype=None): from pypy.module.micronumpy import concrete - + w_base = w_arr + if w_arr.implementation.base() is not None: + w_base = w_arr.implementation.base() impl = concrete.SliceArray(offset, strides, backstrides, shape, parent, - orig_arr, dtype) - return wrap_impl(space, space.type(orig_arr), orig_arr, impl) + w_base, dtype) + return wrap_impl(space, space.type(w_arr), w_arr, impl) @staticmethod def new_scalar(space, dtype, w_val=None): diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py --- a/pypy/module/micronumpy/boxes.py +++ b/pypy/module/micronumpy/boxes.py @@ -147,7 +147,7 @@ def get_flags(self): return (NPY.ARRAY_C_CONTIGUOUS | NPY.ARRAY_F_CONTIGUOUS | - NPY.ARRAY_WRITEABLE | NPY.ARRAY_OWNDATA) + NPY.ARRAY_ALIGNED | NPY.ARRAY_OWNDATA) def item(self, space): return self.get_dtype(space).itemtype.to_builtin_type(space, self) diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py --- a/pypy/module/micronumpy/concrete.py +++ b/pypy/module/micronumpy/concrete.py @@ -1,5 +1,7 @@ from pypy.interpreter.error import OperationError, oefmt from rpython.rlib import jit, rgc +from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.listsort import make_timsort_class from rpython.rlib.buffer import Buffer from rpython.rlib.debug import make_sure_not_resized from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage, \ @@ -16,6 +18,19 @@ is_f_contiguous) from rpython.rlib.objectmodel import keepalive_until_here +TimSort = make_timsort_class() +class StrideSort(TimSort): + ''' + argsort (return the indices to sort) a list of strides + ''' + def __init__(self, rangelist, strides): + self.strides = strides + TimSort.__init__(self, rangelist) + + def lt(self, a, b): + return self.strides[a] < self.strides[b] + + class BaseConcreteArray(object): _immutable_fields_ = ['dtype?', 'storage', 'start', 'size', 'shape[*]', 'strides[*]', 'backstrides[*]', 'order', 'gcstruct', @@ -353,12 +368,15 @@ elif order != self.order: t_strides, backstrides = calc_strides(shape, dtype, order) else: - mins = strides[0] + indx_array = range(len(strides)) + list_sorter = StrideSort(indx_array, strides) + list_sorter.sort() t_elsize = dtype.elsize - for s in strides: - if s < mins: - mins = s - t_strides = [s * t_elsize / mins for s in strides] + t_strides = strides[:] + base = dtype.elsize + for i in indx_array: + t_strides[i] = base + base *= shape[i] backstrides = calc_backstrides(t_strides, shape) impl = ConcreteArray(shape, dtype, order, t_strides, backstrides) loop.setslice(space, impl.get_shape(), impl, self) @@ -409,6 +427,7 @@ make_sure_not_resized(strides) make_sure_not_resized(backstrides) self.shape = shape + # already tested for overflow in from_shape_and_storage self.size = support.product(shape) * dtype.elsize self.order = order self.dtype = dtype @@ -428,9 +447,9 @@ raise oefmt(space.w_ValueError, "sequence too large; must be smaller than %d", NPY.MAXDIMS) try: - support.product(new_shape) * self.dtype.elsize + ovfcheck(support.product_check(new_shape) * self.dtype.elsize) except OverflowError as e: - raise oefmt(space.w_ValueError, "array is too big") + raise oefmt(space.w_ValueError, "array is too big.") strides, backstrides = calc_strides(new_shape, self.dtype, self.order) return SliceArray(self.start, strides, backstrides, new_shape, self, @@ -457,8 +476,11 @@ storage=lltype.nullptr(RAW_STORAGE), zero=True): gcstruct = V_OBJECTSTORE flags = NPY.ARRAY_ALIGNED | NPY.ARRAY_WRITEABLE - length = support.product(shape) - self.size = length * dtype.elsize + try: + length = support.product_check(shape) + self.size = ovfcheck(length * dtype.elsize) + except OverflowError: + raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.") if storage == lltype.nullptr(RAW_STORAGE): if dtype.num == NPY.OBJECT: storage = dtype.itemtype.malloc(length * dtype.elsize, zero=True) @@ -542,7 +564,10 @@ self.gcstruct = parent.gcstruct self.order = parent.order self.dtype = dtype - self.size = support.product(shape) * self.dtype.elsize + try: + self.size = ovfcheck(support.product_check(shape) * self.dtype.elsize) + except OverflowError: + raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.") self.start = start self.orig_arr = orig_arr flags = parent.flags & NPY.ARRAY_ALIGNED @@ -564,9 +589,9 @@ raise oefmt(space.w_ValueError, "sequence too large; must be smaller than %d", NPY.MAXDIMS) try: - support.product(new_shape) * self.dtype.elsize + ovfcheck(support.product_check(new_shape) * self.dtype.elsize) except OverflowError as e: - raise oefmt(space.w_ValueError, "array is too big") + raise oefmt(space.w_ValueError, "array is too big.") if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py --- a/pypy/module/micronumpy/ctors.py +++ b/pypy/module/micronumpy/ctors.py @@ -133,7 +133,9 @@ return w_arr else: imp = w_object.implementation - w_base = imp.base() or w_object + w_base = w_object + if imp.base() is not None: + w_base = imp.base() with imp as storage: sz = support.product(w_object.get_shape()) * dtype.elsize return W_NDimArray.from_shape_and_storage(space, @@ -153,7 +155,7 @@ dtype = descriptor.variable_dtype(space, dtype.char + '1') w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order) - if support.product(shape) == 1: + if support.product(shape) == 1: # safe from overflow since from_shape checks w_arr.set_scalar_value(dtype.coerce(space, elems_w[0])) else: loop.assign(space, w_arr, elems_w) @@ -213,10 +215,9 @@ raise OperationError(space.w_ValueError, space.wrap( "negative dimensions are not allowed")) try: - support.product(shape) + support.product_check(shape) except OverflowError: - raise OperationError(space.w_ValueError, space.wrap( - "array is too big.")) + raise oefmt(space.w_ValueError, "array is too big.") return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero) def empty(space, w_shape, w_dtype=None, w_order=None): diff --git a/pypy/module/micronumpy/flagsobj.py b/pypy/module/micronumpy/flagsobj.py --- a/pypy/module/micronumpy/flagsobj.py +++ b/pypy/module/micronumpy/flagsobj.py @@ -57,6 +57,9 @@ self.flags & NPY.ARRAY_F_CONTIGUOUS or self.flags & NPY.ARRAY_C_CONTIGUOUS )) + def descr_get_num(self, space): + return space.wrap(self.flags) + def descr_getitem(self, space, w_item): key = space.str_w(w_item) if key == "C" or key == "CONTIGUOUS" or key == "C_CONTIGUOUS": @@ -122,4 +125,5 @@ aligned = GetSetProperty(W_FlagsObject.descr_get_aligned), fnc = GetSetProperty(W_FlagsObject.descr_get_fnc), forc = GetSetProperty(W_FlagsObject.descr_get_forc), + num = GetSetProperty(W_FlagsObject.descr_get_num), ) diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py --- a/pypy/module/micronumpy/ndarray.py +++ b/pypy/module/micronumpy/ndarray.py @@ -6,6 +6,7 @@ from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder from rpython.rlib.rawstorage import RAW_STORAGE_PTR +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import rffi from rpython.tool.sourcetools import func_with_new_name from pypy.module.micronumpy import descriptor, ufuncs, boxes, arrayops, loop, \ @@ -611,6 +612,7 @@ "__array__(dtype) not implemented")) if type(self) is W_NDimArray: return self + # sz cannot overflow since self is valid sz = support.product(self.get_shape()) * self.get_dtype().elsize return W_NDimArray.from_shape_and_storage( space, self.get_shape(), self.implementation.storage, @@ -745,8 +747,12 @@ return out def descr_get_ctypes(self, space): - raise OperationError(space.w_NotImplementedError, space.wrap( - "ctypes not implemented yet")) + w_result = space.appexec([self], """(arr): + from numpy.core import _internal + p_data = arr.__array_interface__['data'][0] + return _internal._ctypes(arr, p_data) + """) + return w_result def buffer_w(self, space, flags): return self.implementation.get_buffer(space, True) @@ -1405,9 +1411,9 @@ return W_NDimArray.from_shape(space, shape, dtype, order) strides, backstrides = calc_strides(shape, dtype.base, order) try: - totalsize = support.product(shape) * dtype.base.elsize + totalsize = ovfcheck(support.product_check(shape) * dtype.base.elsize) except OverflowError as e: - raise oefmt(space.w_ValueError, "array is too big") + raise oefmt(space.w_ValueError, "array is too big.") impl = ConcreteArray(shape, dtype.base, order, strides, backstrides) w_ret = space.allocate_instance(W_NDimArray, w_subtype) W_NDimArray.__init__(w_ret, impl) diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -32,10 +32,16 @@ def product(s): i = 1 for x in s: + i *= x + return i + +@jit.unroll_safe +def product_check(s): + i = 1 + for x in s: i = ovfcheck(i * x) return i - def check_and_adjust_index(space, index, size, axis): if index < -size or index >= size: if axis >= 0: diff --git a/pypy/module/micronumpy/test/test_flagsobj.py b/pypy/module/micronumpy/test/test_flagsobj.py --- a/pypy/module/micronumpy/test/test_flagsobj.py +++ b/pypy/module/micronumpy/test/test_flagsobj.py @@ -30,6 +30,7 @@ assert a.flags.forc == True assert a.flags['FNC'] == False assert a.flags['FORC'] == True + assert a.flags.num == 1287 raises(KeyError, "a.flags['blah']") raises(KeyError, "a.flags['C_CONTIGUOUS'] = False") raises((TypeError, AttributeError), "a.flags.c_contiguous = False") @@ -38,6 +39,7 @@ import numpy as np a = np.int32(2) assert a.flags.c_contiguous == True + assert a.flags.num == 263 def test_compare(self): import numpy as np diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py --- a/pypy/module/micronumpy/test/test_ndarray.py +++ b/pypy/module/micronumpy/test/test_ndarray.py @@ -270,7 +270,7 @@ exc = raises(ValueError, ndarray, [1,2,256]*10000) assert exc.value[0] == 'sequence too large; must be smaller than 32' exc = raises(ValueError, ndarray, [1,2,256]*10) - assert exc.value[0] == 'array is too big' + assert exc.value[0] == 'array is too big.' def test_ndmin(self): from numpy import array @@ -2218,7 +2218,7 @@ assert _weakref.ref(a) def test_astype(self): - from numpy import array, arange + from numpy import array, arange, empty b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -2273,14 +2273,36 @@ b = a.astype('f4', order='C', copy=False) assert a is b + a = empty([3, 3, 3, 3], 'uint8') + a[:] = 0 + b = a[2] + c = b[:, :2, :] + d = c.swapaxes(1, -1) + e = d.astype('complex128') + assert e.shape == (3, 3, 2) + assert e.strides == (96, 16, 48) + assert (e.real == d).all() + def test_base(self): - from numpy import array + from numpy import array, empty assert array(1).base is None assert array([1, 2]).base is None a = array([1, 2, 3, 4]) b = a[::2] assert b.base is a + a = empty([3, 3, 3, 3], 'uint8') + a[:] = 0 + b = a[2] + assert b.base.base is None + c = b[:, :2, :] + d = c.swapaxes(1, -1) + assert c.base.base is None + assert d.base.base is None + assert d.shape == (3, 3, 2) + assert d.__array_interface__['data'][0] == \ + a.__array_interface__['data'][0] + a.strides[0] * 2 + def test_byteswap(self): from numpy import array @@ -2497,10 +2519,10 @@ assert b.shape == b[...].shape assert (b == b[...]).all() - a = np.arange(6).reshape(2, 3) + a = np.arange(6) if '__pypy__' in sys.builtin_module_names: raises(ValueError, "a[..., ...]") - b = a [..., 0] + b = a.reshape(2, 3)[..., 0] assert (b == [0, 3]).all() assert b.base is a diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py --- a/pypy/module/micronumpy/ufuncs.py +++ b/pypy/module/micronumpy/ufuncs.py @@ -1006,7 +1006,6 @@ assert isinstance(curarg, W_NDimArray) if len(arg_shapes[i]) != curarg.ndims(): # reshape - sz = product(curarg.get_shape()) * curarg.get_dtype().elsize with curarg.implementation as storage: inargs[i] = W_NDimArray.from_shape_and_storage( diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py --- a/pypy/module/pypyjit/__init__.py +++ b/pypy/module/pypyjit/__init__.py @@ -8,16 +8,18 @@ 'set_param': 'interp_jit.set_param', 'residual_call': 'interp_jit.residual_call', 'not_from_assembler': 'interp_jit.W_NotFromAssembler', - #'set_compile_hook': 'interp_resop.set_compile_hook', - #'set_optimize_hook': 'interp_resop.set_optimize_hook', - #'set_abort_hook': 'interp_resop.set_abort_hook', - #'get_stats_snapshot': 'interp_resop.get_stats_snapshot', - #'enable_debug': 'interp_resop.enable_debug', - #'disable_debug': 'interp_resop.disable_debug', - #'ResOperation': 'interp_resop.WrappedOp', - #'DebugMergePoint': 'interp_resop.DebugMergePoint', - #'JitLoopInfo': 'interp_resop.W_JitLoopInfo', - #'Box': 'interp_resop.WrappedBox', + 'get_jitcell_at_key': 'interp_jit.get_jitcell_at_key', + 'dont_trace_here': 'interp_jit.dont_trace_here', + 'trace_next_iteration': 'interp_jit.trace_next_iteration', + 'trace_next_iteration_hash': 'interp_jit.trace_next_iteration_hash', + 'set_compile_hook': 'interp_resop.set_compile_hook', + 'set_abort_hook': 'interp_resop.set_abort_hook', + 'get_stats_snapshot': 'interp_resop.get_stats_snapshot', + 'enable_debug': 'interp_resop.enable_debug', + 'disable_debug': 'interp_resop.disable_debug', + 'ResOperation': 'interp_resop.WrappedOp', + 'DebugMergePoint': 'interp_resop.DebugMergePoint', + 'JitLoopInfo': 'interp_resop.W_JitLoopInfo', 'PARAMETER_DOCS': 'space.wrap(rpython.rlib.jit.PARAMETER_DOCS)', } diff --git a/pypy/module/pypyjit/hooks.py b/pypy/module/pypyjit/hooks.py --- a/pypy/module/pypyjit/hooks.py +++ b/pypy/module/pypyjit/hooks.py @@ -35,10 +35,10 @@ self._compile_hook(debug_info, is_bridge=True) def before_compile(self, debug_info): - self._optimize_hook(debug_info, is_bridge=False) + pass def before_compile_bridge(self, debug_info): - self._optimize_hook(debug_info, is_bridge=True) + pass def _compile_hook(self, debug_info, is_bridge): space = self.space @@ -46,7 +46,8 @@ if cache.in_recursion: return if space.is_true(cache.w_compile_hook): - w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge) + w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge, + cache.compile_hook_with_ops) cache.in_recursion = True try: try: @@ -57,33 +58,4 @@ finally: cache.in_recursion = False - def _optimize_hook(self, debug_info, is_bridge=False): - space = self.space - cache = space.fromcache(Cache) - if cache.in_recursion: - return - if space.is_true(cache.w_optimize_hook): - w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge) - cache.in_recursion = True - try: - try: - w_res = space.call_function(cache.w_optimize_hook, - space.wrap(w_debug_info)) - if space.is_w(w_res, space.w_None): - return - l = [] - for w_item in space.listview(w_res): - item = space.interp_w(WrappedOp, w_item) - l.append(jit_hooks._cast_to_resop(item.op)) - del debug_info.operations[:] # modifying operations above is - # probably not a great idea since types may not work - # and we'll end up with half-working list and - # a segfault/fatal RPython error - for elem in l: - debug_info.operations.append(elem) - except OperationError, e: - e.write_unraisable(space, "jit hook ", cache.w_compile_hook) - finally: - cache.in_recursion = False - pypy_hooks = PyPyJitIface() diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py --- a/pypy/module/pypyjit/interp_jit.py +++ b/pypy/module/pypyjit/interp_jit.py @@ -5,11 +5,14 @@ from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside -from rpython.rlib import jit -from rpython.rlib.jit import current_trace_length, unroll_parameters +from rpython.rlib import jit, jit_hooks +from rpython.rlib.jit import current_trace_length, unroll_parameters,\ + JitHookInterface +from rpython.rtyper.annlowlevel import cast_instance_to_gcref import pypy.interpreter.pyopcode # for side-effects from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.pycode import CO_GENERATOR, PyCode +from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import ExitFrame, Yield from pypy.interpreter.baseobjspace import W_Root @@ -188,3 +191,100 @@ __call__ = interp2app(W_NotFromAssembler.descr_call), ) W_NotFromAssembler.typedef.acceptable_as_base_class = False + +@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode) +@dont_look_inside +def get_jitcell_at_key(space, next_instr, is_being_profiled, w_pycode): + ll_pycode = cast_instance_to_gcref(w_pycode) + return space.wrap(bool(jit_hooks.get_jitcell_at_key( + 'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode))) + +@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode) +@dont_look_inside +def dont_trace_here(space, next_instr, is_being_profiled, w_pycode): + ll_pycode = cast_instance_to_gcref(w_pycode) + jit_hooks.dont_trace_here( + 'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode) + return space.w_None + +@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode) +@dont_look_inside +def trace_next_iteration(space, next_instr, is_being_profiled, w_pycode): + ll_pycode = cast_instance_to_gcref(w_pycode) + jit_hooks.trace_next_iteration( + 'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode) + return space.w_None + +@unwrap_spec(hash=r_uint) +@dont_look_inside +def trace_next_iteration_hash(space, hash): + jit_hooks.trace_next_iteration_hash('pypyjit', hash) + return space.w_None + +# class Cache(object): +# in_recursion = False + +# def __init__(self, space): +# self.w_compile_bridge = space.w_None +# self.w_compile_loop = space.w_None + +# def set_compile_bridge(space, w_hook): +# cache = space.fromcache(Cache) +# assert w_hook is not None +# cache.w_compile_bridge = w_hook + +# def set_compile_loop(space, w_hook): +# from rpython.rlib.nonconst import NonConstant + +# cache = space.fromcache(Cache) +# assert w_hook is not None +# cache.w_compile_loop = w_hook +# cache.in_recursion = NonConstant(False) + +# class PyPyJitHookInterface(JitHookInterface): +# def after_compile(self, debug_info): +# space = self.space +# cache = space.fromcache(Cache) +# if cache.in_recursion: +# return +# l_w = [] +# if not space.is_true(cache.w_compile_loop): +# return +# for i, op in enumerate(debug_info.operations): +# if op.is_guard(): +# w_t = space.newtuple([space.wrap(i), space.wrap(op.getopnum()), space.wrap(op.getdescr().get_jitcounter_hash())]) +# l_w.append(w_t) +# try: +# cache.in_recursion = True +# try: +# space.call_function(cache.w_compile_loop, space.newlist(l_w)) +# except OperationError, e: +# e.write_unraisable(space, "jit hook ", cache.w_compile_bridge) +# finally: +# cache.in_recursion = False + +# def after_compile_bridge(self, debug_info): +# space = self.space +# cache = space.fromcache(Cache) +# if cache.in_recursion: +# return +# if not space.is_true(cache.w_compile_bridge): +# return +# w_hash = space.wrap(debug_info.fail_descr.get_jitcounter_hash()) +# try: +# cache.in_recursion = True +# try: +# space.call_function(cache.w_compile_bridge, w_hash) +# except OperationError, e: +# e.write_unraisable(space, "jit hook ", cache.w_compile_bridge) +# finally: +# cache.in_recursion = False + +# def before_compile(self, debug_info): +# pass + +# def before_compile_bridge(self, debug_info): +# pass + +# pypy_hooks = PyPyJitHookInterface() + diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -22,7 +22,6 @@ def __init__(self, space): self.w_compile_hook = space.w_None self.w_abort_hook = space.w_None - self.w_optimize_hook = space.w_None def getno(self): self.no += 1 @@ -43,8 +42,9 @@ else: return space.wrap(greenkey_repr) -def set_compile_hook(space, w_hook): - """ set_compile_hook(hook) +@unwrap_spec(operations=bool) +def set_compile_hook(space, w_hook, operations=True): + """ set_compile_hook(hook, operations=True) Set a compiling hook that will be called each time a loop is compiled. @@ -58,25 +58,9 @@ cache = space.fromcache(Cache) assert w_hook is not None cache.w_compile_hook = w_hook + cache.compile_hook_with_ops = operations cache.in_recursion = NonConstant(False) -def set_optimize_hook(space, w_hook): - """ set_optimize_hook(hook) - - Set a compiling hook that will be called each time a loop is optimized, - but before assembler compilation. This allows adding additional - optimizations on Python level. - - The hook will be called with the pypyjit.JitLoopInfo object. Refer to it's - docstring for details. - - Result value will be the resulting list of operations, or None - """ - cache = space.fromcache(Cache) - cache.w_optimize_hook = w_hook - cache.in_recursion = NonConstant(False) - - def set_abort_hook(space, w_hook): """ set_abort_hook(hook) @@ -96,6 +80,9 @@ cache.in_recursion = NonConstant(False) def wrap_oplist(space, logops, operations, ops_offset=None): + # this function is called from the JIT + from rpython.jit.metainterp.resoperation import rop + l_w = [] jitdrivers_sd = logops.metainterp_sd.jitdrivers_sd for op in operations: @@ -103,117 +90,58 @@ ofs = -1 else: ofs = ops_offset.get(op, 0) - if op.opnum == rop.DEBUG_MERGE_POINT: + num = op.getopnum() + name = op.getopname() + if num == rop.DEBUG_MERGE_POINT: jd_sd = jitdrivers_sd[op.getarg(0).getint()] greenkey = op.getarglist()[3:] repr = jd_sd.warmstate.get_location_str(greenkey) w_greenkey = wrap_greenkey(space, jd_sd.jitdriver, greenkey, repr) - l_w.append(DebugMergePoint(space, jit_hooks._cast_to_gcref(op), + l_w.append(DebugMergePoint(space, name, logops.repr_of_resop(op), jd_sd.jitdriver.name, op.getarg(1).getint(), op.getarg(2).getint(), w_greenkey)) else: - l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs, - logops.repr_of_resop(op))) + l_w.append(WrappedOp(name, ofs, logops.repr_of_resop(op))) return l_w +@unwrap_spec(offset=int, repr=str, name=str) +def descr_new_resop(space, w_tp, name, offset=-1, repr=''): + return WrappedOp(name, offset, repr) -class WrappedBox(W_Root): - """ A class representing a single box - """ - def __init__(self, llbox): - self.llbox = llbox - - def descr_getint(self, space): - if not jit_hooks.box_isint(self.llbox): - raise OperationError(space.w_NotImplementedError, - space.wrap("Box has no int value")) - return space.wrap(jit_hooks.box_getint(self.llbox)) - -@unwrap_spec(no=int) -def descr_new_box(space, w_tp, no): - return WrappedBox(jit_hooks.boxint_new(no)) - -WrappedBox.typedef = TypeDef( - 'Box', - __new__ = interp2app(descr_new_box), - getint = interp2app(WrappedBox.descr_getint), -) - -@unwrap_spec(num=int, offset=int, repr=str, w_res=W_Root) -def descr_new_resop(space, w_tp, num, w_args, w_res, offset=-1, - repr=''): - args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in - space.listview(w_args)] - if space.is_none(w_res): - llres = jit_hooks.emptyval() - else: - if not isinstance(w_res, WrappedBox): - raise OperationError(space.w_TypeError, space.wrap( - "expected box type, got %s" % space.type(w_res))) - llres = w_res.llbox - return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr) - -@unwrap_spec(repr=str, jd_name=str, call_depth=int, call_id=int) -def descr_new_dmp(space, w_tp, w_args, repr, jd_name, call_depth, call_id, +@unwrap_spec(repr=str, name=str, jd_name=str, call_depth=int, call_id=int) +def descr_new_dmp(space, w_tp, name, repr, jd_name, call_depth, call_id, w_greenkey): - args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in - space.listview(w_args)] - num = rop.DEBUG_MERGE_POINT - return DebugMergePoint(space, - jit_hooks.resop_new(num, args, jit_hooks.emptyval()), + return DebugMergePoint(space, name, repr, jd_name, call_depth, call_id, w_greenkey) class WrappedOp(W_Root): """ A class representing a single ResOperation, wrapped nicely """ - def __init__(self, op, offset, repr_of_resop): - self.op = op + def __init__(self, name, offset, repr_of_resop): self.offset = offset + self.name = name self.repr_of_resop = repr_of_resop def descr_repr(self, space): return space.wrap(self.repr_of_resop) - def descr_num(self, space): - return space.wrap(jit_hooks.resop_getopnum(self.op)) - def descr_name(self, space): - return space.wrap(hlstr(jit_hooks.resop_getopname(self.op))) - - @unwrap_spec(no=int) - def descr_getarg(self, space, no): - try: - box = jit_hooks.resop_getarg(self.op, no) - except IndexError: - raise OperationError(space.w_IndexError, - space.wrap("Index out of range")) - return WrappedBox(box) - - @unwrap_spec(no=int, w_box=WrappedBox) - def descr_setarg(self, space, no, w_box): - jit_hooks.resop_setarg(self.op, no, w_box.llbox) - - def descr_getresult(self, space): - return WrappedBox(jit_hooks.resop_getresult(self.op)) - - def descr_setresult(self, space, w_box): - box = space.interp_w(WrappedBox, w_box) - jit_hooks.resop_setresult(self.op, box.llbox) + return space.wrap(self.name) class DebugMergePoint(WrappedOp): """ A class representing Debug Merge Point - the entry point to a jitted loop. """ - def __init__(self, space, op, repr_of_resop, jd_name, call_depth, call_id, - w_greenkey): + def __init__(self, space, name, repr_of_resop, jd_name, call_depth, + call_id, w_greenkey): - WrappedOp.__init__(self, op, -1, repr_of_resop) + WrappedOp.__init__(self, name, -1, repr_of_resop) self.jd_name = jd_name self.call_depth = call_depth self.call_id = call_id @@ -237,12 +165,7 @@ __doc__ = WrappedOp.__doc__, __new__ = interp2app(descr_new_resop), __repr__ = interp2app(WrappedOp.descr_repr), - num = GetSetProperty(WrappedOp.descr_num), name = GetSetProperty(WrappedOp.descr_name), - getarg = interp2app(WrappedOp.descr_getarg), - setarg = interp2app(WrappedOp.descr_setarg), - result = GetSetProperty(WrappedOp.descr_getresult, - WrappedOp.descr_setresult), offset = interp_attrproperty("offset", cls=WrappedOp), ) WrappedOp.typedef.acceptable_as_base_class = False @@ -278,14 +201,18 @@ asmaddr = 0 asmlen = 0 - def __init__(self, space, debug_info, is_bridge=False): - logops = debug_info.logger._make_log_operations() - if debug_info.asminfo is not None: - ofs = debug_info.asminfo.ops_offset + def __init__(self, space, debug_info, is_bridge=False, wrap_ops=True): + if wrap_ops: + memo = {} + logops = debug_info.logger._make_log_operations(memo) + if debug_info.asminfo is not None: + ofs = debug_info.asminfo.ops_offset + else: + ofs = {} + ops = debug_info.operations + self.w_ops = space.newlist(wrap_oplist(space, logops, ops, ofs)) else: - ofs = {} - self.w_ops = space.newlist( - wrap_oplist(space, logops, debug_info.operations, ofs)) + self.w_ops = space.w_None self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py --- a/pypy/module/pypyjit/test/test_jit_hook.py +++ b/pypy/module/pypyjit/test/test_jit_hook.py @@ -136,7 +136,6 @@ assert dmp.call_id == 0 assert dmp.offset == -1 assert int_add.name == 'int_add' - assert int_add.num == self.int_add_num assert int_add.offset == 0 self.on_compile_bridge() expected = ('<JitLoopInfo pypyjit, 4 operations, starting at ' @@ -173,10 +172,7 @@ self.on_compile() loop = loops[0] op = loop.operations[2] - # Should not crash the interpreter - raises(IndexError, op.getarg, 2) assert op.name == 'guard_nonnull' - raises(NotImplementedError, op.getarg(0).getint) def test_non_reentrant(self): import pypyjit @@ -234,35 +230,28 @@ assert l == ['pypyjit'] def test_creation(self): - from pypyjit import Box, ResOperation + from pypyjit import ResOperation - op = ResOperation(self.int_add_num, [Box(1), Box(3)], Box(4)) - assert op.num == self.int_add_num + op = ResOperation("int_add", -1, "int_add(1, 2)") assert op.name == 'int_add' - box = op.getarg(0) - assert box.getint() == 1 - box2 = op.result - assert box2.getint() == 4 - op.setarg(0, box2) - assert op.getarg(0).getint() == 4 - op.result = box - assert op.result.getint() == 1 + assert repr(op) == "int_add(1, 2)" def test_creation_dmp(self): - from pypyjit import DebugMergePoint, Box + from pypyjit import DebugMergePoint def f(): pass - op = DebugMergePoint([Box(0)], 'repr', 'pypyjit', 2, 3, (f.func_code, 0, 0)) + op = DebugMergePoint("debug_merge_point", 'repr', 'pypyjit', 2, 3, (f.func_code, 0, 0)) assert op.bytecode_no == 0 assert op.pycode is f.func_code assert repr(op) == 'repr' assert op.jitdriver_name == 'pypyjit' - assert op.num == self.dmp_num + assert op.name == 'debug_merge_point' assert op.call_depth == 2 assert op.call_id == 3 - op = DebugMergePoint([Box(0)], 'repr', 'notmain', 5, 4, ('str',)) + op = DebugMergePoint('debug_merge_point', 'repr', 'notmain', + 5, 4, ('str',)) raises(AttributeError, 'op.pycode') assert op.call_depth == 5 diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py --- a/pypy/module/pypyjit/test_pypy_c/test_containers.py +++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py @@ -43,9 +43,9 @@ # can't change ;) assert loop.match_by_id("getitem", """ ... - i26 = call(ConstClass(ll_call_lookup_function), p18, p6, i25, 0, descr=...) + i26 = call_i(ConstClass(ll_call_lookup_function), p18, p6, i25, 0, descr=...) ... - p33 = getinteriorfield_gc(p31, i26, descr=<InteriorFieldDescr <FieldP odictentry.value .*>>) + p33 = getinteriorfield_gc_r(p31, i26, descr=<InteriorFieldDescr <FieldP odictentry.value .*>>) ... """) @@ -64,9 +64,9 @@ i8 = int_lt(i5, i7) guard_true(i8, descr=...) guard_not_invalidated(descr=...) - p10 = call(ConstClass(ll_str__IntegerR_SignedConst_Signed), i5, descr=<Callr . i EF=3>) + p10 = call_r(ConstClass(ll_str__IntegerR_SignedConst_Signed), i5, descr=<Callr . i EF=3>) guard_no_exception(descr=...) - i12 = call(ConstClass(ll_strhash), p10, descr=<Calli . r EF=0>) + i12 = call_i(ConstClass(ll_strhash), p10, descr=<Calli . r EF=0>) p13 = new(descr=...) p15 = new_array_clear(16, descr=<ArrayU 1>) {{{ @@ -74,25 +74,25 @@ setfield_gc(p13, p15, descr=<FieldP dicttable.indexes .+>) setfield_gc(p13, ConstPtr(0), descr=<FieldP dicttable.entries .+>) }}} - i17 = call(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, 1, descr=<Calli . rrii EF=5 OS=4>) + i17 = call_i(ConstClass(ll_dict_lookup_trampoline), p13, p10, i12, 1, descr=<Calli . rrii EF=5 OS=4>) {{{ setfield_gc(p13, 0, descr=<FieldS dicttable.lookup_function_no .+>) setfield_gc(p13, 0, descr=<FieldS dicttable.num_live_items .+>) setfield_gc(p13, 32, descr=<FieldS dicttable.resize_counter .+>) }}} guard_no_exception(descr=...) - p20 = new_with_vtable(ConstClass(W_IntObject)) - call(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13, p10, p20, i12, i17, descr=<Callv 0 rrrii EF=5>) + p20 = new_with_vtable(descr=...) + call_n(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13, p10, p20, i12, i17, descr=<Callv 0 rrrii EF=5>) setfield_gc(p20, i5, descr=<FieldS .*W_IntObject.inst_intval .*>) guard_no_exception(descr=...) - i23 = call(ConstClass(ll_call_lookup_function), p13, p10, i12, 0, descr=<Calli . rrii EF=5 OS=4>) + i23 = call_i(ConstClass(ll_call_lookup_function), p13, p10, i12, 0, descr=<Calli . rrii EF=5 OS=4>) guard_no_exception(descr=...) i27 = int_lt(i23, 0) guard_false(i27, descr=...) - p28 = getfield_gc(p13, descr=<FieldP dicttable.entries .*>) - p29 = getinteriorfield_gc(p28, i23, descr=<InteriorFieldDescr <FieldP odictentry.value .*>>) + p28 = getfield_gc_r(p13, descr=<FieldP dicttable.entries .*>) + p29 = getinteriorfield_gc_r(p28, i23, descr=<InteriorFieldDescr <FieldP odictentry.value .*>>) guard_nonnull_class(p29, ConstClass(W_IntObject), descr=...) - i31 = getfield_gc_pure(p29, descr=<FieldS .*W_IntObject.inst_intval .*>) + i31 = getfield_gc_pure_i(p29, descr=<FieldS .*W_IntObject.inst_intval .*>) i32 = int_sub_ovf(i31, i5) guard_no_overflow(descr=...) i34 = int_add_ovf(i32, 1) diff --git a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py --- a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py +++ b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py @@ -31,7 +31,7 @@ # but all calls can be special-cased by the backend if # supported. On 64-bit there is only the two calls to # read_timestamp. - r = re.compile(r" call[(]ConstClass[(](.+?)[)]") + r = re.compile(r" call_\w[(]ConstClass[(](.+?)[)]") calls = r.findall(repr(loop.ops_by_id(method))) if sys.maxint == 2147483647: assert len(calls) == 6 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 @@ -414,11 +414,7 @@ guard_not_invalidated(descr=...) p163 = force_token() p164 = force_token() - p165 = getarrayitem_gc(p67, 0, descr=<ArrayP .>) - guard_value(p165, ConstPtr(ptr70), descr=...) - p166 = getfield_gc(p165, descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy .+>) - guard_value(p166, ConstPtr(ptr72), descr=...) - p167 = call(ConstClass(_ll_0_alloc_with_del___), descr=<Callr . EF=5>) + p167 = call_r(ConstClass(_ll_0_alloc_with_del___), descr=<Callr . EF=5>) guard_no_exception(descr=...) i112 = int_signext(i160, 2) setfield_gc(p167, ConstPtr(ptr85), descr=<FieldP pypy.module._cffi_backend.cdataobj.W_CData.inst_ctype .+>) @@ -426,11 +422,11 @@ i114 = int_ne(i160, i112) guard_false(i114, descr=...) --TICK-- - i119 = call(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, descr=<Calli . i EF=5 OS=110>) + i123 = arraylen_gc(p67, descr=<ArrayP .>) + i119 = call_i(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, descr=<Calli . i EF=5 OS=110>) raw_store(i119, 0, i160, descr=<ArrayS 2>) raw_store(i119, 2, i160, descr=<ArrayS 2>) raw_store(i119, 4, i160, descr=<ArrayS 2>) setfield_gc(p167, i119, descr=<FieldU pypy.module._cffi_backend.cdataobj.W_CData.inst__ptr .+>) - i123 = arraylen_gc(p67, descr=<ArrayP .>) jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_generators.py b/pypy/module/pypyjit/test_pypy_c/test_generators.py --- a/pypy/module/pypyjit/test_pypy_c/test_generators.py +++ b/pypy/module/pypyjit/test_pypy_c/test_generators.py @@ -21,10 +21,10 @@ assert loop.match_by_id("generator", """ cond_call(..., descr=...) i16 = force_token() - p45 = new_with_vtable(ConstClass(W_IntObject)) + p45 = new_with_vtable(descr=<.*>) + ifoo = arraylen_gc(p8, descr=<ArrayP .*>) setfield_gc(p45, i29, descr=<FieldS .*>) setarrayitem_gc(p8, 0, p45, descr=<ArrayP .>) - i47 = arraylen_gc(p8, descr=<ArrayP .>) # Should be removed by backend jump(..., descr=...) """) assert loop.match_by_id("subtract", """ @@ -50,10 +50,10 @@ assert loop.match_by_id("generator", """ cond_call(..., descr=...) i16 = force_token() - p45 = new_with_vtable(ConstClass(W_IntObject)) + p45 = new_with_vtable(descr=<.*>) + i47 = arraylen_gc(p8, descr=<ArrayP .>) # Should be removed by backend setfield_gc(p45, i29, descr=<FieldS .*>) setarrayitem_gc(p8, 0, p45, descr=<ArrayP .>) - i47 = arraylen_gc(p8, descr=<ArrayP .>) # Should be removed by backend jump(..., descr=...) """) assert loop.match_by_id("subtract", """ diff --git a/pypy/module/pypyjit/test_pypy_c/test_globals.py b/pypy/module/pypyjit/test_pypy_c/test_globals.py --- a/pypy/module/pypyjit/test_pypy_c/test_globals.py +++ b/pypy/module/pypyjit/test_pypy_c/test_globals.py @@ -16,9 +16,9 @@ assert log.result == 500 loop, = log.loops_by_filename(self.filepath) assert loop.match_by_id("loadglobal", """ - p12 = getfield_gc(p10, descr=<FieldP .*W_DictMultiObject.inst_strategy .*>) + p12 = getfield_gc_r(p10, descr=<FieldP .*W_DictMultiObject.inst_strategy .*>) guard_value(p12, ConstPtr(ptr13), descr=...) guard_not_invalidated(descr=...) - p19 = getfield_gc(ConstPtr(p17), descr=<FieldP .*W_DictMultiObject.inst_strategy .*>) + p19 = getfield_gc_r(ConstPtr(p17), descr=<FieldP .*W_DictMultiObject.inst_strategy .*>) guard_value(p19, ConstPtr(ptr20), descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py --- a/pypy/module/pypyjit/test_pypy_c/test_instance.py +++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py @@ -106,7 +106,7 @@ entry_bridge, = log.loops_by_filename(self.filepath, is_entry_bridge=True) ops = entry_bridge.ops_by_id('mutate', opcode='LOAD_ATTR') assert log.opnames(ops) == ['guard_value', 'guard_not_invalidated', - 'getfield_gc'] + 'getfield_gc_i'] # the STORE_ATTR is folded away assert list(entry_bridge.ops_by_id('meth1', opcode='STORE_ATTR')) == [] # @@ -124,7 +124,7 @@ setfield_gc(ConstPtr(ptr39), i59, descr=...) i62 = int_lt(i61, 0) guard_false(i62, descr=...) - jump(p0, p1, p3, p6, p7, p12, i59, p18, i31, i59, descr=...) + jump(p0, p1, p3, p6, p7, p12, i59, p18, i31, i59, p100, descr=...) """) def test_mutate_class(self): @@ -154,8 +154,8 @@ entry_bridge, = log.loops_by_filename(self.filepath, is_entry_bridge=True) ops = entry_bridge.ops_by_id('mutate', opcode='LOAD_ATTR') assert log.opnames(ops) == ['guard_value', 'guard_not_invalidated', - 'getfield_gc', 'guard_nonnull_class', - 'getfield_gc', 'guard_value', # type check on the attribute + 'getfield_gc_r', 'guard_nonnull_class', + 'getfield_gc_r', 'guard_value', # type check on the attribute ] # the STORE_ATTR is folded away assert list(entry_bridge.ops_by_id('meth1', opcode='STORE_ATTR')) == [] @@ -167,7 +167,7 @@ i70 = int_lt(i58, i33) guard_true(i70, descr=...) guard_not_invalidated(descr=...) - p71 = getfield_gc(p64, descr=...) + p71 = getfield_gc_r(p64, descr=...) guard_value(p71, ConstPtr(ptr42), descr=...) p72 = force_token() p73 = force_token() @@ -175,7 +175,7 @@ i75 = getfield_raw_i(..., descr=...) i76 = int_lt(i75, 0) guard_false(i76, descr=...) - p77 = new_with_vtable(...) + p77 = new_with_vtable(descr=...) setfield_gc(p77, p64, descr=...) setfield_gc(p77, ConstPtr(null), descr=...) setfield_gc(p77, ConstPtr(null), descr=...) @@ -183,7 +183,7 @@ setfield_gc(p77, ConstPtr(null), descr=...) setfield_gc(p77, ConstPtr(ptr42), descr=...) setfield_gc(ConstPtr(ptr69), p77, descr=...) - jump(p0, p1, p3, p6, p7, p12, i74, p20, p26, i33, p77, descr=...) + jump(p0, p1, p3, p6, p7, p12, i74, p20, p26, i33, p77, p100, descr=...) """) @@ -209,11 +209,11 @@ assert loop.match_by_id('loadattr1', ''' guard_not_invalidated(descr=...) - i19 = call(ConstClass(ll_call_lookup_function), _, _, _, 0, descr=...) + i19 = call_i(ConstClass(ll_call_lookup_function), _, _, _, 0, descr=...) guard_no_exception(descr=...) i22 = int_lt(i19, 0) guard_true(i22, descr=...) - i26 = call(ConstClass(ll_call_lookup_function), _, _, _, 0, descr=...) + i26 = call_i(ConstClass(ll_call_lookup_function), _, _, _, 0, descr=...) guard_no_exception(descr=...) i29 = int_lt(i26, 0) guard_true(i29, descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py b/pypy/module/pypyjit/test_pypy_c/test_math.py --- a/pypy/module/pypyjit/test_pypy_c/test_math.py +++ b/pypy/module/pypyjit/test_pypy_c/test_math.py @@ -23,8 +23,8 @@ f1 = cast_int_to_float(i0) i3 = float_le(f1, 0.0) guard_false(i3, descr=...) - f2 = call(ConstClass(log), f1, descr=<Callf . f EF=2>) - f3 = call(ConstClass(log10), f1, descr=<Callf . f EF=2>) + f2 = call_f(ConstClass(log), f1, descr=<Callf . f EF=2>) + f3 = call_f(ConstClass(log10), f1, descr=<Callf . f EF=2>) f4 = float_sub(f2, f3) f5 = float_add(f0, f4) i4 = int_add(i0, 1) @@ -52,8 +52,8 @@ f1 = cast_int_to_float(i0) i6 = --ISINF--(f1) guard_false(i6, descr=...) - f2 = call(ConstClass(sin), f1, descr=<Callf . f EF=0>) - f3 = call(ConstClass(cos), f1, descr=<Callf . f EF=0>) + f2 = call_f(ConstClass(sin), f1, descr=<Callf . f EF=0>) + f3 = call_f(ConstClass(cos), f1, descr=<Callf . f EF=0>) f4 = float_sub(f2, f3) f5 = float_add(f0, f4) i7 = int_add(i0, 1) diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py --- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py +++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py @@ -101,39 +101,39 @@ loop = log._filter(log.loops[0]) assert loop.match(""" guard_class(p1, #, descr=...) - p4 = getfield_gc_pure(p1, descr=<FieldP pypy.module.micronumpy.iterators.ArrayIter.inst_array \d+>) - i5 = getfield_gc(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) - p6 = getfield_gc_pure(p4, descr=<FieldP pypy.module.micronumpy.concrete.BaseConcreteArray.inst_dtype \d+>) - p7 = getfield_gc_pure(p6, descr=<FieldP pypy.module.micronumpy.descriptor.W_Dtype.inst_itemtype \d+>) + p4 = getfield_gc_pure_r(p1, descr=<FieldP pypy.module.micronumpy.iterators.ArrayIter.inst_array \d+>) + i5 = getfield_gc_i(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) + p6 = getfield_gc_pure_r(p4, descr=<FieldP pypy.module.micronumpy.concrete.BaseConcreteArray.inst_dtype \d+>) + p7 = getfield_gc_pure_r(p6, descr=<FieldP pypy.module.micronumpy.descriptor.W_Dtype.inst_itemtype \d+>) guard_class(p7, ConstClass(Float64), descr=...) - i9 = getfield_gc_pure(p4, descr=<FieldU pypy.module.micronumpy.concrete.BaseConcreteArray.inst_storage \d+>) - i10 = getfield_gc_pure(p6, descr=<FieldU pypy.module.micronumpy.descriptor.W_Dtype.inst_byteorder \d+>) + i9 = getfield_gc_pure_i(p4, descr=<FieldU pypy.module.micronumpy.concrete.BaseConcreteArray.inst_storage \d+>) + i10 = getfield_gc_pure_i(p6, descr=<FieldU pypy.module.micronumpy.descriptor.W_Dtype.inst_byteorder \d+>) i12 = int_eq(i10, 61) i14 = int_eq(i10, 60) i15 = int_or(i12, i14) - f16 = raw_load(i9, i5, descr=<ArrayF \d+>) + f16 = raw_load_f(i9, i5, descr=<ArrayF \d+>) guard_true(i15, descr=...) guard_not_invalidated(descr=...) i18 = float_ne(f16, 0.000000) guard_true(i18, descr=...) guard_nonnull_class(p2, ConstClass(W_BoolBox), descr=...) - i20 = getfield_gc_pure(p2, descr=<FieldU pypy.module.micronumpy.boxes.W_BoolBox.inst_value \d+>) + i20 = getfield_gc_pure_i(p2, descr=<FieldU pypy.module.micronumpy.boxes.W_BoolBox.inst_value \d+>) i21 = int_is_true(i20) guard_false(i21, descr=...) - i22 = getfield_gc(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) - i23 = getfield_gc_pure(p1, descr=<FieldU pypy.module.micronumpy.iterators.ArrayIter.inst_track_index \d+>) + i22 = getfield_gc_i(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) + i23 = getfield_gc_pure_i(p1, descr=<FieldU pypy.module.micronumpy.iterators.ArrayIter.inst_track_index \d+>) guard_true(i23, descr=...) i25 = int_add(i22, 1) - p26 = getfield_gc_pure(p0, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) - i27 = getfield_gc_pure(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_contiguous \d+>) + p26 = getfield_gc_pure_r(p0, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) + i27 = getfield_gc_pure_i(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_contiguous \d+>) i28 = int_is_true(i27) guard_true(i28, descr=...) - i29 = getfield_gc_pure(p6, descr=<FieldS pypy.module.micronumpy.descriptor.W_Dtype.inst_elsize \d+>) + i29 = getfield_gc_pure_i(p6, descr=<FieldS pypy.module.micronumpy.descriptor.W_Dtype.inst_elsize \d+>) i30 = int_add(i5, i29) - i31 = getfield_gc_pure(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_size \d+>) + i31 = getfield_gc_pure_i(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_size \d+>) i32 = int_ge(i25, i31) guard_false(i32, descr=...) - p34 = new_with_vtable(#) + p34 = new_with_vtable(descr=...) {{{ setfield_gc(p34, p1, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst_iterator \d+>) setfield_gc(p34, i25, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) @@ -154,13 +154,13 @@ assert len(log.loops) == 1 loop = log._filter(log.loops[0]) assert loop.match(""" - f31 = raw_load(i9, i29, descr=<ArrayF 8>) + f31 = raw_load_f(i9, i29, descr=<ArrayF 8>) guard_not_invalidated(descr=...) i32 = float_ne(f31, 0.000000) guard_true(i32, descr=...) - i34 = getarrayitem_raw(#, #, descr=<ArrayU 1>) # XXX what are these? + i34 = getarrayitem_raw_i(#, #, descr=<ArrayU 1>) # XXX what are these? guard_value(i34, #, descr=...) # XXX don't appear in - i35 = getarrayitem_raw(#, #, descr=<ArrayU 1>) # XXX equiv test_zjit + i35 = getarrayitem_raw_i(#, #, descr=<ArrayU 1>) # XXX equiv test_zjit i36 = int_add(i24, 1) i37 = int_add(i29, 8) i38 = int_ge(i36, i30) @@ -198,7 +198,7 @@ i78 = int_mul(i71, i61) i79 = int_add(i55, i78) """ + alignment_check + """ - f80 = raw_load(i67, i79, descr=<ArrayF 8>) + f80 = raw_load_f(i67, i79, descr=<ArrayF 8>) i81 = int_add(i71, 1) --TICK-- jump(..., descr=...) @@ -235,12 +235,12 @@ i83 = int_mul(i76, i64) i84 = int_add(i58, i83) """ + alignment_check + """ - f85 = raw_load(i70, i84, descr=<ArrayF 8>) + f85 = raw_load_f(i70, i84, descr=<ArrayF 8>) guard_not_invalidated(descr=...) f86 = float_add(f74, f85) i87 = int_add(i76, 1) --TICK-- - jump(p0, p1, p6, p7, p8, p11, p13, f86, p17, i87, i62, p42, i58, p48, i41, i64, i70, descr=...) + jump(..., descr=...) """) def test_array_flatiter_next(self): @@ -262,7 +262,7 @@ guard_not_invalidated(descr=...) i88 = int_ge(i87, i59) guard_false(i88, descr=...) - f90 = raw_load(i67, i89, descr=<ArrayF 8>) + f90 = raw_load_f(i67, i89, descr=<ArrayF 8>) i91 = int_add(i87, 1) i93 = int_add(i89, 8) i94 = int_add(i79, 1) @@ -294,11 +294,11 @@ guard_true(i126, descr=...) i128 = int_mul(i117, i59) i129 = int_add(i55, i128) - f149 = raw_load(i100, i129, descr=<ArrayF 8>) + f149 = raw_load_f(i100, i129, descr=<ArrayF 8>) i151 = int_add(i117, 1) + setfield_gc(p156, i55, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset .+>) setarrayitem_gc(p150, 1, 0, descr=<ArrayS .+>) setarrayitem_gc(p150, 0, 0, descr=<ArrayS .+>) - setfield_gc(p156, i55, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset .+>) --TICK-- jump(..., descr=...) """) @@ -327,9 +327,9 @@ raw_store(i103, i132, 42.000000, descr=<ArrayF 8>) i153 = int_add(i120, 1) i154 = getfield_raw_i(#, descr=<FieldS pypysig_long_struct.c_value 0>) + setfield_gc(p158, i53, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset .+>) setarrayitem_gc(p152, 1, 0, descr=<ArrayS .+>) setarrayitem_gc(p152, 0, 0, descr=<ArrayS .+>) - setfield_gc(p158, i53, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset .+>) i157 = int_lt(i154, 0) guard_false(i157, descr=...) jump(..., descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py --- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py +++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py @@ -38,7 +38,7 @@ loop, = log.loops_by_filename(self.filepath) assert loop.match(""" ... - p76 = call_assembler(_, _, _, _, descr=...) + p76 = call_assembler_r(_, _, _, _, descr=...) ... """) loop2 = log.loops[0] @@ -50,11 +50,11 @@ guard_not_invalidated? i17 = int_ge(i11, i7) guard_false(i17, descr=...) - p18 = getarrayitem_gc(p5, i11, descr=...) + p18 = getarrayitem_gc_r(p5, i11, descr=...) i19 = int_add(i11, 1) setfield_gc(p2, i19, descr=...) guard_nonnull_class(p18, ConstClass(W_IntObject), descr=...) - i20 = getfield_gc_pure(p18, descr=...) + i20 = getfield_gc_pure_i(p18, descr=...) i21 = int_gt(i20, i14) guard_true(i21, descr=...) jump(..., descr=...) @@ -79,6 +79,6 @@ assert len(guards) < 20 assert loop.match(""" ... - p76 = call_assembler(_, _, _, _, descr=...) + p76 = call_assembler_r(_, _, _, _, descr=...) ... """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -65,7 +65,7 @@ assert loop.match(""" i7 = int_gt(i4, 1) guard_true(i7, descr=...) - p11 = call(ConstClass(rbigint.int_mul), p5, i4, descr=...) + p11 = call_r(ConstClass(rbigint.int_mul), p5, i4, descr=...) guard_no_exception(descr=...) i13 = int_sub(i4, 1) --TICK-- @@ -113,14 +113,14 @@ i12 = int_is_true(i4) guard_true(i12, descr=...) guard_not_invalidated(descr=...) - i13 = int_add_ovf(i8, i9) - guard_no_overflow(descr=...) - i10p = getfield_gc_pure(p10, descr=...) + i10p = getfield_gc_pure_i(p10, descr=...) i10 = int_mul_ovf(2, i10p) guard_no_overflow(descr=...) i14 = int_add_ovf(i13, i10) guard_no_overflow(descr=...) - setfield_gc(p7, p11, descr=...) + i13 = int_add_ovf(i14, i9) + guard_no_overflow(descr=...) + setfield_gc(p17, p10, descr=...) i17 = int_sub_ovf(i4, 1) guard_no_overflow(descr=...) --TICK-- @@ -148,6 +148,7 @@ i18 = force_token() setfield_gc(p9, i17, descr=<.* .*W_XRangeIterator.inst_current .*>) guard_not_invalidated(descr=...) + i84 = int_sub(i14, 1) i21 = int_lt(i10, 0) guard_false(i21, descr=...) i22 = int_lt(i10, i14) @@ -180,6 +181,7 @@ i21 = force_token() setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>) guard_not_invalidated? + i88 = int_sub(i9, 1) i25 = int_ge(i11, i9) guard_false(i25, descr=...) i27 = int_add_ovf(i7, i11) @@ -212,6 +214,7 @@ i21 = force_token() setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>) guard_not_invalidated? + i95 = int_sub(i9, 1) i23 = int_lt(i18, 0) guard_false(i23, descr=...) i25 = int_ge(i18, i9) @@ -260,25 +263,24 @@ loop, = log.loops_by_filename(self.filepath) assert loop.match(""" guard_not_invalidated? - i14 = getfield_gc(p12, descr=<FieldS list.length .*>) i16 = uint_ge(i12, i14) guard_false(i16, descr=...) - p16 = getfield_gc(p12, descr=<FieldP list.items .*>) - p17 = getarrayitem_gc(p16, i12, descr=<ArrayP .>) + p17 = getarrayitem_gc_r(p16, i12, descr=<ArrayP .>) i19 = int_add(i12, 1) setfield_gc(p9, i19, descr=<FieldS .*W_AbstractSeqIterObject.inst_index .*>) guard_nonnull_class(p17, ..., descr=...) guard_not_invalidated? - i21 = getfield_gc(p17, descr=<FieldS .*W_Array.*.inst_len .*>) + i21 = getfield_gc_i(p17, descr=<FieldS .*W_Array.*.inst_len .*>) i23 = int_lt(0, i21) guard_true(i23, descr=...) - i24 = getfield_gc(p17, descr=<FieldU .*W_ArrayTypei.inst_buffer .*>) - i25 = getarrayitem_raw(i24, 0, descr=<.*>) + i24 = getfield_gc_i(p17, descr=<FieldU .*W_ArrayTypei.inst_buffer .*>) + i25 = getarrayitem_raw_i(i24, 0, descr=<.*>) i27 = int_lt(1, i21) guard_false(i27, descr=...) i28 = int_add_ovf(i10, i25) guard_no_overflow(descr=...) --TICK-- + if00 = arraylen_gc(p16, descr=...) jump(..., descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -43,9 +43,9 @@ i25 = unicodegetitem(p13, i19) p27 = newstr(1) strsetitem(p27, 0, i23) - p30 = call(ConstClass(ll_str2unicode__rpy_stringPtr), p27, descr=...) + p30 = call_r(ConstClass(ll_str2unicode__rpy_stringPtr), p27, descr=...) guard_no_exception(descr=...) - i32 = call(ConstClass(_ll_2_str_eq_checknull_char__rpy_unicodePtr_UniChar), p30, i25, descr=...) + i32 = call_i(ConstClass(_ll_2_str_eq_checknull_char__rpy_unicodePtr_UniChar), p30, i25, descr=...) guard_true(i32, descr=...) i34 = int_add(i6, 1) --TICK-- @@ -80,12 +80,12 @@ i23 = strgetitem(p10, i19) p25 = newstr(1) strsetitem(p25, 0, i23) - p93 = call(ConstClass(fromstr), p25, 16, descr=<Callr . ri EF=4>) + p93 = call_r(ConstClass(fromstr), p25, 16, descr=<Callr . ri EF=4>) guard_no_exception(descr=...) - i95 = getfield_gc_pure(p93, descr=<FieldS rpython.rlib.rbigint.rbigint.inst_size .*>) + i95 = getfield_gc_pure_i(p93, descr=<FieldS rpython.rlib.rbigint.rbigint.inst_size .*>) i96 = int_gt(i95, #) guard_false(i96, descr=...) - i94 = call(ConstClass(rbigint._toint_helper), p93, descr=<Calli . r EF=4>) + i94 = call_i(ConstClass(rbigint._toint_helper), p93, descr=<Calli . r EF=4>) guard_no_exception(descr=...) i95 = int_add_ovf(i6, i94) guard_no_overflow(descr=...) @@ -108,7 +108,7 @@ i79 = int_gt(i74, 0) guard_true(i79, descr=...) guard_not_invalidated(descr=...) - p80 = call(ConstClass(ll_int2dec__Signed), i74, descr=<Callr . i EF=3>) + p80 = call_r(ConstClass(ll_int2dec__Signed), i74, descr=<Callr . i EF=3>) guard_no_exception(descr=...) i85 = strlen(p80) p86 = new(descr=<SizeDescr .+>) @@ -119,21 +119,21 @@ setfield_gc(p86, 23, descr=<FieldS stringbuilder.current_end .+>) setfield_gc(p86, 23, descr=<FieldS stringbuilder.total_size .+>) }}} - call(ConstClass(ll_append_res0__stringbuilderPtr_rpy_stringPtr), p86, p80, descr=<Callv 0 rr EF=5>) + call_n(ConstClass(ll_append_res0__stringbuilderPtr_rpy_stringPtr), p86, p80, descr=<Callv 0 rr EF=5>) guard_no_exception(descr=...) - i89 = getfield_gc(p86, descr=<FieldS stringbuilder.current_pos .+>) - i90 = getfield_gc(p86, descr=<FieldS stringbuilder.current_end .+>) + i89 = getfield_gc_i(p86, descr=<FieldS stringbuilder.current_pos .+>) + i90 = getfield_gc_i(p86, descr=<FieldS stringbuilder.current_end .+>) i91 = int_eq(i89, i90) cond_call(i91, ConstClass(ll_grow_by__stringbuilderPtr_Signed), p86, 1, descr=<Callv 0 ri EF=5>) guard_no_exception(descr=...) - i92 = getfield_gc(p86, descr=<FieldS stringbuilder.current_pos .+>) + i92 = getfield_gc_i(p86, descr=<FieldS stringbuilder.current_pos .+>) i93 = int_add(i92, 1) - p94 = getfield_gc(p86, descr=<FieldP stringbuilder.current_buf .+>) + p94 = getfield_gc_r(p86, descr=<FieldP stringbuilder.current_buf .+>) strsetitem(p94, i92, 32) setfield_gc(p86, i93, descr=<FieldS stringbuilder.current_pos .+>) - call(ConstClass(ll_append_res0__stringbuilderPtr_rpy_stringPtr), p86, p80, descr=<Callv 0 rr EF=5>) + call_n(ConstClass(ll_append_res0__stringbuilderPtr_rpy_stringPtr), p86, p80, descr=<Callv 0 rr EF=5>) guard_no_exception(descr=...) - p95 = call(..., descr=<Callr . r EF=5>) # ll_build + p95 = call_r(..., descr=<Callr . r EF=5>) # ll_build guard_no_exception(descr=...) i96 = strlen(p95) i97 = int_add_ovf(i71, i96) @@ -176,7 +176,7 @@ strsetitem(p35, 3, 104) strsetitem(p35, 4, 95) copystrcontent(p31, p35, 0, 5, i32) - i49 = call(ConstClass(_ll_2_str_eq_nonnull__rpy_stringPtr_rpy_stringPtr), p35, ConstPtr(ptr48), descr=<Calli [48] rr EF=0 OS=28>) + i49 = call_i(ConstClass(_ll_2_str_eq_nonnull__rpy_stringPtr_rpy_stringPtr), p35, ConstPtr(ptr48), descr=<Calli [48] rr EF=0 OS=28>) guard_value(i49, 1, descr=...) ''') @@ -195,7 +195,7 @@ loops = log.loops_by_filename(self.filepath) loop, = loops assert loop.match_by_id('callone', ''' - p114 = call(ConstClass(ll_lower__rpy_stringPtr), p113, descr=<Callr . r EF=3>) + p114 = call_r(ConstClass(ll_lower__rpy_stringPtr), p113, descr=<Callr . r EF=3>) guard_no_exception(descr=...) ''') assert loop.match_by_id('calltwo', '') # nothing @@ -248,9 +248,9 @@ i50 = int_add(i47, 1) setfield_gc(p15, i50, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current 8>) guard_not_invalidated(descr=...) - p80 = call(ConstClass(ll_str__IntegerR_SignedConst_Signed), i47, descr=<Callr . i EF=3>) + p80 = call_r(ConstClass(ll_str__IntegerR_SignedConst_Signed), i47, descr=<Callr . i EF=3>) guard_no_exception(descr=...) - p53 = call(ConstClass(fast_str_decode_ascii), p80, descr=<Callr . r EF=4>) + p53 = call_r(ConstClass(fast_str_decode_ascii), p80, descr=<Callr . r EF=4>) guard_no_exception(descr=...) guard_nonnull(p53, descr=...) --TICK-- diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py --- a/pypy/module/pypyjit/test_pypy_c/test_thread.py +++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py @@ -64,11 +64,11 @@ guard_true(i56, descr=...) p57 = force_token() setfield_gc(p0, p57, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 8>) - i58 = call_release_gil(0, _, i37, 1, descr=<Calli 4 ii EF=7>) + i58 = call_release_gil_i(0, _, i37, 1, descr=<Calli 4 ii EF=7>) guard_not_forced(descr=...) guard_no_exception(descr=...) i58 = int_sub(i44, 1) - i59 = call(ConstClass(RPyThreadReleaseLock), i37, descr=<Calli . i EF=2>) + i59 = call_i(ConstClass(RPyThreadReleaseLock), i37, descr=<Calli . i EF=2>) i60 = int_is_true(i59) guard_false(i60, descr=...) guard_not_invalidated(descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_weakref.py b/pypy/module/pypyjit/test_pypy_c/test_weakref.py --- a/pypy/module/pypyjit/test_pypy_c/test_weakref.py +++ b/pypy/module/pypyjit/test_pypy_c/test_weakref.py @@ -19,23 +19,23 @@ """, [500]) loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i58 = getfield_gc(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current .>) + i58 = getfield_gc_i(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current .>) i60 = int_lt(i58, i31) guard_true(i60, descr=...) i61 = int_add(i58, 1) - p62 = getfield_gc(ConstPtr(ptr37), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) + p62 = getfield_gc_r(ConstPtr(ptr37), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) setfield_gc(p18, i61, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current 8>) guard_value(p62, ConstPtr(ptr39), descr=...) guard_not_invalidated(descr=...) - p64 = getfield_gc(ConstPtr(ptr40), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) + p64 = getfield_gc_r(ConstPtr(ptr40), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) guard_value(p64, ConstPtr(ptr42), descr=...) - p65 = getfield_gc(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst_map \d+>) + p65 = getfield_gc_r(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst_map \d+>) guard_value(p65, ConstPtr(ptr45), descr=...) - p66 = getfield_gc(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst__value0 \d+>) + p66 = getfield_gc_r(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst__value0 \d+>) guard_nonnull_class(p66, ..., descr=...) p67 = force_token() setfield_gc(p0, p67, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token \d+>) - p68 = call_may_force(ConstClass(WeakrefLifelineWithCallbacks.make_weakref_with_callback), p66, ConstPtr(ptr50), p14, ConstPtr(ptr51), descr=<Callr \d rrrr EF=7>) + p68 = call_may_force_r(ConstClass(WeakrefLifelineWithCallbacks.make_weakref_with_callback), p66, ConstPtr(ptr50), p14, ConstPtr(ptr51), descr=<Callr \d rrrr EF=7>) guard_not_forced(descr=...) guard_no_exception(descr=...) guard_nonnull_class(p68, ..., descr=...) diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -123,23 +123,26 @@ self.sig_recvd = True old_handler = signal.signal(signal.SIGUSR1, my_handler) try: + ready = thread.allocate_lock() + ready.acquire() def other_thread(): # Acquire the lock in a non-main thread, so this test works for # RLocks. lock.acquire() - # Wait until the main thread is blocked in the lock acquire, and - # then wake it up with this. - time.sleep(0.5) + # Notify the main thread that we're ready + ready.release() + # Wait for 5 seconds here + for n in range(50): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit