Author: Maciej Fijalkowski <fij...@gmail.com> Branch: share-guard-info Changeset: r79867:303ed67a871d Date: 2015-09-27 18:03 +0200 http://bitbucket.org/pypy/pypy/changeset/303ed67a871d/
Log: merge default diff too long, truncating to 2000 out of 3974 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/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 @@ -21,3 +21,15 @@ .. 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 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/_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/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( 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,6 @@ from pypy.interpreter.error import OperationError, oefmt from rpython.rlib import jit, rgc +from rpython.rlib.rarithmetic import ovfcheck 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, \ @@ -409,6 +410,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 +430,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 +459,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 +547,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 +572,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 @@ -153,7 +153,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 +213,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/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, @@ -1405,9 +1407,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,13 +32,19 @@ 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: try: i = ovfcheck(i * x) except OverflowError: raise 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_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 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_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 @@ -422,11 +422,11 @@ i114 = int_ne(i160, i112) guard_false(i114, descr=...) --TICK-- + 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_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 @@ -47,7 +47,7 @@ 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,7 +154,7 @@ 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): 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 @@ -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) diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -385,7 +385,8 @@ class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeCodePoint)): def union((uchr1, uchr2)): - return SomeUnicodeCodePoint() + no_nul = uchr1.no_nul and uchr2.no_nul + return SomeUnicodeCodePoint(no_nul=no_nul) def add((chr1, chr2)): return SomeUnicodeString() @@ -598,32 +599,33 @@ class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): - return SomeUnicodeCodePoint() + return SomeUnicodeCodePoint(no_nul=str1.no_nul) getitem.can_only_throw = [] def getitem_idx((str1, int2)): - return SomeUnicodeCodePoint() + return SomeUnicodeCodePoint(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] def mul((str1, int2)): # xxx do we want to support this - return SomeUnicodeString() + return SomeUnicodeString(no_nul=str1.no_nul) class __extend__(pairtype(SomeInteger, SomeString), pairtype(SomeInteger, SomeUnicodeString)): def mul((int1, str2)): # xxx do we want to support this - return str2.basestringclass() + return str2.basestringclass(no_nul=str2.no_nul) class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeString), pairtype(SomeUnicodeString, SomeUnicodeCodePoint), pairtype(SomeUnicodeString, SomeUnicodeString)): def union((str1, str2)): - return SomeUnicodeString(can_be_None=str1.can_be_none() or - str2.can_be_none()) + can_be_None = str1.can_be_None or str2.can_be_None + no_nul = str1.no_nul and str2.no_nul + return SomeUnicodeString(can_be_None=can_be_None, no_nul=no_nul) def add((str1, str2)): # propagate const-ness to help getattr(obj, 'prefix' + const_name) - result = SomeUnicodeString() + result = SomeUnicodeString(no_nul=str1.no_nul and str2.no_nul) if str1.is_immutable_constant() and str2.is_immutable_constant(): result.const = str1.const + str2.const return result diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -237,10 +237,11 @@ else: result = SomeString(no_nul=no_nul) elif tp is unicode: + no_nul = not u'\x00' in x if len(x) == 1: - result = SomeUnicodeCodePoint() + result = SomeUnicodeCodePoint(no_nul=no_nul) else: - result = SomeUnicodeString() + result = SomeUnicodeString(no_nul=no_nul) elif tp is bytearray: result = SomeByteArray() elif tp is tuple: diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -438,6 +438,18 @@ assert s.knowntype == str assert s.no_nul + def test_unicode_join(self): + a = self.RPythonAnnotator() + def g(n): + if n: + return [u"foo", u"bar"] + def f(n): + g(0) + return u''.join(g(n)) + s = a.build_types(f, [int]) + assert s.knowntype == unicode + assert s.no_nul + def test_str_split(self): a = self.RPythonAnnotator() def g(n): @@ -451,6 +463,19 @@ s_item = s.listdef.listitem.s_value assert s_item.no_nul + def test_unicode_split(self): + a = self.RPythonAnnotator() + def g(n): + if n: + return u"test string" + def f(n): + if n: + return g(n).split(u' ') + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeList) + s_item = s.listdef.listitem.s_value + assert s_item.no_nul + def test_str_split_nul(self): def f(n): return n.split('\0')[0] @@ -470,6 +495,27 @@ assert not s.can_be_None assert not s.no_nul + def test_unicode_split_nul(self): + def f(n): + return n.split(u'\0')[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeUnicodeString( + no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert not s.can_be_None + assert s.no_nul + + def g(n): + return n.split(u'\0', 1)[0] + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(g, [annmodel.SomeUnicodeString( + no_nul=False, can_be_None=False)]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert not s.can_be_None + assert not s.no_nul + def test_str_splitlines(self): a = self.RPythonAnnotator() def f(a_str): @@ -490,6 +536,18 @@ s = a.build_types(f, [int, annmodel.SomeString(no_nul=True)]) assert s.no_nul + def test_unicode_strip(self): + a = self.RPythonAnnotator() + def f(n, a_str): + if n == 0: + return a_str.strip(u' ') + elif n == 1: + return a_str.rstrip(u' ') + else: + return a_str.lstrip(u' ') + s = a.build_types(f, [int, annmodel.SomeUnicodeString(no_nul=True)]) + assert s.no_nul + def test_str_mul(self): a = self.RPythonAnnotator() def f(a_str): @@ -2042,6 +2100,17 @@ assert s.can_be_None assert s.no_nul + def test_unicode_noNUL_canbeNone(self): + def f(a): + if a: + return u"abc" + else: + return None + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert s.can_be_None + assert s.no_nul + def test_str_or_None(self): def f(a): if a: @@ -2058,6 +2127,22 @@ assert s.can_be_None assert s.no_nul + def test_unicode_or_None(self): + def f(a): + if a: + return u"abc" + else: + return None + def g(a): + x = f(a) + if x is None: + return u"abcd" + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert s.can_be_None + assert s.no_nul + def test_emulated_pbc_call_simple(self): def f(a,b): return a + b @@ -2124,6 +2209,19 @@ assert isinstance(s, annmodel.SomeString) assert s.no_nul + def test_iteritems_unicode0(self): + def it(d): + return d.iteritems() + def f(): + d0 = {u'1a': u'2a', u'3': u'4'} + for item in it(d0): + return u"%s=%s" % item + raise ValueError + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul + def test_no_nul_mod(self): def f(x): s = "%d" % x @@ -2133,6 +2231,14 @@ assert isinstance(s, annmodel.SomeString) assert s.no_nul + def test_no_nul_mod_unicode(self): + def f(x): + s = u"%d" % x + return s + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul def test_mul_str0(self): def f(s): @@ -2142,6 +2248,24 @@ assert isinstance(s, annmodel.SomeString) assert s.no_nul + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul + + def test_reverse_mul_str0(self): + def f(s): + return 10*s + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeString(no_nul=True)]) + assert isinstance(s, annmodel.SomeString) + assert s.no_nul + + a = self.RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True)]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul + def test_getitem_str0(self): def f(s, n): if n == 1: @@ -2153,12 +2277,18 @@ return s a = self.RPythonAnnotator() a.translator.config.translation.check_str_without_nul = True - s = a.build_types(f, [annmodel.SomeString(no_nul=True), annmodel.SomeInteger()]) assert isinstance(s, annmodel.SomeString) assert s.no_nul + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=True), + annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul + def test_non_none_and_none_with_isinstance(self): class A(object): pass @@ -3411,6 +3541,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [unicode]) assert isinstance(s, annmodel.SomeUnicodeString) + assert s.no_nul def test_unicode_char(self): def f(x, i): @@ -3916,6 +4047,19 @@ assert s.can_be_None assert s.no_nul + def test_contains_no_nul_unicode(self): + def f(i): + if u"\0" in i: + return None + else: + return i + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + s = a.build_types(f, [annmodel.SomeUnicodeString(no_nul=False)]) + assert isinstance(s, annmodel.SomeUnicodeString) + assert s.can_be_None + assert s.no_nul + def test_no___call__(self): class X(object): def __call__(self): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -574,7 +574,9 @@ return self.basecharclass() def method_split(self, patt, max=-1): - if max == -1 and patt.is_constant() and patt.const == "\0": + # special-case for .split( '\x00') or .split(u'\x00') + if max == -1 and patt.is_constant() and ( + len(patt.const) == 1 and ord(patt.const) == 0): no_nul = True else: no_nul = self.no_nul diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -16,10 +16,11 @@ DEFL_GC = "incminimark" # XXX +DEFL_ROOTFINDER_WITHJIT = "shadowstack" if sys.platform.startswith("linux"): - DEFL_ROOTFINDER_WITHJIT = "asmgcc" -else: - DEFL_ROOTFINDER_WITHJIT = "shadowstack" + _mach = os.popen('uname -m', 'r').read().strip() + if _mach.startswith('x86') or _mach in ['i386', 'i486', 'i586', 'i686']: + DEFL_ROOTFINDER_WITHJIT = "asmgcc" # only for Linux on x86 / x86-64 IS_64_BITS = sys.maxint > 2147483647 diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -909,7 +909,7 @@ descr.adr_jump_offset = failure_recovery_pos relative_offset = tok.pos_recovery_stub - tok.offset guard_pos = block_start + tok.offset - if not tok.is_guard_not_invalidated: + if not tok.guard_not_invalidated(): # patch the guard jump to the stub # overwrite the generate NOP with a B_offs to the pos of the # stub diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -36,11 +36,9 @@ class ArmGuardToken(GuardToken): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, - offset, exc, frame_depth, is_guard_not_invalidated=False, - is_guard_not_forced=False, fcond=c.AL): + offset, guard_opnum, frame_depth, fcond=c.AL): GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs, - exc, frame_depth, is_guard_not_invalidated, - is_guard_not_forced) + guard_opnum, frame_depth) self.fcond = fcond self.offset = offset @@ -175,10 +173,7 @@ self.mc.RSB_ri(resloc.value, l0.value, imm=0) return fcond - def build_guard_token(self, op, frame_depth, arglocs, offset, fcond, save_exc, - is_guard_not_invalidated=False, - is_guard_not_forced=False): - assert isinstance(save_exc, bool) + def build_guard_token(self, op, frame_depth, arglocs, offset, fcond): assert isinstance(fcond, int) descr = op.getdescr() assert isinstance(descr, AbstractFailDescr) @@ -189,16 +184,12 @@ failargs=op.getfailargs(), fail_locs=arglocs, offset=offset, - exc=save_exc, + guard_opnum=op.getopnum(), frame_depth=frame_depth, - is_guard_not_invalidated=is_guard_not_invalidated, - is_guard_not_forced=is_guard_not_forced, fcond=fcond) return token - def _emit_guard(self, op, arglocs, save_exc, - is_guard_not_invalidated=False, - is_guard_not_forced=False): + def _emit_guard(self, op, arglocs, is_guard_not_invalidated=False): if is_guard_not_invalidated: fcond = c.cond_none else: @@ -206,10 +197,9 @@ self.guard_success_cc = c.cond_none assert fcond != c.cond_none pos = self.mc.currpos() - token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond, save_exc, - is_guard_not_invalidated, - is_guard_not_forced) + token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond) self.pending_guards.append(token) + assert token.guard_not_invalidated() == is_guard_not_invalidated # For all guards that are not GUARD_NOT_INVALIDATED we emit a # breakpoint to ensure the location is patched correctly. In the case # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only @@ -221,12 +211,12 @@ return c.AL def emit_op_guard_true(self, op, arglocs, regalloc, fcond): - fcond = self._emit_guard(op, arglocs, save_exc=False) + fcond = self._emit_guard(op, arglocs) return fcond def emit_op_guard_false(self, op, arglocs, regalloc, fcond): self.guard_success_cc = c.get_opposite_of(self.guard_success_cc) - fcond = self._emit_guard(op, arglocs, save_exc=False) + fcond = self._emit_guard(op, arglocs) return fcond def emit_op_guard_value(self, op, arglocs, regalloc, fcond): @@ -244,7 +234,7 @@ self.mc.VCMP(l0.value, l1.value) self.mc.VMRS(cond=fcond) self.guard_success_cc = c.EQ - fcond = self._emit_guard(op, failargs, save_exc=False) + fcond = self._emit_guard(op, failargs) return fcond emit_op_guard_nonnull = emit_op_guard_true @@ -256,14 +246,14 @@ def emit_op_guard_class(self, op, arglocs, regalloc, fcond): self._cmp_guard_class(op, arglocs, regalloc, fcond) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_nonnull_class(self, op, arglocs, regalloc, fcond): self.mc.CMP_ri(arglocs[0].value, 1) self._cmp_guard_class(op, arglocs, regalloc, c.HS) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def _cmp_guard_class(self, op, locs, regalloc, fcond): @@ -288,7 +278,7 @@ def emit_op_guard_gc_type(self, op, arglocs, regalloc, fcond): self._cmp_guard_gc_type(arglocs[0], arglocs[1].value, fcond) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_is_object(self, op, arglocs, regalloc, fcond): @@ -309,7 +299,7 @@ self.mc.LDRB_rr(r.ip.value, r.ip.value, r.lr.value) self.mc.TST_ri(r.ip.value, imm=(IS_OBJECT_FLAG & 0xff)) self.guard_success_cc = c.NE - self._emit_guard(op, arglocs[1:], save_exc=False) + self._emit_guard(op, arglocs[1:]) return fcond def emit_op_guard_subclass(self, op, arglocs, regalloc, fcond): @@ -353,12 +343,11 @@ self.mc.CMP_rr(r.ip.value, r.lr.value) # the guard passes if we get a result of "below or equal" self.guard_success_cc = c.LS - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond): - return self._emit_guard(op, locs, save_exc=False, - is_guard_not_invalidated=True) + return self._emit_guard(op, locs, is_guard_not_invalidated=True) def emit_op_label(self, op, arglocs, regalloc, fcond): self._check_frame_depth_debug(self.mc) @@ -498,7 +487,7 @@ self.mc.LDR_ri(loc.value, loc.value) self.mc.CMP_ri(loc.value, 0) self.guard_success_cc = c.EQ - fcond = self._emit_guard(op, failargs, save_exc=True) + fcond = self._emit_guard(op, failargs) # If the previous operation was a COND_CALL, overwrite its conditional # jump to jump over this GUARD_NO_EXCEPTION as well, if we can if self._find_nearby_operation(-1).getopnum() == rop.COND_CALL: @@ -515,7 +504,7 @@ self.mc.CMP_rr(r.ip.value, loc.value) self.guard_success_cc = c.EQ - self._emit_guard(op, failargs, save_exc=True) + self._emit_guard(op, failargs) self._store_and_reset_exception(self.mc, resloc) return fcond @@ -1047,7 +1036,7 @@ def store_force_descr(self, op, fail_locs, frame_depth): pos = self.mc.currpos() - guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL, True, False, True) + guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL) #self.pending_guards.append(guard_token) self._finish_gcmap = guard_token.gcmap self._store_force_index(op) @@ -1152,7 +1141,7 @@ self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs, save_exc=True, is_guard_not_forced=True) + self._emit_guard(op, arglocs) return fcond def _genop_call_may_force(self, op, arglocs, regalloc, fcond): diff --git a/rpython/jit/backend/arm/test/support.py b/rpython/jit/backend/arm/test/support.py --- a/rpython/jit/backend/arm/test/support.py +++ b/rpython/jit/backend/arm/test/support.py @@ -10,7 +10,9 @@ class JitARMMixin(support.LLJitMixin): type_system = 'lltype' CPUClass = getcpuclass() - basic = True + # we have to disable unroll + enable_opts = "intbounds:rewrite:virtualize:string:earlyforce:pure:heap" + basic = False def check_jumps(self, maxcount): pass diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -10,18 +10,14 @@ from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.test.support import skip_unless_run_slow_tests from rpython.jit.backend.arm.test.test_runner import boxfloat, constfloat -from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.metainterp.history import (AbstractFailDescr, - AbstractDescr, - BasicFailDescr, - BasicFinalDescr, - BoxInt, Box, BoxPtr, - JitCellToken, TargetToken, - ConstInt, ConstPtr, - BoxFloat, ConstFloat) +from rpython.jit.metainterp.resoperation import rop, InputArgInt, InputArgFloat +from rpython.jit.metainterp.history import JitCellToken skip_unless_run_slow_tests() +boxint = InputArgInt +boxfloat = InputArgFloat.fromfloat + class TestARMCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py @@ -82,9 +78,9 @@ EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(7)] + - [BoxInt(1), boxfloat(.2), BoxInt(2), boxfloat(.3), + [boxint(1), boxfloat(.2), boxint(2), boxfloat(.3), boxfloat(.4)]) - res = self.execute_operation(rop.CALL, + res = self.execute_operation(rop.CALL_F, [funcbox] + args, 'float', descr=calldescr) for i,j in enumerate(callargs[0]): @@ -112,7 +108,7 @@ EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) args = ([boxfloat(.1) for i in range(10)]) - res = self.execute_operation(rop.CALL, + res = self.execute_operation(rop.CALL_F, [funcbox] + args, 'float', descr=calldescr) for i,j in enumerate(callargs[0]): @@ -134,8 +130,8 @@ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) funcbox = self.get_funcbox(cpu, func_ptr) - args = ([BoxInt(1) for i in range(10)]) - res = self.execute_operation(rop.CALL, + args = ([boxint(1) for i in range(10)]) + res = self.execute_operation(rop.CALL_I, [funcbox] + args, 'int', descr=calldescr) for i,j in enumerate(callargs[0]): diff --git a/rpython/jit/backend/arm/test/test_generated.py b/rpython/jit/backend/arm/test/test_generated.py --- a/rpython/jit/backend/arm/test/test_generated.py +++ b/rpython/jit/backend/arm/test/test_generated.py @@ -1,4 +1,6 @@ import py +py.test.skip("XXX FIX ME OR KILL ME") + from rpython.jit.metainterp.history import (AbstractFailDescr, AbstractDescr, BasicFailDescr, diff --git a/rpython/jit/backend/arm/test/test_helper.py b/rpython/jit/backend/arm/test/test_helper.py --- a/rpython/jit/backend/arm/test/test_helper.py +++ b/rpython/jit/backend/arm/test/test_helper.py @@ -1,6 +1,8 @@ from rpython.jit.backend.arm.helper.assembler import count_reg_args -from rpython.jit.metainterp.history import (BoxInt, BoxPtr, BoxFloat, - INT, REF, FLOAT) +from rpython.jit.metainterp.history import INT, REF, FLOAT +from rpython.jit.metainterp.resoperation import InputArgInt as BoxInt +from rpython.jit.metainterp.resoperation import InputArgRef as BoxPtr +from rpython.jit.metainterp.resoperation import InputArgFloat as BoxFloat def test_count_reg_args(): diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -215,14 +215,14 @@ def test_exception_bridge_no_exception(self): ops = ''' [i0] - i1 = same_as(1) - call(ConstClass(raising_fptr), i0, descr=raising_calldescr) + i1 = same_as_i(1) + call_n(ConstClass(raising_fptr), i0, descr=raising_calldescr) guard_exception(ConstClass(zero_division_error)) [i1] finish(0) ''' bridge_ops = ''' [i3] - i2 = same_as(2) + i2 = same_as_i(2) guard_no_exception() [i2] finish(1) ''' @@ -379,7 +379,7 @@ def test_bug_wrong_stack_adj(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8] - i9 = same_as(0) + i9 = same_as_i(0) guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] finish(1) ''' @@ -387,7 +387,7 @@ assert self.getint(0) == 0 bridge_ops = ''' [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] - call(ConstClass(raising_fptr), 0, descr=raising_calldescr) + call_n(ConstClass(raising_fptr), 0, descr=raising_calldescr) guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8] finish(1) ''' @@ -430,7 +430,7 @@ def test_cmp_op_0(self): ops = ''' [i0, i3] - i1 = same_as(1) + i1 = same_as_i(1) i2 = int_lt(i0, 100) guard_true(i3) [i1, i2] finish(i2) @@ -630,7 +630,7 @@ def test_one_call(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] - i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + i10 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr) guard_true(i10), [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9] ''' self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9]) @@ -639,8 +639,8 @@ def test_two_calls(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] - i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) - i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr) + i10 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr) + i11 = call_i(ConstClass(f2ptr), i10, i1, descr=f2_calldescr) guard_true(i11) [i11, i1, i2, i3, i4, i5, i6, i7, i8, i9] ''' self.interpret(ops, [4, 7, 9, 9, 9, 9, 9, 9, 9, 9]) @@ -649,7 +649,7 @@ def test_call_many_arguments(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7] - i8 = call(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr) + i8 = call_i(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr) finish(i8) ''' self.interpret(ops, [2, 3, 4, 5, 6, 7, 8, 9]) @@ -658,7 +658,7 @@ def test_bridge_calls_1(self): ops = ''' [i0, i1] - i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + i2 = call_i(ConstClass(f1ptr), i0, descr=f1_calldescr) guard_value(i2, 0, descr=fdescr1) [i2, i1] finish(i1) ''' @@ -666,7 +666,7 @@ assert self.getint(0) == 5 ops = ''' [i2, i1] - i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr) + i3 = call_i(ConstClass(f2ptr), i2, i1, descr=f2_calldescr) finish(i3) ''' self.attach_bridge(ops, loop, -2) @@ -677,7 +677,7 @@ def test_bridge_calls_2(self): ops = ''' [i0, i1] - i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr) + i2 = call_i(ConstClass(f2ptr), i0, i1, descr=f2_calldescr) guard_value(i2, 0, descr=fdescr1) [i2] finish(i1) ''' @@ -685,7 +685,7 @@ assert self.getint(0) == 4 * 7 ops = ''' [i2] - i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr) + i3 = call_i(ConstClass(f1ptr), i2, descr=f1_calldescr) finish(i3) ''' self.attach_bridge(ops, loop, -2) @@ -734,7 +734,7 @@ loop2 = """ [i0] i1 = force_token() - i2 = call_assembler(1,2,3,4,5,6,7,8,9,10,11, descr=looptoken) + i2 = call_assembler_i(1,2,3,4,5,6,7,8,9,10,11, descr=looptoken) guard_not_forced() [i0] guard_false(i0) [i0, i2] """ @@ -749,23 +749,23 @@ label(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, descr=targettoken) i11 = int_add(i0, 1) i12 = int_lt(i11, 2) - i13 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i14 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i15 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i16 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i17 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i18 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i19 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i20 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i21 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i22 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i23 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i24 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i26 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i27 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i28 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i29 = call(ConstClass(f_fptr), i12, descr=f_calldescr) - i30 = call(ConstClass(f_fptr), i12, descr=f_calldescr) + i13 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i14 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i15 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i16 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i17 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i18 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i19 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i20 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i21 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i22 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i23 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i24 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i26 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i27 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i28 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i29 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) + i30 = call_i(ConstClass(f_fptr), i12, descr=f_calldescr) guard_true(i12) [i11, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] jump(i11, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, descr=targettoken) """ diff --git a/rpython/jit/backend/arm/test/test_regalloc2.py b/rpython/jit/backend/arm/test/test_regalloc2.py deleted file mode 100644 --- a/rpython/jit/backend/arm/test/test_regalloc2.py +++ /dev/null @@ -1,281 +0,0 @@ -import py -from rpython.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\ - BoxPtr, ConstPtr, BasicFailDescr, BasicFinalDescr -from rpython.jit.metainterp.history import JitCellToken -from rpython.jit.metainterp.resoperation import rop -from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.arm.arch import WORD -CPU = getcpuclass() - -def test_bug_rshift(): - v1 = BoxInt() - v2 = BoxInt() - v3 = BoxInt() - v4 = BoxInt() - inputargs = [v1] - operations = [ - ResOperation(rop.INT_ADD, [v1, v1], v2), - ResOperation(rop.INT_INVERT, [v2], v3), - ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4), - ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), - ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(1)), - ] - operations[-2].setfailargs([v4, v3]) - cpu = CPU(None, None) - cpu.setup_once() - looptoken = JitCellToken() - cpu.compile_loop(inputargs, operations, looptoken) - deadframe = cpu.execute_token(looptoken, 9) - assert cpu.get_int_value(deadframe, 0) == (9 >> 3) - assert cpu.get_int_value(deadframe, 1) == (~18) - -def test_bug_int_is_true_1(): - v1 = BoxInt() - v2 = BoxInt() - v3 = BoxInt() - v4 = BoxInt() - tmp5 = BoxInt() - inputargs = [v1] - operations = [ - ResOperation(rop.INT_MUL, [v1, v1], v2), - ResOperation(rop.INT_MUL, [v2, v1], v3), - ResOperation(rop.INT_IS_TRUE, [v2], tmp5), - ResOperation(rop.INT_IS_ZERO, [tmp5], v4), - ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), - ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr()), - ] - operations[-2].setfailargs([v4, v3, tmp5]) - cpu = CPU(None, None) - cpu.setup_once() - looptoken = JitCellToken() - cpu.compile_loop(inputargs, operations, looptoken) - deadframe = cpu.execute_token(looptoken, -10) - assert cpu.get_int_value(deadframe, 0) == 0 - assert cpu.get_int_value(deadframe, 1) == -1000 - assert cpu.get_int_value(deadframe, 2) == 1 - -def test_bug_0(): - v1 = BoxInt() - v2 = BoxInt() - v3 = BoxInt() - v4 = BoxInt() - v5 = BoxInt() - v6 = BoxInt() - v7 = BoxInt() - v8 = BoxInt() - v9 = BoxInt() - v10 = BoxInt() - v11 = BoxInt() - v12 = BoxInt() - v13 = BoxInt() - v14 = BoxInt() - v15 = BoxInt() - v16 = BoxInt() - v17 = BoxInt() - v18 = BoxInt() - v19 = BoxInt() - v20 = BoxInt() - v21 = BoxInt() - v22 = BoxInt() - v23 = BoxInt() - v24 = BoxInt() - v25 = BoxInt() - v26 = BoxInt() - v27 = BoxInt() - v28 = BoxInt() - v29 = BoxInt() - v30 = BoxInt() - v31 = BoxInt() - v32 = BoxInt() - v33 = BoxInt() - v34 = BoxInt() - v35 = BoxInt() - v36 = BoxInt() - v37 = BoxInt() - v38 = BoxInt() - v39 = BoxInt() - v40 = BoxInt() - tmp41 = BoxInt() - tmp42 = BoxInt() - tmp43 = BoxInt() - tmp44 = BoxInt() - tmp45 = BoxInt() - tmp46 = BoxInt() - inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] - operations = [ - ResOperation(rop.UINT_GT, [v3, ConstInt(-48)], v11), - ResOperation(rop.INT_XOR, [v8, v1], v12), - ResOperation(rop.INT_GT, [v6, ConstInt(-9)], v13), - ResOperation(rop.INT_LE, [v13, v2], v14), - ResOperation(rop.INT_LE, [v11, v5], v15), - ResOperation(rop.UINT_GE, [v13, v13], v16), - ResOperation(rop.INT_OR, [v9, ConstInt(-23)], v17), - ResOperation(rop.INT_LT, [v10, v13], v18), - ResOperation(rop.INT_OR, [v15, v5], v19), - ResOperation(rop.INT_XOR, [v17, ConstInt(54)], v20), - ResOperation(rop.INT_MUL, [v8, v10], v21), - ResOperation(rop.INT_OR, [v3, v9], v22), - ResOperation(rop.INT_AND, [v11, ConstInt(-4)], tmp41), - ResOperation(rop.INT_OR, [tmp41, ConstInt(1)], tmp42), - ResOperation(rop.INT_MOD, [v12, tmp42], v23), - ResOperation(rop.INT_IS_TRUE, [v6], v24), - ResOperation(rop.UINT_RSHIFT, [v15, ConstInt(6)], v25), - ResOperation(rop.INT_OR, [ConstInt(-4), v25], v26), - ResOperation(rop.INT_INVERT, [v8], v27), - ResOperation(rop.INT_SUB, [ConstInt(-113), v11], v28), - ResOperation(rop.INT_NEG, [v7], v29), - ResOperation(rop.INT_NEG, [v24], v30), - ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(53)], v31), - ResOperation(rop.INT_MUL, [v28, v27], v32), - ResOperation(rop.INT_AND, [v18, ConstInt(-4)], tmp43), - ResOperation(rop.INT_OR, [tmp43, ConstInt(1)], tmp44), - ResOperation(rop.INT_MOD, [v26, tmp44], v33), - ResOperation(rop.INT_OR, [v27, v19], v34), - ResOperation(rop.UINT_LT, [v13, ConstInt(1)], v35), - ResOperation(rop.INT_AND, [v21, ConstInt(31)], tmp45), - ResOperation(rop.INT_RSHIFT, [v21, tmp45], v36), - ResOperation(rop.INT_AND, [v20, ConstInt(31)], tmp46), - ResOperation(rop.UINT_RSHIFT, [v4, tmp46], v37), - ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38), - ResOperation(rop.INT_NEG, [v7], v39), - ResOperation(rop.INT_GT, [v24, v32], v40), - ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()), - ] - operations[-1].setfailargs([v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38]) - cpu = CPU(None, None) - cpu.setup_once() - looptoken = JitCellToken() - cpu.compile_loop(inputargs, operations, looptoken) - args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26] - deadframe = cpu.execute_token(looptoken, *args) - assert cpu.get_int_value(deadframe, 0) == 0 - assert cpu.get_int_value(deadframe, 1) == 0 - assert cpu.get_int_value(deadframe, 2) == 0 - assert cpu.get_int_value(deadframe, 3) == 0 - assert cpu.get_int_value(deadframe, 4) == 1 - assert cpu.get_int_value(deadframe, 5) == -7 - assert cpu.get_int_value(deadframe, 6) == 1 - assert cpu.get_int_value(deadframe, 7) == 0 - assert cpu.get_int_value(deadframe, 8) == -2 - assert cpu.get_int_value(deadframe, 9) == 18 - assert cpu.get_int_value(deadframe, 10) == 1 - assert cpu.get_int_value(deadframe, 11) == 18 - assert cpu.get_int_value(deadframe, 12) == -1 - assert cpu.get_int_value(deadframe, 13) == 0 - -def test_bug_1(): - v1 = BoxInt() - v2 = BoxInt() - v3 = BoxInt() - v4 = BoxInt() - v5 = BoxInt() - v6 = BoxInt() - v7 = BoxInt() - v8 = BoxInt() - v9 = BoxInt() - v10 = BoxInt() - v11 = BoxInt() - v12 = BoxInt() - v13 = BoxInt() - v14 = BoxInt() - v15 = BoxInt() - v16 = BoxInt() - v17 = BoxInt() - v18 = BoxInt() - v19 = BoxInt() - v20 = BoxInt() - v21 = BoxInt() - v22 = BoxInt() - v23 = BoxInt() - v24 = BoxInt() - v25 = BoxInt() - v26 = BoxInt() - v27 = BoxInt() - v28 = BoxInt() - v29 = BoxInt() - v30 = BoxInt() - v31 = BoxInt() - v32 = BoxInt() - v33 = BoxInt() - v34 = BoxInt() - v35 = BoxInt() - v36 = BoxInt() - v37 = BoxInt() - v38 = BoxInt() - v39 = BoxInt() - v40 = BoxInt() - tmp41 = BoxInt() - tmp42 = BoxInt() - tmp43 = BoxInt() - tmp44 = BoxInt() - tmp45 = BoxInt() - inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] - operations = [ - ResOperation(rop.UINT_LT, [v6, ConstInt(0)], v11), - ResOperation(rop.INT_AND, [v3, ConstInt(31)], tmp41), - ResOperation(rop.INT_RSHIFT, [v3, tmp41], v12), - ResOperation(rop.INT_NEG, [v2], v13), - ResOperation(rop.INT_ADD, [v11, v7], v14), - ResOperation(rop.INT_OR, [v3, v2], v15), - ResOperation(rop.INT_OR, [v12, v12], v16), - ResOperation(rop.INT_NE, [v2, v5], v17), - ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp42), - ResOperation(rop.UINT_RSHIFT, [v14, tmp42], v18), - ResOperation(rop.INT_AND, [v14, ConstInt(31)], tmp43), - ResOperation(rop.INT_LSHIFT, [ConstInt(7), tmp43], v19), - ResOperation(rop.INT_NEG, [v19], v20), - ResOperation(rop.INT_MOD, [v3, ConstInt(1)], v21), - ResOperation(rop.UINT_GE, [v15, v1], v22), - ResOperation(rop.INT_AND, [v16, ConstInt(31)], tmp44), - ResOperation(rop.INT_LSHIFT, [v8, tmp44], v23), - ResOperation(rop.INT_IS_TRUE, [v17], v24), - ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp45), - ResOperation(rop.INT_LSHIFT, [v14, tmp45], v25), - ResOperation(rop.INT_LSHIFT, [v5, ConstInt(17)], v26), - ResOperation(rop.INT_EQ, [v9, v15], v27), _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit