[pypy-commit] pypy split-rpython: Merge with default
Aquana
noreply at buildbot.pypy.org
Sun Jan 13 07:52:09 CET 2013
Author: Alexander Hesse <webmaster at aquanasoft.de>
Branch: split-rpython
Changeset: r60013:9f3e3485ed27
Date: 2013-01-13 07:49 +0100
http://bitbucket.org/pypy/pypy/changeset/9f3e3485ed27/
Log: Merge with default
diff too long, truncating to 2000 out of 10188 lines
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -28,7 +28,7 @@
DEALINGS IN THE SOFTWARE.
-PyPy Copyright holders 2003-2012
+PyPy Copyright holders 2003-2013
-----------------------------------
Except when otherwise stated (look for LICENSE files or information at
diff --git a/goal/targetpypystandalone.py b/goal/targetpypystandalone.py
--- a/goal/targetpypystandalone.py
+++ b/goal/targetpypystandalone.py
@@ -29,6 +29,11 @@
w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup))
withjit = space.config.objspace.usemodules.pypyjit
+ if withjit:
+ from pypy.module.pypyjit.interp_jit import callback_hook
+ from pypy.rlib import objectmodel
+ objectmodel.register_around_callback_hook(callback_hook)
+
def entry_point(argv):
if withjit:
from rpython.jit.backend.hlinfo import highleveljitinfo
diff --git a/goal/test2/test_app_main.py b/goal/test2/test_app_main.py
--- a/goal/test2/test_app_main.py
+++ b/goal/test2/test_app_main.py
@@ -376,6 +376,30 @@
child.expect('Traceback')
child.expect('NameError')
+ def test_pythonstartup_file1(self, monkeypatch):
+ monkeypatch.setenv('PYTHONPATH', None)
+ monkeypatch.setenv('PYTHONSTARTUP', demo_script)
+ child = self.spawn([])
+ child.expect('File: [^\n]+\.py')
+ child.expect('goodbye')
+ child.expect('>>> ')
+ child.sendline('[myvalue]')
+ child.expect(re.escape('[42]'))
+ child.expect('>>> ')
+ child.sendline('__file__')
+ child.expect('Traceback')
+ child.expect('NameError')
+
+ def test_pythonstartup_file2(self, monkeypatch):
+ monkeypatch.setenv('PYTHONPATH', None)
+ monkeypatch.setenv('PYTHONSTARTUP', crashing_demo_script)
+ child = self.spawn([])
+ child.expect('Traceback')
+ child.expect('>>> ')
+ child.sendline('__file__')
+ child.expect('Traceback')
+ child.expect('NameError')
+
def test_ignore_python_startup(self):
old = os.environ.get('PYTHONSTARTUP', '')
try:
diff --git a/lib-python/2.7/sre_parse.py b/lib-python/2.7/sre_parse.py
--- a/lib-python/2.7/sre_parse.py
+++ b/lib-python/2.7/sre_parse.py
@@ -16,6 +16,12 @@
from sre_constants import *
+try:
+ from __pypy__ import newdict
+except ImportError:
+ def newdict(tp):
+ return {}
+
SPECIAL_CHARS = ".\\[{()*+?^$|"
REPEAT_CHARS = "*+?{"
@@ -68,7 +74,7 @@
self.flags = 0
self.open = []
self.groups = 1
- self.groupdict = {}
+ self.groupdict = newdict("module")
def opengroup(self, name=None):
gid = self.groups
self.groups = gid + 1
diff --git a/pypy/doc/Makefile b/pypy/doc/Makefile
--- a/pypy/doc/Makefile
+++ b/pypy/doc/Makefile
@@ -32,38 +32,38 @@
-rm -rf $(BUILDDIR)/*
html:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
@@ -73,7 +73,7 @@
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyPy.qhc"
latex:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@@ -81,26 +81,26 @@
"run these through (pdf)latex."
man:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man"
changes:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
- python config/generate.py
+ # python config/generate.py #readthedocs will not run this Makefile
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -38,7 +38,7 @@
# General information about the project.
project = u'PyPy'
-copyright = u'2011, The PyPy Project'
+copyright = u'2013, The PyPy Project'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/pypy/doc/config/translation.no__thread.txt b/pypy/doc/config/translation.no__thread.txt
--- a/pypy/doc/config/translation.no__thread.txt
+++ b/pypy/doc/config/translation.no__thread.txt
@@ -1,3 +1,3 @@
Don't use gcc __thread attribute for fast thread local storage
-implementation . Increases the chance that moving the resulting
+implementation. Increases the chance that moving the resulting
executable to another same processor Linux machine will work.
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -67,7 +67,7 @@
.. _Python: http://docs.python.org/index.html
.. _`more...`: architecture.html#mission-statement
.. _`PyPy blog`: http://morepypy.blogspot.com/
-.. _`development bug/feature tracker`: https://codespeak.net/issue/pypy-dev/
+.. _`development bug/feature tracker`: https://bugs.pypy.org
.. _here: http://tismerysoft.de/pypy/irc-logs/pypy
.. _`Mercurial commit mailing list`: http://python.org/mailman/listinfo/pypy-commit
.. _`development mailing list`: http://python.org/mailman/listinfo/pypy-dev
diff --git a/pypy/doc/pypyconfig.py b/pypy/doc/pypyconfig.py
--- a/pypy/doc/pypyconfig.py
+++ b/pypy/doc/pypyconfig.py
@@ -3,6 +3,10 @@
def setup(app):
import sys, os
sys.path.insert(0, os.path.abspath("../../"))
+
+ #Autmatically calls make_cmdlline_overview
+ from pypy.doc.config import generate
+
from pypy.config import makerestdoc
import py
role = makerestdoc.register_config_role(py.path.local())
diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py
--- a/pypy/doc/test/test_whatsnew.py
+++ b/pypy/doc/test/test_whatsnew.py
@@ -29,7 +29,7 @@
merge() and \
branch(default)) and \
not branch(default)' % (startrev, endrev)
- cmd = r"hg log -R '%s' -r '%s' --template '{branches}\n'" % (path, revset)
+ cmd = r'hg log -R "%s" -r "%s" --template "{branches}\n"' % (path, revset)
out = getoutput(cmd)
branches = set(map(str.strip, out.splitlines()))
return branches
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
@@ -5,15 +5,38 @@
.. this is a revision shortly after release-2.0-beta1
.. startrev: 0e6161a009c6
+.. branch: callback-jit
+Callbacks from C are now better JITted
+
+.. branch: remove-globals-in-jit
+
.. branch: length-hint
Implement __lenght_hint__ according to PEP 424
+.. branch: numpypy-longdouble
+Long double support for numpypy
+.. branch: numpypy-real-as-view
+Convert real, imag from ufuncs to views. This involves the beginning of
+view() functionality
+
+.. branch: signatures
+Improved RPython typing
+
+.. branch: rpython-bytearray
+Rudimentary support for bytearray in RPython
+
.. branches we don't care about
.. branch: autoreds
+.. branch: reflex-support
+.. branch: kill-faking
+.. branch: improved_ebnfparse_error
+.. branch: task-decorator
.. branch: release-2.0-beta1
.. branch: remove-PYPY_NOT_MAIN_FILE
+.. branch: missing-jit-operations
+
.. branch: fix-lookinside-iff-oopspec
Fixed the interaction between two internal tools for controlling the JIT.
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -56,11 +56,24 @@
----------------------------
On Windows, there is no standard place where to download, build and
-install third-party libraries. We chose to install them in the parent
+install third-party libraries. We recommend installing them in the parent
directory of the pypy checkout. For example, if you installed pypy in
``d:\pypy\trunk\`` (This directory contains a README file), the base
-directory is ``d:\pypy``. You may choose different values by setting the
-INCLUDE, LIB and PATH (for DLLs)
+directory is ``d:\pypy``. You must then set the
+INCLUDE, LIB and PATH (for DLLs) environment variables appropriately.
+
+Abridged method (for -Ojit builds using Visual Studio 2008)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Download the versions of all the external packages
+from
+https://bitbucket.org/pypy/pypy/downloads/local.zip
+Then expand it into the base directory (base_dir) and modify your environment to reflect this::
+
+ set PATH=<base_dir>\bin;%PATH%
+ set INCLUDE=<base_dir>\include;%INCLUDE%
+ set LIB=<base_dir>\lib;%LIB%
+
+Now you should be good to go. Read on for more information.
The Boehm garbage collector
~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -584,7 +584,12 @@
python_startup,
'exec')
exec co_python_startup in mainmodule.__dict__
+ mainmodule.__file__ = python_startup
run_toplevel(run_it)
+ try:
+ del mainmodule.__file__
+ except (AttributeError, TypeError):
+ pass
# Then we need a prompt.
inspect = True
else:
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -178,6 +178,11 @@
else:
oparg = 0
+ # note: the structure of the code here is such that it makes
+ # (after translation) a big "if/elif" chain, which is then
+ # turned into a switch(). It starts here: even if the first
+ # one is not an "if" but a "while" the effect is the same.
+
while opcode == self.opcodedesc.EXTENDED_ARG.index:
opcode = ord(co_code[next_instr])
if opcode < self.HAVE_ARGUMENT:
@@ -226,6 +231,8 @@
'END_FINALLY', 'JUMP_ABSOLUTE'):
continue # opcodes implemented above
+ # the following "if" is part of the big switch described
+ # above.
if opcode == opdesc.index:
# dispatch to the opcode method
meth = getattr(self, opdesc.methodname)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -105,6 +105,13 @@
# typical usage (case 1 is the most common kind of app-level subclasses;
# case 2 is the memory-saving kind defined with __slots__).
#
+# +----------------------------------------------------------------+
+# | NOTE: if withmapdict is enabled, the following doesn't apply! |
+# | Map dicts can flexibly allow any slots/__dict__/__weakref__ to |
+# | show up only when needed. In particular there is no way with |
+# | mapdict to prevent some objects from being weakrefable. |
+# +----------------------------------------------------------------+
+#
# dict slots del weakrefable
#
# 1. Y N N Y UserDictWeakref
diff --git a/pypy/module/README.txt b/pypy/module/README.txt
--- a/pypy/module/README.txt
+++ b/pypy/module/README.txt
@@ -3,7 +3,7 @@
that require access to interpreter level. See here
for more information:
- http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#modules-in-pypy
+ http://doc.pypy.org/en/latest/coding-guide.html#modules-in-pypy
ATTENTION: don't put any '.py' files directly into pypy/module
because you can easily get import mixups on e.g. "import sys"
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -5,8 +5,8 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here
-from rpython.rlib import clibffi, rweakref, rgc
-from rpython.rlib.rarithmetic import r_ulonglong
+from rpython.rlib import clibffi, rweakref
+from rpython.rlib import jit
from pypy.module._cffi_backend.cdataobj import W_CData
from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN
@@ -77,6 +77,7 @@
space.wrap("expected a function ctype"))
return ctype
+ @jit.unroll_safe
def invoke(self, ll_args):
space = self.space
ctype = self.getfunctype()
diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py
--- a/pypy/module/_sre/interp_sre.py
+++ b/pypy/module/_sre/interp_sre.py
@@ -54,7 +54,7 @@
result = [-1] * (2 * num_groups)
mark = ctx.match_marks
while mark is not None:
- index = mark.gid
+ index = jit.promote(mark.gid)
if result[index] == -1:
result[index] = mark.position
mark = mark.prev
@@ -90,7 +90,7 @@
# SRE_Pattern class
class W_SRE_Pattern(Wrappable):
- _immutable_fields_ = ["code", "flags", "num_groups"]
+ _immutable_fields_ = ["code", "flags", "num_groups", "w_groupindex"]
def cannot_copy_w(self):
space = self.space
diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -114,19 +114,28 @@
class A(object):
def __eq__(self, other):
return True
+ def __ne__(self, other):
+ return False
a1 = A()
a2 = A()
ref1 = _weakref.ref(a1)
ref2 = _weakref.ref(a2)
assert ref1 == ref2
+ assert not (ref1 != ref2)
+ assert not (ref1 == [])
+ assert ref1 != []
del a1
gc.collect()
assert not ref1 == ref2
assert ref1 != ref2
+ assert not (ref1 == [])
+ assert ref1 != []
del a2
gc.collect()
assert not ref1 == ref2
assert ref1 != ref2
+ assert not (ref1 == [])
+ assert ref1 != []
def test_getweakrefs(self):
import _weakref, gc
@@ -298,6 +307,13 @@
if seen_callback:
assert seen_callback == [True, True, True]
+ def test_type_weakrefable(self):
+ import _weakref, gc
+ w = _weakref.ref(list)
+ assert w() is list
+ gc.collect()
+ assert w() is list
+
class AppTestProxy(object):
spaceconfig = dict(usemodules=('_weakref',))
@@ -435,6 +451,8 @@
class A(object):
def __eq__(self, other):
return True
+ def __ne__(self, other):
+ return False
a = A()
assert _weakref.ref(a) == a
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -13,6 +13,7 @@
from rpython.rlib.debug import make_sure_not_resized
class ConcreteArrayIterator(base.BaseArrayIterator):
+ _immutable_fields_ = ['dtype', 'skip', 'size']
def __init__(self, array):
self.array = array
self.offset = 0
@@ -21,10 +22,10 @@
self.size = array.size
def setitem(self, elem):
- self.array.setitem(self.offset, elem)
+ self.dtype.setitem(self.array, self.offset, elem)
def getitem(self):
- return self.array.getitem(self.offset)
+ return self.dtype.getitem(self.array, self.offset)
def getitem_bool(self):
return self.dtype.getitem_bool(self.array, self.offset)
@@ -42,13 +43,16 @@
self.offset %= self.size
class OneDimViewIterator(ConcreteArrayIterator):
- def __init__(self, array):
+ ''' The view iterator dtype can be different from the
+ array.dtype, this is what makes it a View
+ '''
+ def __init__(self, array, dtype, start, strides, shape):
self.array = array
- self.offset = array.start
- self.skip = array.get_strides()[0]
- self.dtype = array.dtype
+ self.dtype = dtype
+ self.offset = start
+ self.skip = strides[0]
self.index = 0
- self.size = array.get_shape()[0]
+ self.size = shape[0]
def next(self):
self.offset += self.skip
@@ -65,9 +69,13 @@
self.offset %= self.size
class MultiDimViewIterator(ConcreteArrayIterator):
- def __init__(self, array, start, strides, backstrides, shape):
+ ''' The view iterator dtype can be different from the
+ array.dtype, this is what makes it a View
+ '''
+ def __init__(self, array, dtype, start, strides, backstrides, shape):
self.indexes = [0] * len(shape)
self.array = array
+ self.dtype = dtype
self.shape = shape
self.offset = start
self.shapelen = len(shape)
@@ -131,12 +139,13 @@
self.offset = array.start
self.dim = dim
self.array = array
+ self.dtype = array.dtype
def setitem(self, elem):
- self.array.setitem(self.offset, elem)
+ self.dtype.setitem(self.array, self.offset, elem)
def getitem(self):
- return self.array.getitem(self.offset)
+ return self.dtype.getitem(self.array, self.offset)
@jit.unroll_safe
def next(self):
@@ -220,6 +229,32 @@
new_shape, self)
else:
return None
+
+ def get_real(self):
+ strides = self.get_strides()
+ backstrides = self.get_backstrides()
+ if self.dtype.is_complex_type():
+ dtype = self.dtype.float_type
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self, dtype=dtype)
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self)
+
+ def get_imag(self):
+ strides = self.get_strides()
+ backstrides = self.get_backstrides()
+ if self.dtype.is_complex_type():
+ dtype = self.dtype.float_type
+ return SliceArray(self.start + dtype.get_size(), strides,
+ backstrides, self.get_shape(), self, dtype=dtype)
+ if self.dtype.is_flexible_type():
+ # numpy returns self for self.imag
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self)
+ impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
+ backstrides)
+ impl.fill(self.dtype.box(0))
+ return impl
# -------------------- applevel get/setitem -----------------------
@@ -377,7 +412,7 @@
def create_dot_iter(self, shape, skip):
r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
shape, skip)
- return MultiDimViewIterator(self, self.start, r[0], r[1], shape)
+ return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
def swapaxes(self, axis1, axis2):
shape = self.get_shape()[:]
@@ -411,7 +446,7 @@
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self, 0, r[0], r[1], shape)
+ return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
def fill(self, box):
self.dtype.fill(self.storage, box, 0, self.size)
@@ -424,6 +459,12 @@
self.order)
return SliceArray(0, strides, backstrides, new_shape, self)
+class NonWritableArray(ConcreteArray):
+ def descr_setitem(self, space, w_index, w_value):
+ raise OperationError(space.w_RuntimeError, space.wrap(
+ "array is not writable"))
+
+
class SliceArray(BaseConcreteArray):
def __init__(self, start, strides, backstrides, shape, parent, dtype=None):
self.strides = strides
@@ -448,11 +489,12 @@
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self.parent,
+ return MultiDimViewIterator(self.parent, self.dtype,
self.start, r[0], r[1], shape)
if len(self.get_shape()) == 1:
- return OneDimViewIterator(self)
- return MultiDimViewIterator(self.parent, self.start,
+ return OneDimViewIterator(self.parent, self.dtype, self.start,
+ self.get_strides(), self.get_shape())
+ return MultiDimViewIterator(self.parent, self.dtype, self.start,
self.get_strides(),
self.get_backstrides(), self.get_shape())
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -136,7 +136,7 @@
return self.kind == SIGNEDLTR
def is_complex_type(self):
- return (self.num == 14 or self.num == 15 or self.num == 16)
+ return False
def is_bool_type(self):
return self.kind == BOOLLTR
@@ -155,6 +155,19 @@
def get_size(self):
return self.itemtype.get_element_size()
+class W_ComplexDtype(W_Dtype):
+
+ def __init__(self, itemtype, num, kind, name, char, w_box_type,
+ alternate_constructors=[], aliases=[],
+ fields=None, fieldnames=None, native=True, float_type=None):
+ W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type,
+ alternate_constructors=alternate_constructors, aliases=aliases,
+ fields=fields, fieldnames=fieldnames, native=native)
+ self.float_type = float_type
+
+ def is_complex_type(self):
+ return True
+
def dtype_from_list(space, w_lst):
lst_w = space.listview(w_lst)
fields = {}
@@ -413,15 +426,16 @@
alternate_constructors=[space.w_float],
aliases=["float"],
)
- self.w_complex64dtype = W_Dtype(
+ self.w_complex64dtype = W_ComplexDtype(
types.Complex64(),
num=14,
kind=COMPLEXLTR,
name="complex64",
char="F",
w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
+ float_type = self.w_float32dtype,
)
- self.w_complex128dtype = W_Dtype(
+ self.w_complex128dtype = W_ComplexDtype(
types.Complex128(),
num=15,
kind=COMPLEXLTR,
@@ -430,6 +444,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex128Box),
alternate_constructors=[space.w_complex],
aliases=["complex"],
+ float_type = self.w_float64dtype,
)
if interp_boxes.long_double_size == 12:
self.w_float96dtype = W_Dtype(
@@ -443,7 +458,7 @@
)
self.w_longdouble = self.w_float96dtype
- self.w_complex192dtype = W_Dtype(
+ self.w_complex192dtype = W_ComplexDtype(
types.Complex192(),
num=16,
kind=COMPLEXLTR,
@@ -452,6 +467,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex192Box),
alternate_constructors=[space.w_complex],
aliases=["clongdouble", "clongfloat"],
+ float_type = self.w_float96dtype,
)
self.w_clongdouble = self.w_complex192dtype
@@ -467,7 +483,7 @@
)
self.w_longdouble = self.w_float128dtype
- self.w_complex256dtype = W_Dtype(
+ self.w_complex256dtype = W_ComplexDtype(
types.Complex256(),
num=16,
kind=COMPLEXLTR,
@@ -476,6 +492,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex256Box),
alternate_constructors=[space.w_complex],
aliases=["clongdouble", "clongfloat"],
+ float_type = self.w_float128dtype,
)
self.w_clongdouble = self.w_complex256dtype
else:
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -235,6 +235,29 @@
def descr_copy(self, space):
return W_NDimArray(self.implementation.copy())
+ def descr_get_real(self, space):
+ return W_NDimArray(self.implementation.get_real())
+
+ def descr_get_imag(self, space):
+ ret = self.implementation.get_imag()
+ if ret:
+ return W_NDimArray(ret)
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap('imag not implemented for this dtype'))
+
+ def descr_set_real(self, space, w_value):
+ # copy (broadcast) values into self
+ tmp = self.implementation.get_real()
+ tmp.setslice(space, convert_to_array(space, w_value))
+
+ def descr_set_imag(self, space, w_value):
+ # if possible, copy (broadcast) values into self
+ if not self.get_dtype().is_complex_type():
+ raise OperationError(space.w_TypeError,
+ space.wrap('array does not have imaginary part to set'))
+ tmp = self.implementation.get_imag()
+ tmp.setslice(space, convert_to_array(space, w_value))
+
def descr_reshape(self, space, args_w):
"""reshape(...)
a.reshape(shape)
@@ -387,8 +410,6 @@
descr_neg = _unaryop_impl("negative")
descr_abs = _unaryop_impl("absolute")
descr_invert = _unaryop_impl("invert")
- descr_get_real = _unaryop_impl("real")
- descr_get_imag = _unaryop_impl("imag")
def descr_nonzero(self, space):
if self.get_size() > 1:
@@ -635,9 +656,10 @@
swapaxes = interp2app(W_NDimArray.descr_swapaxes),
flat = GetSetProperty(W_NDimArray.descr_get_flatiter),
item = interp2app(W_NDimArray.descr_item),
- real = GetSetProperty(W_NDimArray.descr_get_real),
- imag = GetSetProperty(W_NDimArray.descr_get_imag),
-
+ real = GetSetProperty(W_NDimArray.descr_get_real,
+ W_NDimArray.descr_set_real),
+ imag = GetSetProperty(W_NDimArray.descr_get_imag,
+ W_NDimArray.descr_set_imag),
__array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface),
)
diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py
--- a/pypy/module/micronumpy/test/test_iter.py
+++ b/pypy/module/micronumpy/test/test_iter.py
@@ -12,7 +12,7 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next()
i.next()
i.next()
@@ -30,7 +30,7 @@
strides = [1, 3]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [2, 12]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next()
i.next()
i.next()
@@ -51,7 +51,7 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next_skip_x(2)
i.next_skip_x(2)
i.next_skip_x(2)
@@ -74,7 +74,7 @@
strides = [1, 3]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [2, 12]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next_skip_x(2)
i.next_skip_x(2)
i.next_skip_x(2)
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1169,8 +1169,8 @@
assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all()
def test_eye(self):
- from _numpypy import eye, array
- from _numpypy import int32, float64, dtype
+ from _numpypy import eye
+ from _numpypy import int32, dtype
a = eye(0)
assert len(a) == 0
assert a.dtype == dtype('float64')
@@ -1345,6 +1345,42 @@
assert b[0] == 3
assert b[1] == 2
+ def test_realimag_views(self):
+ from _numpypy import arange, array
+ a = arange(15)
+ b = a.real
+ b[5]=50
+ assert a[5] == 50
+ b = a.imag
+ assert b[7] == 0
+ raises(RuntimeError, 'b[7] = -2')
+ raises(TypeError, 'a.imag = -2')
+ a = array(['abc','def'],dtype='S3')
+ b = a.real
+ assert a[0] == b[0]
+ assert a[1] == b[1]
+ b[1] = 'xyz'
+ assert a[1] == 'xyz'
+ assert a.imag[0] == 'abc'
+ raises(TypeError, 'a.imag = "qop"')
+ a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]])
+ assert a.real[0,1] == 2
+ a.real[0,1] = -20
+ assert a[0,1].real == -20
+ b = a.imag
+ assert b[1,2] == -1
+ b[1,2] = 30
+ assert a[1,2].imag == 30
+ a.real = 13
+ assert a[1,1].real == 13
+ a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j])
+ a.real = 13
+ assert a[3].real == 13
+ a.imag = -5
+ a.imag[3] = -10
+ assert a[3].imag == -10
+ assert a[2].imag == -5
+
def test_tolist_scalar(self):
from _numpypy import int32, bool_
x = int32(23)
@@ -2273,7 +2309,7 @@
assert a[0]['x'] == 'a'
def test_stringarray(self):
- from _numpypy import array, flexible
+ from _numpypy import array
a = array(['abc'],'S3')
assert str(a.dtype) == '|S3'
a = array(['abc'])
@@ -2293,7 +2329,6 @@
def test_flexible_repr(self):
# import overrides str(), repr() for array
- from numpypy.core import arrayprint
from _numpypy import array
a = array(['abc'],'S3')
s = repr(a)
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -182,6 +182,8 @@
def clear(self):
self.next_id = 0
+ self._last_object_id = -1
+ self._last_object = None
self.storage = {}
@staticmethod
@@ -194,10 +196,18 @@
@staticmethod
def get_object(id):
- return global_storage.storage[id]
+ if id == global_storage._last_object_id:
+ return global_storage._last_object
+ result = global_storage.storage[id]
+ global_storage._last_object_id = id
+ global_storage._last_object = result
+ return result
@staticmethod
def free_nonmoving_id(id):
+ if id == global_storage._last_object_id:
+ global_storage._last_object = None
+ global_storage._last_object_id = -1
del global_storage.storage[id]
global_storage = Storage()
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
@@ -6,7 +6,7 @@
from rpython.tool.pairtype import extendabletype
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 import jit, objectmodel
from rpython.rlib.jit import current_trace_length, unroll_parameters
import pypy.interpreter.pyopcode # for side-effects
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -97,6 +97,15 @@
is_being_profiled=self.is_being_profiled)
return jumpto
+callback_jit_driver = JitDriver(greens = ['name'], reds = 'auto')
+
+def callback_merge_point(name):
+ callback_jit_driver.jit_merge_point(name=name)
+
+ at callback_jit_driver.inline(callback_merge_point)
+def callback_hook(name):
+ pass
+
def _get_adapted_tick_counter():
# Normally, the tick counter is decremented by 100 for every
# Python opcode. Here, to better support JIT compilation of
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -106,7 +106,7 @@
'posix', '_socket', '_sre', '_lsprof', '_weakref',
'__pypy__', 'cStringIO', '_collections', 'struct',
'mmap', 'marshal', '_codecs', 'rctime', 'cppyy',
- '_cffi_backend']:
+ '_cffi_backend', 'pyexpat']:
if modname == 'pypyjit' and 'interp_resop' in rest:
return False
return True
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -14,6 +14,7 @@
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.rsignal import *
+WIN32 = sys.platform == 'win32'
class SignalActionFlag(AbstractActionFlag):
# This class uses the C-level pypysig_counter variable as the tick
@@ -144,7 +145,10 @@
None -- if an unknown handler is in effect (XXX UNIMPLEMENTED)
anything else -- the callable Python object used as a handler
"""
- check_signum_in_range(space, signum)
+ if WIN32:
+ check_signum_exists(space, signum)
+ else:
+ check_signum_in_range(space, signum)
action = space.check_signal_action
if signum in action.handlers_w:
return action.handlers_w[signum]
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -55,7 +55,7 @@
skip("requires os.kill() and os.getpid()")
signal = self.signal # the signal module to test
if not hasattr(signal, 'SIGUSR1'):
- py.test.skip("requires SIGUSR1 in signal")
+ skip("requires SIGUSR1 in signal")
signum = signal.SIGUSR1
received = []
@@ -156,6 +156,7 @@
import sys
if sys.platform == 'win32':
raises(ValueError, signal, 42, lambda *args: None)
+ raises(ValueError, signal, 7, lambda *args: None)
else:
signal(42, lambda *args: None)
signal(42, SIG_DFL)
diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py
--- a/pypy/module/sys/app.py
+++ b/pypy/module/sys/app.py
@@ -66,11 +66,11 @@
return None
copyright_str = """
-Copyright 2003-2012 PyPy development team.
+Copyright 2003-2013 PyPy development team.
All Rights Reserved.
For further information, see <http://pypy.org>
-Portions Copyright (c) 2001-2012 Python Software Foundation.
+Portions Copyright (c) 2001-2013 Python Software Foundation.
All Rights Reserved.
Portions Copyright (c) 2000 BeOpen.com.
diff --git a/pypy/tool/option.py b/pypy/tool/option.py
--- a/pypy/tool/option.py
+++ b/pypy/tool/option.py
@@ -6,7 +6,7 @@
import optparse
extra_useage = """For detailed descriptions of all the options see
-http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html"""
+http://doc.pypy.org/en/latest/config/commandline.html"""
def get_standard_options():
config = get_pypy_config()
diff --git a/pypy/tool/pypyjit_child.py b/pypy/tool/pypyjit_child.py
--- a/pypy/tool/pypyjit_child.py
+++ b/pypy/tool/pypyjit_child.py
@@ -15,7 +15,7 @@
interp.heap.malloc_nonmovable = returns_null # XXX
from rpython.jit.backend.llgraph.runner import LLtypeCPU
- #LLtypeCPU.supports_floats = False # for now
+ #LLtypeCPU.supports_floats = False # for now
apply_jit(interp, graph, LLtypeCPU)
diff --git a/pypy/tool/release/make_release.py b/pypy/tool/release/make_release.py
deleted file mode 100755
--- a/pypy/tool/release/make_release.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-
-""" A tool to download correct pypy-c's from nightly build run and package them
-into release packages. Note: you must run apropriate buildbots first and
-make sure there are no failures. Use force-builds.py from the same directory.
-
-Usage: make_release.py <branchname> <version>
- e.g.: make_release.py release-1.4.1 1.4.1
-"""
-
-import sys
-import urllib2
-from xml.dom import minidom
-import re
-import py
-from rpython.tool.udir import udir
-from pypy.tool.release.package import package
-import tarfile
-import os
-import shutil
-
-BASEURL = 'http://buildbot.pypy.org/nightly/'
-PAUSE = False
-
-def browse_nightly(branch,
- baseurl=BASEURL,
- override_xml=None):
- if override_xml is None:
- url = baseurl + branch + '/'
- xml = urllib2.urlopen(url).read()
- else:
- xml = override_xml
- dom = minidom.parseString(xml)
- refs = [node.getAttribute('href') for node in dom.getElementsByTagName('a')
- if 'pypy' in node.getAttribute('href')]
- # all refs are of form: pypy-c-{type}-{revnum}-{hghash}-{platform}.tar.bz2
- r = re.compile('pypy-c-([\w\d]+)-(\d+)-([0-9a-f]+)-([\w\d]+).tar.bz2$')
- d = {}
- for ref in refs:
- kind, revnum, hghash, platform = r.match(ref).groups()
- rev = int(revnum)
- try:
- lastrev, _ = d[(kind, platform)]
- except KeyError:
- lastrev = -1
- if rev > lastrev:
- d[(kind, platform)] = rev, ref
- return d
-
-def main(branch, release):
- to_download = browse_nightly(branch)
- tmpdir = udir.join('download')
- tmpdir.ensure(dir=True)
- alltars = []
- olddir = os.getcwd()
- try:
- os.chdir(str(tmpdir))
- print 'Using tmpdir', str(tmpdir)
- for (kind, platform), (rev, name) in to_download.iteritems():
- if platform == 'win32':
- print 'Ignoring %s, windows unsupported' % name
- else:
- print "Downloading %s at rev %d" % (name, rev)
- url = BASEURL + branch + "/" + name
- data = urllib2.urlopen(url).read()
- tmpdir.join(name).write(data, mode="wb")
- t = tarfile.open(str(tmpdir.join(name)))
- dirname = t.getmembers()[0].name
- t.extractall(path=str(tmpdir))
- if kind == 'jit':
- kind = ''
- else:
- kind = '-' + kind
- topdirname = 'pypy-%s-%s%s' % (release, platform, kind)
- os.system('mv %s %s' % (str(tmpdir.join(dirname)),
- str(tmpdir.join(topdirname))))
- if PAUSE:
- print 'Pausing, press Enter...'
- raw_input()
- name = '%s.tar.bz2' % topdirname
- print "Building %s" % name
- t = tarfile.open(name, 'w:bz2')
- t.add(topdirname)
- alltars.append(name)
- t.close()
- shutil.rmtree(str(tmpdir.join(topdirname)))
- for name in alltars:
- print "Uploading %s" % name
- os.system('scp %s codespeak.net:/www/pypy.org/htdocs/download' % name)
- finally:
- os.chdir(olddir)
-
-if __name__ == '__main__':
- if len(sys.argv) != 3:
- print __doc__
- sys.exit(1)
- main(sys.argv[1], release=sys.argv[2])
-
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -121,7 +121,7 @@
try:
os.chdir(str(builddir))
#
- # 'strip' fun: see https://codespeak.net/issue/pypy-dev/issue587
+ # 'strip' fun: see issue #587
for source, target in binaries:
if sys.platform == 'win32':
pass
diff --git a/pypy/tool/release/test/test_make_release.py b/pypy/tool/release/test/test_make_release.py
deleted file mode 100644
--- a/pypy/tool/release/test/test_make_release.py
+++ /dev/null
@@ -1,11 +0,0 @@
-
-import py
-from pypy.tool.release.make_release import browse_nightly
-
-XML = py.path.local(__file__).join('..', 'nightly.xml').read()
-
-def test_browse_nightly():
- res = browse_nightly('branch', override_xml=XML)
- assert res[('jit', 'linux')] == (40170, 'pypy-c-jit-40170-c407c9dc5382-linux.tar.bz2')
- assert len(res) == 6
- assert res[('nojit', 'linux64')] == (40170, 'pypy-c-nojit-40170-c407c9dc5382-linux64.tar.bz2')
diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -8,18 +8,17 @@
from rpython.flowspace.objspace import FlowObjSpace
from rpython.flowspace.flowcontext import FlowingError, FlowSpaceFrame
from rpython.conftest import option
-from rpython.tool.stdlib_opcode import bytecode_spec, host_bytecode_spec
+from rpython.tool.stdlib_opcode import host_bytecode_spec
import os
import operator
is_operator = getattr(operator, 'is_', operator.eq) # it's not there 2.2
@contextmanager
-def patching_opcodes(*opcodes):
+def patching_opcodes(**opcodes):
meth_names = host_bytecode_spec.method_names
- opnums = [bytecode_spec.opmap[name] for name in opcodes]
old_name = {}
- for name, num in zip(opcodes, opnums):
+ for name, num in opcodes.items():
old_name[num] = meth_names[num]
meth_names[num] = name
yield
@@ -898,7 +897,7 @@
""" Tests code generated by pypy-c compiled with CALL_METHOD
bytecode
"""
- with patching_opcodes('CALL_METHOD', 'LOOKUP_METHOD'):
+ with patching_opcodes(CALL_METHOD=202, LOOKUP_METHOD=201):
class X:
def m(self):
return 3
@@ -922,7 +921,7 @@
""" Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
bytecode
"""
- with patching_opcodes('BUILD_LIST_FROM_ARG'):
+ with patching_opcodes(BUILD_LIST_FROM_ARG=203):
def f():
return [i for i in "abc"]
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
@@ -1,5 +1,6 @@
from __future__ import with_statement
import os
+from rpython.jit.backend.llsupport import jitframe
from rpython.jit.backend.arm.helper.assembler import saved_registers
from rpython.jit.backend.arm import conditions as c
from rpython.jit.backend.arm import registers as r
@@ -25,12 +26,12 @@
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.jit.backend.arm.opassembler import ResOpAssembler
from rpython.rlib.debug import (debug_print, debug_start, debug_stop,
- have_debug_prints)
+ have_debug_prints, fatalerror)
from rpython.rlib.jit import AsmInfo
from rpython.rlib.objectmodel import compute_unique_id
# XXX Move to llsupport
-from rpython.jit.backend.x86.support import values_array, memcpy_fn
+from rpython.jit.backend.x86.support import memcpy_fn
DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed),
('type', lltype.Char), # 'b'ridge, 'l'abel or
@@ -44,14 +45,8 @@
debug = True
- def __init__(self, cpu, failargs_limit=1000):
+ def __init__(self, cpu, translate_support_code=False):
self.cpu = cpu
- self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
- self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
- failargs_limit)
- self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
- self.fail_boxes_count = 0
- self.fail_force_index = 0
self.setup_failure_recovery()
self.mc = None
self.memcpy_addr = 0
@@ -68,6 +63,7 @@
self._debug = False
self.loop_run_counters = []
self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i')
+ self.force_token_to_dead_frame = {} # XXX temporary hack
def set_debug(self, v):
r = self._debug
@@ -112,9 +108,13 @@
gc_ll_descr.initialize()
self._build_wb_slowpath(False)
self._build_wb_slowpath(True)
+ self._build_failure_recovery(exc=True, withfloats=False)
+ self._build_failure_recovery(exc=False, withfloats=False)
if self.cpu.supports_floats:
self._build_wb_slowpath(False, withfloats=True)
self._build_wb_slowpath(True, withfloats=True)
+ self._build_failure_recovery(exc=True, withfloats=True)
+ self._build_failure_recovery(exc=False, withfloats=True)
self._build_propagate_exception_path()
if gc_ll_descr.get_malloc_slowpath_addr is not None:
self._build_malloc_slowpath()
@@ -122,10 +122,7 @@
if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack:
self._build_release_gil(gc_ll_descr.gcrootmap)
self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
- self._exit_code_addr = self._gen_exit_path()
- self._leave_jitted_hook_save_exc = \
- self._gen_leave_jitted_hook_code(True)
- self._leave_jitted_hook = self._gen_leave_jitted_hook_code(False)
+
if not self._debug:
# if self._debug is already set it means that someone called
# set_debug by hand before initializing the assembler. Leave it
@@ -220,36 +217,17 @@
self.releasegil_addr = rffi.cast(lltype.Signed, releasegil_func)
self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func)
- def _gen_leave_jitted_hook_code(self, save_exc):
- mc = ARMv7Builder()
- if self.cpu.supports_floats:
- floats = r.caller_vfp_resp
- else:
- floats = []
- with saved_registers(mc, r.caller_resp + [r.lr], floats):
- addr = self.cpu.get_on_leave_jitted_int(save_exception=save_exc)
- mc.BL(addr)
- assert self._exit_code_addr != 0
- mc.B(self._exit_code_addr)
- return mc.materialize(self.cpu.asmmemmgr, [],
- self.cpu.gc_ll_descr.gcrootmap)
-
def _build_propagate_exception_path(self):
if self.cpu.propagate_exception_v < 0:
return # not supported (for tests, or non-translated)
#
mc = ARMv7Builder()
- # call on_leave_jitted_save_exc()
- if self.cpu.supports_floats:
- floats = r.caller_vfp_resp
- else:
- floats = []
- with saved_registers(mc, r.caller_resp + [r.lr], floats):
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True,
- default_to_memoryerror=True)
- mc.BL(addr)
- mc.gen_load_int(r.ip.value, self.cpu.propagate_exception_v)
- mc.MOV_rr(r.r0.value, r.ip.value)
+ #
+ # Call the helper, which will return a dead frame object with
+ # the correct exception set, or MemoryError by default
+ # XXX make sure we return the correct value here
+ addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception())
+ mc.BL(addr)
self.gen_func_epilog(mc=mc)
self.propagate_exception_path = mc.materialize(self.cpu.asmmemmgr, [])
@@ -282,12 +260,12 @@
# restore registers and return
# We check for c.EQ here, meaning all bits zero in this case
mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value], cond=c.EQ)
- # call on_leave_jitted_save_exc()
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
+ #
+ # Call the helper, which will return a dead frame object with
+ # the correct exception set, or MemoryError by default
+ addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception())
mc.BL(addr)
#
- mc.gen_load_int(r.r0.value, self.cpu.propagate_exception_v)
- #
# footer -- note the ADD, which skips the return address of this
# function, and will instead return to the caller's caller. Note
# also that we completely ignore the saved arguments, because we
@@ -339,39 +317,82 @@
def setup_failure_recovery(self):
- @rgc.no_collect
+ #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold
def failure_recovery_func(mem_loc, frame_pointer, stack_pointer):
"""mem_loc is a structure in memory describing where the values for
the failargs are stored. frame loc is the address of the frame
pointer for the frame to be decoded frame """
- vfp_registers = rffi.cast(rffi.LONGLONGP, stack_pointer)
- registers = rffi.ptradd(vfp_registers, len(r.all_vfp_regs))
+ vfp_registers = rffi.cast(rffi.LONGP, stack_pointer)
+ registers = rffi.ptradd(vfp_registers, 2*len(r.all_vfp_regs))
registers = rffi.cast(rffi.LONGP, registers)
- return self.decode_registers_and_descr(mem_loc, frame_pointer,
+ bytecode = rffi.cast(rffi.UCHARP, mem_loc)
+ return self.grab_frame_values(self.cpu, bytecode, frame_pointer,
registers, vfp_registers)
+ self.failure_recovery_code = [0, 0, 0, 0]
self.failure_recovery_func = failure_recovery_func
- recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed] * 3,
- lltype.Signed))
+ _FAILURE_RECOVERY_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP] * 3,
+ llmemory.GCREF))
- @rgc.no_collect
- def decode_registers_and_descr(self, mem_loc, frame_pointer,
+ @staticmethod
+ #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold
+ def grab_frame_values(cpu, bytecode, frame_pointer,
registers, vfp_registers):
- """Decode locations encoded in memory at mem_loc and write the values
- to the failboxes. Values for spilled vars and registers are stored on
- stack at frame_loc """
- assert frame_pointer & 1 == 0
- self.fail_force_index = frame_pointer
- bytecode = rffi.cast(rffi.UCHARP, mem_loc)
+ # no malloc allowed here!! xxx apart from one, hacking a lot
+ force_index = rffi.cast(lltype.Signed, frame_pointer)
num = 0
- value = 0
- fvalue = 0
+ deadframe = lltype.nullptr(jitframe.DEADFRAME)
+ # step 1: lots of mess just to count the final value of 'num'
+ bytecode1 = bytecode
+ while 1:
+ code = rffi.cast(lltype.Signed, bytecode1[0])
+ bytecode1 = rffi.ptradd(bytecode1, 1)
+ if code >= AssemblerARM.CODE_FROMSTACK:
+ while code > 0x7F:
+ code = rffi.cast(lltype.Signed, bytecode1[0])
+ bytecode1 = rffi.ptradd(bytecode1, 1)
+ else:
+ kind = code & 3
+ if kind == AssemblerARM.DESCR_SPECIAL:
+ if code == AssemblerARM.CODE_HOLE:
+ num += 1
+ continue
+ if code == AssemblerARM.CODE_INPUTARG:
+ continue
+ if code == AssemblerARM.CODE_FORCED:
+ # resuming from a GUARD_NOT_FORCED
+ token = force_index
+ deadframe = (
+ cpu.assembler.force_token_to_dead_frame.pop(token))
+ deadframe = lltype.cast_opaque_ptr(
+ jitframe.DEADFRAMEPTR, deadframe)
+ continue
+ assert code == AssemblerARM.CODE_STOP
+ break
+ num += 1
+
+ # allocate the deadframe
+ if not deadframe:
+ # Remove the "reserve" at the end of the nursery. This means
+ # that it is guaranteed that the following malloc() works
+ # without requiring a collect(), but it needs to be re-added
+ # as soon as possible.
+ cpu.gc_clear_extra_threshold()
+ assert num <= cpu.get_failargs_limit()
+ try:
+ deadframe = lltype.malloc(jitframe.DEADFRAME, num)
+ except MemoryError:
+ fatalerror("memory usage error in grab_frame_values")
+ # fill it
code_inputarg = False
- while True:
+ num = 0
+ value_hi = 0
+ while 1:
+ # decode the next instruction from the bytecode
code = rffi.cast(lltype.Signed, bytecode[0])
bytecode = rffi.ptradd(bytecode, 1)
- if code >= self.CODE_FROMSTACK:
+ if code >= AssemblerARM.CODE_FROMSTACK:
if code > 0x7F:
shift = 7
code &= 0x7F
@@ -384,54 +405,63 @@
break
# load the value from the stack
kind = code & 3
- code = int((code - self.CODE_FROMSTACK) >> 2)
+ code = (code - AssemblerARM.CODE_FROMSTACK) >> 2
if code_inputarg:
code = ~code
code_inputarg = False
- if kind == self.DESCR_FLOAT:
- # we use code + 1 to get the hi word of the double worded float
- stackloc = frame_pointer - get_fp_offset(int(code) + 1)
- assert stackloc & 3 == 0
- fvalue = rffi.cast(rffi.LONGLONGP, stackloc)[0]
- else:
- stackloc = frame_pointer - get_fp_offset(int(code))
- assert stackloc & 1 == 0
- value = rffi.cast(rffi.LONGP, stackloc)[0]
+ stackloc = force_index - get_fp_offset(int(code))
+ value = rffi.cast(rffi.LONGP, stackloc)[0]
+ if kind == AssemblerARM.DESCR_FLOAT:
+ assert WORD == 4
+ value_hi = value
+ value = rffi.cast(rffi.LONGP, stackloc - WORD)[0]
else:
- # 'code' identifies a register: load its value
kind = code & 3
- if kind == self.DESCR_SPECIAL:
- if code == self.CODE_HOLE:
+ if kind == AssemblerARM.DESCR_SPECIAL:
+ if code == AssemblerARM.CODE_HOLE:
num += 1
continue
- if code == self.CODE_INPUTARG:
+ if code == AssemblerARM.CODE_INPUTARG:
code_inputarg = True
continue
- assert code == self.CODE_STOP
+ if code == AssemblerARM.CODE_FORCED:
+ continue
+ assert code == AssemblerARM.CODE_STOP
break
+ # 'code' identifies a register: load its value
code >>= 2
- if kind == self.DESCR_FLOAT:
- fvalue = vfp_registers[code]
+ if kind == AssemblerARM.DESCR_FLOAT:
+ if WORD == 4:
+ value = vfp_registers[2*code]
+ value_hi = vfp_registers[2*code + 1]
+ else:
+ value = registers[code]
else:
value = registers[code]
# store the loaded value into fail_boxes_<type>
- if kind == self.DESCR_FLOAT:
- tgt = self.fail_boxes_float.get_addr_for_num(num)
- rffi.cast(rffi.LONGLONGP, tgt)[0] = fvalue
+ if kind == AssemblerARM.DESCR_INT:
+ deadframe.jf_values[num].int = value
+ elif kind == AssemblerARM.DESCR_REF:
+ deadframe.jf_values[num].ref = rffi.cast(llmemory.GCREF, value)
+ elif kind == AssemblerARM.DESCR_FLOAT:
+ assert WORD == 4
+ assert not longlong.is_64_bit
+ floatvalue = rffi.cast(lltype.SignedLongLong, value_hi)
+ floatvalue <<= 32
+ floatvalue |= rffi.cast(lltype.SignedLongLong,
+ rffi.cast(lltype.Unsigned, value))
+ deadframe.jf_values[num].float = floatvalue
else:
- if kind == self.DESCR_INT:
- tgt = self.fail_boxes_int.get_addr_for_num(num)
- elif kind == self.DESCR_REF:
- assert (value & 3) == 0, "misaligned pointer"
- tgt = self.fail_boxes_ptr.get_addr_for_num(num)
- else:
- assert 0, "bogus kind"
- rffi.cast(rffi.LONGP, tgt)[0] = value
+ assert 0, "bogus kind"
num += 1
- self.fail_boxes_count = num
+ #
+ assert num == len(deadframe.jf_values)
+ if not we_are_translated():
+ assert bytecode[4] == 0xCC
fail_index = rffi.cast(rffi.INTP, bytecode)[0]
- fail_index = rffi.cast(lltype.Signed, fail_index)
- return fail_index
+ fail_descr = cpu.get_fail_descr_from_number(fail_index)
+ deadframe.jf_descr = fail_descr.hide(cpu)
+ return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe)
def decode_inputargs(self, code):
descr_to_box_type = [REF, INT, FLOAT]
@@ -514,12 +544,26 @@
self.mc.CMP_ri(r.r0.value, 0)
self.mc.B(self.propagate_exception_path, c=c.EQ)
- def _gen_exit_path(self):
+ def _build_failure_recovery(self, exc, withfloats=False):
mc = ARMv7Builder()
- decode_registers_addr = llhelper(self.recovery_func_sign,
+ failure_recovery = llhelper(self._FAILURE_RECOVERY_FUNC,
self.failure_recovery_func)
self._insert_checks(mc)
- with saved_registers(mc, r.all_regs, r.all_vfp_regs):
+ if withfloats:
+ f = r.all_vfp_regs
+ else:
+ f = []
+ with saved_registers(mc, r.all_regs, f):
+ if exc:
+ # We might have an exception pending. Load it into r4
+ # (this is a register saved across calls)
+ mc.gen_load_int(r.r5.value, self.cpu.pos_exc_value())
+ mc.LDR_ri(r.r4.value, self.cpu.pos_exc_value())
+ # clear the exc flags
+ mc.gen_load_int(r.r6.value, 0)
+ mc.STR_ri(r.r6.value, r.r5.value)
+ mc.gen_load_int(r.r5.value, self.cpu.pos_exception())
+ mc.STR_ri(r.r6.value, r.r5.value)
# move mem block address, to r0 to pass as
mc.MOV_rr(r.r0.value, r.lr.value)
# pass the current frame pointer as second param
@@ -527,23 +571,32 @@
# pass the current stack pointer as third param
mc.MOV_rr(r.r2.value, r.sp.value)
self._insert_checks(mc)
- mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
+ mc.BL(rffi.cast(lltype.Signed, failure_recovery))
+ if exc:
+ # save ebx into 'jf_guard_exc'
+ from pypy.jit.backend.llsupport.descr import unpack_fielddescr
+ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+ offset, size, _ = unpack_fielddescr(descrs.jf_guard_exc)
+ mc.STR_rr(r.r4.value, r.r0.value, offset, cond=c.AL)
mc.MOV_rr(r.ip.value, r.r0.value)
mc.MOV_rr(r.r0.value, r.ip.value)
self.gen_func_epilog(mc=mc)
- return mc.materialize(self.cpu.asmmemmgr, [],
+ rawstart = mc.materialize(self.cpu.asmmemmgr, [],
self.cpu.gc_ll_descr.gcrootmap)
+ self.failure_recovery_code[exc + 2 * withfloats] = rawstart
+ self.mc = None
DESCR_REF = 0x00
DESCR_INT = 0x01
DESCR_FLOAT = 0x02
DESCR_SPECIAL = 0x03
CODE_FROMSTACK = 64
- CODE_STOP = 0 | DESCR_SPECIAL
- CODE_HOLE = 4 | DESCR_SPECIAL
- CODE_INPUTARG = 8 | DESCR_SPECIAL
+ CODE_STOP = 0 | DESCR_SPECIAL
+ CODE_HOLE = 4 | DESCR_SPECIAL
+ CODE_INPUTARG = 8 | DESCR_SPECIAL
+ CODE_FORCED = 12 | DESCR_SPECIAL #XXX where should this be written?
- def gen_descr_encoding(self, descr, failargs, locs):
+ def write_failure_recovery_description(self, descr, failargs, locs):
assert self.mc is not None
for i in range(len(failargs)):
arg = failargs[i]
@@ -575,26 +628,33 @@
self.mc.writechar(chr(n))
self.mc.writechar(chr(self.CODE_STOP))
- fdescr = self.cpu.get_fail_descr_number(descr)
- self.mc.write32(fdescr)
+
+ def generate_quick_failure(self, guardtok, fcond=c.AL):
+ assert isinstance(guardtok.save_exc, bool)
+ fail_index = self.cpu.get_fail_descr_number(guardtok.descr)
+ startpos = self.mc.currpos()
+ withfloats = False
+ for box in guardtok.failargs:
+ if box is not None and box.type == FLOAT:
+ withfloats = True
+ break
+ exc = guardtok.save_exc
+ target = self.failure_recovery_code[exc + 2 * withfloats]
+ assert target != 0
+ self.mc.BL(target)
+ # write tight data that describes the failure recovery
+ if guardtok.is_guard_not_forced:
+ self.mc.writechar(chr(self.CODE_FORCED))
+ self.write_failure_recovery_description(guardtok.descr,
+ guardtok.failargs, guardtok.faillocs[1:])
+ self.mc.write32(fail_index)
+ # for testing the decoding, write a final byte 0xCC
+ if not we_are_translated():
+ self.mc.writechar('\xCC')
+ faillocs = [loc for loc in guardtok.faillocs if loc is not None]
+ guardtok.descr._arm_debug_faillocs = faillocs
self.align()
-
- # assert that the fail_boxes lists are big enough
- assert len(failargs) <= self.fail_boxes_int.SIZE
-
- def _gen_path_to_exit_path(self, descr, args, arglocs,
- save_exc, fcond=c.AL):
- assert isinstance(save_exc, bool)
- self.gen_exit_code(self.mc, save_exc, fcond)
- self.gen_descr_encoding(descr, args, arglocs[1:])
-
- def gen_exit_code(self, mc, save_exc, fcond=c.AL):
- assert isinstance(save_exc, bool)
- if save_exc:
- path = self._leave_jitted_hook_save_exc
- else:
- path = self._leave_jitted_hook
- mc.BL(path)
+ return startpos
def align(self):
while(self.mc.currpos() % FUNC_ALIGN != 0):
@@ -841,15 +901,10 @@
def write_pending_failure_recoveries(self):
for tok in self.pending_guards:
- descr = tok.descr
#generate the exit stub and the encoded representation
- pos = self.mc.currpos()
- tok.pos_recovery_stub = pos
-
- self._gen_path_to_exit_path(descr, tok.failargs,
- tok.faillocs, save_exc=tok.save_exc)
+ tok.pos_recovery_stub = self.generate_quick_failure(tok)
# store info on the descr
- descr._arm_current_frame_depth = tok.faillocs[0].getint()
+ tok.descr._arm_current_frame_depth = tok.faillocs[0].getint()
def process_pending_guards(self, block_start):
clt = self.current_clt
@@ -860,7 +915,7 @@
descr._arm_failure_recovery_block = failure_recovery_pos
relative_offset = tok.pos_recovery_stub - tok.offset
guard_pos = block_start + tok.offset
- if not tok.is_invalidate:
+ if not tok.is_guard_not_invalidated:
# patch the guard jumpt to the stub
# overwrite the generate NOP with a B_offs to the pos of the
# stub
@@ -1255,11 +1310,6 @@
else:
raise AssertionError('Trying to pop to an invalid location')
- def leave_jitted_hook(self):
- ptrs = self.fail_boxes_ptr.ar
- llop.gc_assume_young_pointers(lltype.Void,
- llmemory.cast_ptr_to_adr(ptrs))
-
def malloc_cond(self, nursery_free_adr, nursery_top_adr, size):
assert size & (WORD-1) == 0 # must be correctly aligned
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
@@ -16,6 +16,7 @@
gen_emit_unary_float_op,
saved_registers,
count_reg_args)
+from rpython.jit.backend.arm.helper.regalloc import check_imm_arg
from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
from rpython.jit.backend.arm.jump import remap_frame_layout
from rpython.jit.backend.arm.regalloc import TempInt, TempPtr
@@ -27,18 +28,20 @@
from rpython.jit.metainterp.history import JitCellToken, TargetToken
from rpython.jit.metainterp.resoperation import rop
from rpython.rlib.objectmodel import we_are_translated
-from rpython.rtyper.lltypesystem import rstr
+from rpython.rlib import rgc
+from rpython.rtyper.lltypesystem import rstr, rffi, lltype, llmemory
NO_FORCE_INDEX = -1
class GuardToken(object):
- def __init__(self, descr, failargs, faillocs, offset,
- save_exc, fcond=c.AL, is_invalidate=False):
+ def __init__(self, descr, failargs, faillocs, offset, save_exc, fcond=c.AL,
+ is_guard_not_invalidated=False, is_guard_not_forced=False):
assert isinstance(save_exc, bool)
self.descr = descr
self.offset = offset
- self.is_invalidate = is_invalidate
+ self.is_guard_not_invalidated = is_guard_not_invalidated
+ self.is_guard_not_forced = is_guard_not_forced
self.failargs = failargs
self.faillocs = faillocs
self.save_exc = save_exc
@@ -190,7 +193,8 @@
return fcond
def _emit_guard(self, op, arglocs, fcond, save_exc,
- is_guard_not_invalidated=False):
+ is_guard_not_invalidated=False,
+ is_guard_not_forced=False):
assert isinstance(save_exc, bool)
assert isinstance(fcond, int)
descr = op.getdescr()
@@ -210,7 +214,8 @@
faillocs=arglocs,
offset=pos,
save_exc=save_exc,
- is_invalidate=is_guard_not_invalidated,
+ is_guard_not_invalidated=is_guard_not_invalidated,
+ is_guard_not_forced=is_guard_not_forced,
fcond=fcond))
return c.AL
@@ -312,49 +317,10 @@
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
- for i in range(len(arglocs) - 1):
- loc = arglocs[i]
- box = op.getarg(i)
- if loc is None:
- continue
- if loc.is_reg():
- if box.type == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(i)
- elif box.type == INT:
- adr = self.fail_boxes_int.get_addr_for_num(i)
- else:
- assert 0
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.STR_ri(loc.value, r.ip.value)
- elif loc.is_vfp_reg():
- assert box.type == FLOAT
- adr = self.fail_boxes_float.get_addr_for_num(i)
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.VSTR(loc.value, r.ip.value)
- elif loc.is_stack() or loc.is_imm() or loc.is_imm_float():
- if box.type == FLOAT:
- adr = self.fail_boxes_float.get_addr_for_num(i)
- self.mov_loc_loc(loc, r.vfp_ip)
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.VSTR(r.vfp_ip.value, r.ip.value)
- elif box.type == REF or box.type == INT:
- if box.type == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(i)
- elif box.type == INT:
- adr = self.fail_boxes_int.get_addr_for_num(i)
- else:
- assert 0
- self.mov_loc_loc(loc, r.ip)
- self.mc.gen_load_int(r.lr.value, adr)
- self.mc.STR_ri(r.ip.value, r.lr.value)
- else:
- assert 0
- # note: no exception should currently be set in llop.get_exception_addr
- # even if this finish may be an exit_frame_with_exception (in this case
- # the exception instance is in arglocs[0]).
- addr = self.cpu.get_on_leave_jitted_int(save_exception=False)
- self.mc.BL(addr)
- self.mc.gen_load_int(r.r0.value, arglocs[-1].value)
+ [argloc] = arglocs
+ if argloc is not r.r0: #XXX verify this
+ self.mov_loc_loc(argloc, r.r0, fcond)
+ # exit function
self.gen_func_epilog()
return fcond
@@ -1152,8 +1118,26 @@
value = self.cpu.done_with_this_frame_float_v
else:
raise AssertionError(kind)
- self.mc.gen_load_int(r.ip.value, value)
- self.mc.CMP_rr(tmploc.value, r.ip.value)
+ from pypy.jit.backend.llsupport.descr import unpack_fielddescr
+ from pypy.jit.backend.llsupport.descr import unpack_interiorfielddescr
+ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+ _offset, _size, _ = unpack_fielddescr(descrs.jf_descr)
+ fail_descr = self.cpu.get_fail_descr_from_number(value)
+ value = fail_descr.hide(self.cpu)
+ rgc._make_sure_does_not_move(value)
+ value = rffi.cast(lltype.Signed, value)
+
+ if check_imm_arg(_offset):
+ self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset)
+ else:
+ self.mc.gen_load_int(r.ip.value, _offset)
+ self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value)
+ if check_imm_arg(value):
+ self.mc.CMP_ri(r.ip.value, imm=value)
+ else:
+ self.mc.gen_load_int(r.lr.value, value)
+ self.mc.CMP_rr(r.lr.value, r.ip.value)
+
#if values are equal we take the fast path
# Slow path, calling helper
@@ -1180,19 +1164,31 @@
if op.result is not None:
# load the return value from fail_boxes_xxx[0]
kind = op.result.type
- if kind == INT:
- adr = self.fail_boxes_int.get_addr_for_num(0)
- elif kind == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(0)
- elif kind == FLOAT:
- adr = self.fail_boxes_float.get_addr_for_num(0)
+ if kind == FLOAT:
+ t = unpack_interiorfielddescr(descrs.as_float)[0]
+ if not check_imm_arg(t):
+ self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond)
+ self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value,
+ cond=fast_path_cond)
+ t = 0
+ base = r.ip
+ else:
+ base = r.r0
+ self.mc.VLDR(resloc.value, base.value, imm=t,
+ cond=fast_path_cond)
else:
- raise AssertionError(kind)
- self.mc.gen_load_int(r.ip.value, adr, cond=fast_path_cond)
- if op.result.type == FLOAT:
- self.mc.VLDR(resloc.value, r.ip.value, cond=fast_path_cond)
- else:
- self.mc.LDR_ri(resloc.value, r.ip.value, cond=fast_path_cond)
+ assert resloc is r.r0
+ if kind == INT:
+ t = unpack_interiorfielddescr(descrs.as_int)[0]
+ else:
+ t = unpack_interiorfielddescr(descrs.as_ref)[0]
+ if not check_imm_arg(t):
+ self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond)
+ self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value,
+ cond=fast_path_cond)
+ else:
+ self.mc.LDR_ri(resloc.value, resloc.value, imm=t,
+ cond=fast_path_cond)
# jump to merge point
jmp_pos = self.mc.currpos()
self.mc.BKPT()
@@ -1266,7 +1262,8 @@
self.mc.LDR_ri(r.ip.value, r.fp.value)
self.mc.CMP_ri(r.ip.value, 0)
- self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE, save_exc=True)
+ self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE,
+ save_exc=True, is_guard_not_forced=True)
return fcond
def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc,
diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -644,15 +644,9 @@
return args
def prepare_op_finish(self, op, fcond):
- args = [None] * (op.numargs() + 1)
- for i in range(op.numargs()):
- arg = op.getarg(i)
- if arg:
- args[i] = self.loc(arg)
- self.possibly_free_var(arg)
- n = self.cpu.get_fail_descr_number(op.getdescr())
- args[-1] = imm(n)
- return args
+ loc = self.loc(op.getarg(0))
+ self.possibly_free_var(op.getarg(0))
+ return [loc]
def prepare_op_guard_true(self, op, fcond):
l0 = self.make_sure_var_in_reg(op.getarg(0))
diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -23,15 +23,21 @@
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
+ from pypy.jit.backend.llsupport import jitframe
+ self.deadframe_size_max = llmemory.sizeof(jitframe.DEADFRAME,
+ self.get_failargs_limit())
+
def set_debug(self, flag):
return self.assembler.set_debug(flag)
+ def get_failargs_limit(self):
+ if self.opts is not None:
+ return self.opts.failargs_limit
+ else:
+ return 1000
+
def setup(self):
- if self.opts is not None:
- failargs_limit = self.opts.failargs_limit
- else:
- failargs_limit = 1000
- self.assembler = AssemblerARM(self, failargs_limit=failargs_limit)
+ self.assembler = AssemblerARM(self, self.translate_support_code)
def setup_once(self):
self.assembler.setup_once()
@@ -51,24 +57,6 @@
return self.assembler.assemble_bridge(faildescr, inputargs, operations,
original_loop_token, log=log)
- def get_latest_value_float(self, index):
- return self.assembler.fail_boxes_float.getitem(index)
-
- def get_latest_value_int(self, index):
- return self.assembler.fail_boxes_int.getitem(index)
-
- def get_latest_value_ref(self, index):
- return self.assembler.fail_boxes_ptr.getitem(index)
-
- def get_latest_value_count(self):
- return self.assembler.fail_boxes_count
-
- def get_latest_force_token(self):
- return self.assembler.fail_force_index
-
- def get_on_leave_jitted_hook(self):
- return self.assembler.leave_jitted_hook
-
def clear_latest_values(self, count):
setitem = self.assembler.fail_boxes_ptr.setitem
null = lltype.nullptr(llmemory.GCREF.TO)
@@ -76,7 +64,7 @@
setitem(index, null)
def make_execute_token(self, *ARGS):
- FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
+ FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, llmemory.GCREF))
def execute_token(executable_token, *args):
clt = executable_token.compiled_loop_token
@@ -91,12 +79,13 @@
prev_interpreter = LLInterpreter.current_interpreter
LLInterpreter.current_interpreter = self.debug_ll_interpreter
try:
- fail_index = func(*args)
+ deadframe = func(*args)
finally:
if not self.translate_support_code:
More information about the pypy-commit
mailing list