[pypy-commit] pypy value-profiling: merge default
cfbolz
noreply at buildbot.pypy.org
Tue Sep 22 10:57:00 CEST 2015
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: value-profiling
Changeset: r79750:95fb006bbdff
Date: 2015-09-22 10:57 +0200
http://bitbucket.org/pypy/pypy/changeset/95fb006bbdff/
Log: merge default
diff too long, truncating to 2000 out of 3446 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/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,10 +32,16 @@
def product(s):
i = 1
for x in s:
+ i *= x
+ return i
+
+ at 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_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
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at 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)))
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at 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
+
+ at unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+ at 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
+
+ at unwrap_spec(hash=r_uint)
+ at 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)
+ at 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
+ at 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))
-
- at 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),
-)
-
- at 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)
-
- at 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,
+ at 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/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_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),
- ResOperation(rop.INT_GE, [ConstInt(0), v6], v28),
- ResOperation(rop.INT_NEG, [v15], v29),
- ResOperation(rop.INT_NEG, [v22], v30),
- ResOperation(rop.INT_ADD, [v7, v16], v31),
- ResOperation(rop.UINT_LT, [v19, v19], v32),
- ResOperation(rop.INT_ADD, [v2, ConstInt(1)], v33),
- ResOperation(rop.INT_NEG, [v5], v34),
- ResOperation(rop.INT_ADD, [v17, v24], v35),
- ResOperation(rop.UINT_LT, [ConstInt(2), v16], v36),
- ResOperation(rop.INT_NEG, [v9], v37),
- ResOperation(rop.INT_GT, [v4, v11], v38),
- ResOperation(rop.INT_LT, [v27, v22], v39),
- ResOperation(rop.INT_NEG, [v27], v40),
- ResOperation(rop.GUARD_FALSE, [v1], None, descr=BasicFailDescr()),
- ]
- operations[-1].setfailargs([v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37])
- cpu = CPU(None, None)
- cpu.setup_once()
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8]
- deadframe = cpu.execute_token(looptoken, *args)
- assert cpu.get_int_value(deadframe, 0) == 0
- assert cpu.get_int_value(deadframe, 1) == 8
- assert cpu.get_int_value(deadframe, 2) == 1
- assert cpu.get_int_value(deadframe, 3) == 131072
- assert cpu.get_int_value(deadframe, 4) == 20
- assert cpu.get_int_value(deadframe, 5) == -1
- assert cpu.get_int_value(deadframe, 6) == 0
- assert cpu.get_int_value(deadframe, 7) == -19
- assert cpu.get_int_value(deadframe, 8) == 6
- assert cpu.get_int_value(deadframe, 9) == 26
- assert cpu.get_int_value(deadframe, 10) == 12
- assert cpu.get_int_value(deadframe, 11) == 0
- assert cpu.get_int_value(deadframe, 12) == 0
- assert cpu.get_int_value(deadframe, 13) == 2
- assert cpu.get_int_value(deadframe, 14) == 2
- assert cpu.get_int_value(deadframe, 15) == 1
- assert cpu.get_int_value(deadframe, 16) == -57344
- assert cpu.get_int_value(deadframe, 17) == 1
- assert cpu.get_int_value(deadframe, 18) == -1
- if WORD == 4:
- assert cpu.get_int_value(deadframe, 19) == -2147483648
- elif WORD == 8:
- assert cpu.get_int_value(deadframe, 19) == 19327352832
- assert cpu.get_int_value(deadframe, 20) == -49
diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -80,8 +80,8 @@
self.gc_size_of_header = gc_ll_descr.gcheaderbuilder.size_gc_header
else:
self.gc_size_of_header = WORD # for tests
- self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
- self.memset_addr = self.cpu.cast_ptr_to_int(memset_fn)
+ self.memcpy_addr = rffi.cast(lltype.Signed, memcpy_fn)
+ self.memset_addr = rffi.cast(lltype.Signed, memset_fn)
self._build_failure_recovery(False, withfloats=False)
self._build_failure_recovery(True, withfloats=False)
self._build_wb_slowpath(False)
diff --git a/rpython/jit/backend/llsupport/codemap.py b/rpython/jit/backend/llsupport/codemap.py
--- a/rpython/jit/backend/llsupport/codemap.py
+++ b/rpython/jit/backend/llsupport/codemap.py
@@ -15,7 +15,7 @@
from rpython.rlib.entrypoint import jit_entrypoint
from rpython.rlib.rbisect import bisect_right, bisect_right_addr
from rpython.rlib.rbisect import bisect_left, bisect_left_addr
-from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.translator import cdir
@@ -74,11 +74,12 @@
stack_depth_at_loc = llexternal('pypy_jit_stack_depth_at_loc',
[lltype.Signed], lltype.Signed)
find_codemap_at_addr = llexternal('pypy_find_codemap_at_addr',
- [lltype.Signed, rffi.CArrayPtr(lltype.Signed)], lltype.Signed)
+ [lltype.Signed, rffi.CArrayPtr(lltype.Signed)],
+ llmemory.Address)
yield_bytecode_at_addr = llexternal('pypy_yield_codemap_at_addr',
- [lltype.Signed, lltype.Signed,
+ [llmemory.Address, lltype.Signed,
rffi.CArrayPtr(lltype.Signed)],
- lltype.Signed)
+ lltype.Signed)
class CodemapStorage(object):
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -600,16 +600,22 @@
@specialize.argtype(1)
def bh_getfield_gc_i(self, struct, fielddescr):
ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
+ if isinstance(lltype.typeOf(struct), lltype.Ptr):
+ fielddescr.check_correct_type(struct)
return self.read_int_at_mem(struct, ofs, size, sign)
@specialize.argtype(1)
def bh_getfield_gc_r(self, struct, fielddescr):
ofs = self.unpack_fielddescr(fielddescr)
+ if isinstance(lltype.typeOf(struct), lltype.Ptr):
+ fielddescr.check_correct_type(struct)
return self.read_ref_at_mem(struct, ofs)
@specialize.argtype(1)
def bh_getfield_gc_f(self, struct, fielddescr):
ofs = self.unpack_fielddescr(fielddescr)
+ if isinstance(lltype.typeOf(struct), lltype.Ptr):
+ fielddescr.check_correct_type(struct)
return self.read_float_at_mem(struct, ofs)
bh_getfield_raw_i = bh_getfield_gc_i
diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py
--- a/rpython/jit/backend/test/calling_convention_test.py
+++ b/rpython/jit/backend/test/calling_convention_test.py
@@ -152,6 +152,7 @@
res = self.execute_operation(rop.CALL_F,
[funcbox] + argslist,
'float', descr=calldescr)
+ res = longlong.getrealfloat(res)
assert abs(res - result) < 0.0001
def test_call_aligned_with_args_on_the_stack(self):
@@ -194,6 +195,7 @@
res = self.execute_operation(rop.CALL_F,
[funcbox] + argslist,
'float', descr=calldescr)
+ res = longlong.getrealfloat(res)
assert abs(res - result) < 0.0001
def test_call_alignment_call_assembler(self):
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2293,6 +2293,7 @@
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
EffectInfo.MOST_GENERAL)
+ gfs = longlong.getfloatstorage
for (operation, arg1, arg2_if_true, arg2_if_false) in [
('int_lt', -5, 2, -5),
@@ -2303,8 +2304,8 @@
('int_xor', 7, 3, 7), # test without a comparison at all
('int_is_true', 4242, 1, 0),
('int_is_zero', 4242, 0, 1),
- ('float_lt', -0.5, 0.2, -0.5),
- ('float_eq', 1.1, 1.1, 1.2),
+ ('float_lt', gfs(-0.5), gfs(0.2), gfs(-0.5)),
+ ('float_eq', gfs(1.1), gfs(1.1), gfs(1.2)),
]:
called = []
@@ -3788,10 +3789,61 @@
assert called == [finish_descr]
del called[:]
- # compile a replacement
+ # compile a replacement which needs more jitframe stack space
ops = '''
[f0, f1]
f2 = float_sub(f0, f1)
+ f3 = float_sub(f0, f1)
+ f4 = float_sub(f0, f1)
+ f5 = float_sub(f0, f1)
+ f6 = float_sub(f0, f1)
+ f7 = float_sub(f0, f1)
+ f8 = float_sub(f0, f1)
+ f9 = float_sub(f0, f1)
+ f10 = float_sub(f0, f1)
+ f11 = float_sub(f0, f1)
+ f12 = float_sub(f0, f1)
+ f13 = float_sub(f0, f1)
+ f14 = float_sub(f0, f1)
+ f15 = float_sub(f0, f1)
+ f16 = float_sub(f0, f1)
+ f17 = float_sub(f0, f1)
+ f18 = float_sub(f0, f1)
+ f19 = float_sub(f0, f1)
+ i3 = float_eq(f2, f3)
+ i4 = float_eq(f2, f4)
+ i5 = float_eq(f2, f5)
+ i6 = float_eq(f2, f6)
+ i7 = float_eq(f2, f7)
+ i8 = float_eq(f2, f8)
+ i9 = float_eq(f2, f9)
+ i10 = float_eq(f2, f10)
+ i11 = float_eq(f2, f11)
+ i12 = float_eq(f2, f12)
+ i13 = float_eq(f2, f13)
+ i14 = float_eq(f2, f14)
+ i15 = float_eq(f2, f15)
+ i16 = float_eq(f2, f16)
+ i17 = float_eq(f2, f17)
+ i18 = float_eq(f2, f18)
+ i19 = float_eq(f2, f19)
+ guard_true(i3) []
+ guard_true(i4) []
+ guard_true(i5) []
+ guard_true(i6) []
+ guard_true(i7) []
+ guard_true(i8) []
+ guard_true(i9) []
+ guard_true(i10) []
+ guard_true(i11) []
+ guard_true(i12) []
+ guard_true(i13) []
+ guard_true(i14) []
+ guard_true(i15) []
+ guard_true(i16) []
+ guard_true(i17) []
+ guard_true(i18) []
+ guard_true(i19) []
finish(f2)'''
loop2 = parse(ops)
looptoken2 = JitCellToken()
@@ -3799,9 +3851,21 @@
self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2)
finish_descr2 = loop2.operations[-1].getdescr()
+ # check the jitframeinfo
+ if isinstance(self.cpu, AbstractLLCPU):
+ num1 = looptoken.compiled_loop_token.frame_info.jfi_frame_depth
+ num2 = looptoken2.compiled_loop_token.frame_info.jfi_frame_depth
+ assert num1 < num2
+
# install it
self.cpu.redirect_call_assembler(looptoken, looptoken2)
+ # check that the jitframeinfo was updated
+ if isinstance(self.cpu, AbstractLLCPU):
+ num1 = looptoken.compiled_loop_token.frame_info.jfi_frame_depth
+ num2 = looptoken2.compiled_loop_token.frame_info.jfi_frame_depth
+ assert num1 == num2
+
# now, our call_assembler should go to looptoken2
args = [longlong.getfloatstorage(6.0),
longlong.getfloatstorage(1.5)] # 6.0-1.5 == 1.25+3.25
@@ -5000,3 +5064,56 @@
]:
self.execute_operation(rop.GUARD_SUBCLASS, [arg, klass], 'void')
assert self.guard_failed == (not is_subclass)
+
+ def test_bug_from_optimize_cond_call(self):
+ loop = parse("""
+ [i0, i1]
+ i99 = int_sub(i0, i0)
+ force_spill(i99)
+ i2 = int_add(i0, i1)
+ i3 = int_add(i0, i1)
+ i4 = int_add(i0, i1)
+ i5 = int_add(i0, i1)
+ i6 = int_add(i0, i1)
+ i7 = int_add(i0, i1)
+ i8 = int_add(i0, i1)
+ i9 = int_add(i0, i1)
+ i10 = int_add(i0, i1)
+ i11 = int_add(i0, i1)
+ i12 = int_add(i0, i1)
+ i13 = int_add(i0, i1)
+ i14 = int_add(i0, i1)
+ i15 = int_add(i0, i1)
+ i16 = int_add(i0, i1)
+ i17 = int_add(i0, i1)
+ i18 = int_add(i0, i1)
+ i19 = int_add(i0, i1)
+ i20 = int_is_true(i99)
+ force_spill(i0)
+ force_spill(i1)
+ force_spill(i2)
+ force_spill(i3)
+ force_spill(i4)
+ force_spill(i5)
+ force_spill(i6)
+ force_spill(i7)
+ force_spill(i8)
+ force_spill(i9)
+ force_spill(i10)
+ force_spill(i11)
+ force_spill(i12)
+ force_spill(i13)
+ force_spill(i14)
+ force_spill(i15)
+ force_spill(i16)
+ force_spill(i17)
+ force_spill(i18)
+ force_spill(i19)
+ finish(i20, descr=finaldescr)
+ """, namespace={"finaldescr": BasicFinalDescr(1)})
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ deadframe = self.cpu.execute_token(looptoken, 40, 2)
+ fail = self.cpu.get_latest_descr(deadframe)
+ res = self.cpu.get_int_value(deadframe, 0)
+ assert res == 0
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -175,12 +175,12 @@
for i in range(4):
mc.MOV_sr(i * WORD, cond_call_register_arguments[i].value)
mc.CALL(eax)
+ self._reload_frame_if_necessary(mc)
if IS_X86_64:
mc.ADD(esp, imm(WORD))
else:
mc.ADD(esp, imm(WORD * 7))
self.set_extra_stack_depth(mc, 0)
- self._reload_frame_if_necessary(mc, align_stack=True)
self.pop_gcmap(mc) # cancel the push_gcmap(store=True) in the caller
self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only)
mc.RET()
@@ -244,14 +244,15 @@
mc.MOV_rs(edi.value, WORD * 3) # load the itemsize
self.set_extra_stack_depth(mc, 16)
mc.CALL(imm(follow_jump(addr)))
+ self._reload_frame_if_necessary(mc)
mc.ADD_ri(esp.value, 16 - WORD)
+ self.set_extra_stack_depth(mc, 0)
+ #
mc.TEST_rr(eax.value, eax.value)
More information about the pypy-commit
mailing list