[pypy-commit] pypy new-jit-log: merge default
plan_rich
pypy.commits at gmail.com
Thu Jul 21 09:18:15 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: new-jit-log
Changeset: r85790:3a2bd151550e
Date: 2016-07-21 14:59 +0200
http://bitbucket.org/pypy/pypy/changeset/3a2bd151550e/
Log: merge default
diff --git a/pypy/doc/install.rst b/pypy/doc/install.rst
--- a/pypy/doc/install.rst
+++ b/pypy/doc/install.rst
@@ -39,17 +39,16 @@
library.
If you want to install 3rd party libraries, the most convenient way is
-to install pip_ (unless you want to install virtualenv as explained
-below; then you can directly use pip inside virtualenvs):
+to install pip_ using ensurepip_ (unless you want to install virtualenv as
+explained below; then you can directly use pip inside virtualenvs):
.. code-block:: console
- $ curl -O https://bootstrap.pypa.io/get-pip.py
- $ ./pypy-2.1/bin/pypy get-pip.py
- $ ./pypy-2.1/bin/pip install pygments # for example
+ $ ./pypy-xxx/bin/pypy -m ensurepip
+ $ ./pypy-xxx/bin/pip install pygments # for example
-Third party libraries will be installed in ``pypy-2.1/site-packages``, and
-the scripts in ``pypy-2.1/bin``.
+Third party libraries will be installed in ``pypy-xxx/site-packages``, and
+the scripts in ``pypy-xxx/bin``.
Installing using virtualenv
@@ -61,7 +60,7 @@
checkout::
# from a tarball
- $ virtualenv -p /opt/pypy-c-jit-41718-3fb486695f20-linux/bin/pypy my-pypy-env
+ $ virtualenv -p /opt/pypy-xxx/bin/pypy my-pypy-env
# from the mercurial checkout
$ virtualenv -p /path/to/pypy/pypy/translator/goal/pypy-c my-pypy-env
@@ -69,7 +68,7 @@
Note that bin/python is now a symlink to bin/pypy.
.. _pip: http://pypi.python.org/pypi/pip
-
+.. _ensurepip: https://docs.python.org/2.7/library/ensurepip.html
Building PyPy yourself
~~~~~~~~~~~~~~~~~~~~~~
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
@@ -424,6 +424,7 @@
--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>)
+ check_memory_error(i119)
raw_store(i119, 0, i160, descr=<ArrayS 2>)
raw_store(i119, 2, i160, descr=<ArrayS 2>)
raw_store(i119, 4, i160, descr=<ArrayS 2>)
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
@@ -82,9 +82,6 @@
self.failure_recovery_code = [0, 0, 0, 0]
def _build_propagate_exception_path(self):
- if not self.cpu.propagate_exception_descr:
- return # not supported (for tests, or non-translated)
- #
mc = InstrBuilder(self.cpu.cpuinfo.arch_version)
self._store_and_reset_exception(mc, r.r0)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
@@ -372,9 +369,9 @@
self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False,
is_frame=True)
- def propagate_memoryerror_if_r0_is_null(self):
- # see ../x86/assembler.py:propagate_memoryerror_if_eax_is_null
- self.mc.CMP_ri(r.r0.value, 0)
+ def propagate_memoryerror_if_reg_is_null(self, reg_loc):
+ # see ../x86/assembler.py:genop_discard_check_memory_error()
+ self.mc.CMP_ri(reg_loc.value, 0)
self.mc.B(self.propagate_exception_path, c=c.EQ)
def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats,
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
@@ -1050,9 +1050,8 @@
regalloc = self._regalloc
return regalloc.operations[regalloc.rm.position + delta]
- def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond):
- self._emit_call(op, arglocs, fcond=fcond)
- self.propagate_memoryerror_if_r0_is_null()
+ def emit_op_check_memory_error(self, op, arglocs, regalloc, fcond):
+ self.propagate_memoryerror_if_reg_is_null(arglocs[0])
self._alignment_check()
return fcond
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
@@ -594,8 +594,9 @@
resloc = self.after_call(op)
return resloc
- def prepare_op_call_malloc_gc(self, op, fcond):
- return self._prepare_call(op)
+ def prepare_op_check_memory_error(self, op, fcond):
+ argloc = self.make_sure_var_in_reg(op.getarg(0))
+ return [argloc]
def _prepare_llong_binop_xx(self, op, fcond):
# arg 0 is the address of the function
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -1521,6 +1521,11 @@
lle = None
self.last_exception = lle
+ def execute_check_memory_error(self, descr, value):
+ if not value:
+ from rpython.jit.backend.llsupport import llmodel
+ raise llmodel.MissingLatestDescrError
+
def _getdescr(op):
d = op.getdescr()
diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -48,7 +48,10 @@
anything, it must be an optional MemoryError.
"""
FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, RESULT))
- descr = get_call_descr(self, ARGS, RESULT)
+ # Note: the call may invoke the GC, which may run finalizers.
+ # Finalizers are constrained in what they can do, but we can't
+ # really express that in a useful way here.
+ descr = get_call_descr(self, ARGS, RESULT, EffectInfo.MOST_GENERAL)
setattr(self, funcname, func)
setattr(self, funcname + '_FUNCPTR', FUNCPTR)
setattr(self, funcname + '_descr', descr)
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
@@ -408,6 +408,9 @@
deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe)
descr = deadframe.jf_descr
res = history.AbstractDescr.show(self, descr)
+ if not we_are_translated(): # tests only: for missing
+ if res is None: # propagate_exception_descr
+ raise MissingLatestDescrError
assert isinstance(res, history.AbstractFailDescr)
return res
@@ -816,6 +819,9 @@
calldescr.call_stub_i(func, args_i, args_r, args_f)
+class MissingLatestDescrError(Exception):
+ """For propagate_exception_descr in untranslated tests."""
+
final_descr_rd_locs = [rffi.cast(rffi.USHORT, 0)]
history.BasicFinalDescr.rd_locs = final_descr_rd_locs
compile._DoneWithThisFrameDescr.rd_locs = final_descr_rd_locs
diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -26,7 +26,8 @@
class GcRewriterAssembler(object):
""" This class performs the following rewrites on the list of operations:
- - Turn all NEW_xxx to either a CALL_MALLOC_GC, or a CALL_MALLOC_NURSERY
+ - Turn all NEW_xxx to either a CALL_R/CHECK_MEMORY_ERROR,
+ or a CALL_MALLOC_NURSERY,
followed by SETFIELDs in order to initialize their GC fields. The
two advantages of CALL_MALLOC_NURSERY is that it inlines the common
path, and we need only one such operation to allocate several blocks
@@ -715,16 +716,17 @@
self._delayed_zero_setfields.clear()
def _gen_call_malloc_gc(self, args, v_result, descr):
- """Generate a CALL_MALLOC_GC with the given args."""
+ """Generate a CALL_R/CHECK_MEMORY_ERROR with the given args."""
self.emitting_an_operation_that_can_collect()
- op = ResOperation(rop.CALL_MALLOC_GC, args, descr=descr)
+ op = ResOperation(rop.CALL_R, args, descr=descr)
self.replace_op_with(v_result, op)
self.emit_op(op)
+ self.emit_op(ResOperation(rop.CHECK_MEMORY_ERROR, [op]))
# In general, don't add v_result to write_barrier_applied:
# v_result might be a large young array.
def gen_malloc_fixedsize(self, size, typeid, v_result):
- """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, ...).
+ """Generate a CALL_R(malloc_fixedsize_fn, ...).
Used on Boehm, and on the framework GC for large fixed-size
mallocs. (For all I know this latter case never occurs in
practice, but better safe than sorry.)
@@ -744,7 +746,7 @@
self.remember_write_barrier(v_result)
def gen_boehm_malloc_array(self, arraydescr, v_num_elem, v_result):
- """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) for Boehm."""
+ """Generate a CALL_R(malloc_array_fn, ...) for Boehm."""
addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_array')
self._gen_call_malloc_gc([ConstInt(addr),
ConstInt(arraydescr.basesize),
@@ -755,7 +757,7 @@
self.gc_ll_descr.malloc_array_descr)
def gen_malloc_array(self, arraydescr, v_num_elem, v_result):
- """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) going either
+ """Generate a CALL_R(malloc_array_fn, ...) going either
to the standard or the nonstandard version of the function."""
#
if (arraydescr.basesize == self.gc_ll_descr.standard_array_basesize
@@ -782,13 +784,13 @@
self._gen_call_malloc_gc(args, v_result, calldescr)
def gen_malloc_str(self, v_num_elem, v_result):
- """Generate a CALL_MALLOC_GC(malloc_str_fn, ...)."""
+ """Generate a CALL_R(malloc_str_fn, ...)."""
addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_str')
self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result,
self.gc_ll_descr.malloc_str_descr)
def gen_malloc_unicode(self, v_num_elem, v_result):
- """Generate a CALL_MALLOC_GC(malloc_unicode_fn, ...)."""
+ """Generate a CALL_R(malloc_unicode_fn, ...)."""
addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_unicode')
self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result,
self.gc_ll_descr.malloc_unicode_descr)
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -254,8 +254,9 @@
jump()
""", """
[p1]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
- descr=malloc_fixedsize_descr)
+ p0 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ check_memory_error(p0)
jump()
""")
@@ -267,10 +268,12 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
- descr=malloc_fixedsize_descr)
- p1 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
- descr=malloc_fixedsize_descr)
+ p0 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ check_memory_error(p0)
+ p1 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ check_memory_error(p1)
jump()
""")
@@ -281,16 +284,17 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_array), \
+ p0 = call_r(ConstClass(malloc_array), \
%(adescr.basesize)d, \
10, \
%(adescr.itemsize)d, \
%(adescr.lendescr.offset)d, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
## should ideally be:
-## p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+## p0 = call_r(ConstClass(malloc_fixedsize), \
## %(adescr.basesize + 10 * adescr.itemsize)d, \
## descr=malloc_fixedsize_descr)
## setfield_gc(p0, 10, descr=alendescr)
@@ -302,12 +306,13 @@
jump()
""", """
[i1]
- p0 = call_malloc_gc(ConstClass(malloc_array), \
+ p0 = call_r(ConstClass(malloc_array), \
%(adescr.basesize)d, \
i1, \
%(adescr.itemsize)d, \
%(adescr.lendescr.offset)d, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
@@ -318,8 +323,9 @@
jump()
""", """
[p1]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), 102, \
+ p0 = call_r(ConstClass(malloc_fixedsize), 102, \
descr=malloc_fixedsize_descr)
+ check_memory_error(p0)
gc_store(p0, 0, ConstClass(o_vtable), %(vtable_descr.field_size)s)
jump()
""")
@@ -331,12 +337,13 @@
jump()
""", """
[i1]
- p0 = call_malloc_gc(ConstClass(malloc_array), \
+ p0 = call_r(ConstClass(malloc_array), \
%(strdescr.basesize)d, \
i1, \
%(strdescr.itemsize)d, \
%(strlendescr.offset)d, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
@@ -347,16 +354,17 @@
jump()
""", """
[i1]
- p0 = call_malloc_gc(ConstClass(malloc_array), \
+ p0 = call_r(ConstClass(malloc_array), \
%(unicodedescr.basesize)d, \
10, \
%(unicodedescr.itemsize)d, \
%(unicodelendescr.offset)d, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
## should ideally be:
-## p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+## p0 = call_r(ConstClass(malloc_fixedsize), \
## %(unicodedescr.basesize + \
## 10 * unicodedescr.itemsize)d, \
## descr=malloc_fixedsize_descr)
@@ -545,11 +553,12 @@
jump(i0)
""", """
[i0, p1]
- p0 = call_malloc_gc(ConstClass(malloc_array_nonstandard), \
+ p0 = call_r(ConstClass(malloc_array_nonstandard), \
64, 8, \
%(nonstd_descr.lendescr.offset)d, \
6464, i0, \
descr=malloc_array_nonstandard_descr)
+ check_memory_error(p0)
cond_call_gc_wb_array(p0, i0, descr=wbdescr)
gc_store_indexed(p0, i0, p1, 8, 64, 8)
jump(i0)
@@ -563,9 +572,10 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_array), 1, \
+ p0 = call_r(ConstClass(malloc_array), 1, \
%(bdescr.tid)d, 103, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
@@ -601,9 +611,10 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_array), 1, \
+ p0 = call_r(ConstClass(malloc_array), 1, \
%(bdescr.tid)d, 20000000, \
descr=malloc_array_descr)
+ check_memory_error(p0)
jump()
""")
@@ -628,8 +639,9 @@
jump()
""", """
[p1]
- p0 = call_malloc_gc(ConstClass(malloc_big_fixedsize), 104, 9315, \
+ p0 = call_r(ConstClass(malloc_big_fixedsize), 104, 9315, \
descr=malloc_big_fixedsize_descr)
+ check_memory_error(p0)
gc_store(p0, 0, 0, %(vtable_descr.field_size)s)
jump()
""")
diff --git a/rpython/jit/backend/ppc/opassembler.py b/rpython/jit/backend/ppc/opassembler.py
--- a/rpython/jit/backend/ppc/opassembler.py
+++ b/rpython/jit/backend/ppc/opassembler.py
@@ -1025,9 +1025,8 @@
_mixin_ = True
- def emit_call_malloc_gc(self, op, arglocs, regalloc):
- self._emit_call(op, arglocs)
- self.propagate_memoryerror_if_r3_is_null()
+ def emit_check_memory_error(self, op, arglocs, regalloc):
+ self.propagate_memoryerror_if_reg_is_null(arglocs[0])
def emit_call_malloc_nursery(self, op, arglocs, regalloc):
# registers r.RES and r.RSZ are allocated for this call
diff --git a/rpython/jit/backend/ppc/ppc_assembler.py b/rpython/jit/backend/ppc/ppc_assembler.py
--- a/rpython/jit/backend/ppc/ppc_assembler.py
+++ b/rpython/jit/backend/ppc/ppc_assembler.py
@@ -412,7 +412,7 @@
# Check that we don't get NULL; if we do, we always interrupt the
# current loop, as a "good enough" approximation (same as
# emit_call_malloc_gc()).
- self.propagate_memoryerror_if_r3_is_null()
+ self.propagate_memoryerror_if_reg_is_null(r.r3)
mc.mtlr(r.RCS1.value) # restore LR
self._pop_core_regs_from_jitframe(mc, saved_regs)
@@ -594,9 +594,6 @@
self.wb_slowpath[withcards + 2 * withfloats] = rawstart
def _build_propagate_exception_path(self):
- if not self.cpu.propagate_exception_descr:
- return
-
self.mc = PPCBuilder()
#
# read and reset the current exception
@@ -1326,11 +1323,8 @@
pmc.b(offset) # jump always
pmc.overwrite()
- def propagate_memoryerror_if_r3_is_null(self):
- # if self.propagate_exception_path == 0 (tests), this may jump to 0
- # and segfaults. too bad. the alternative is to continue anyway
- # with r3==0, but that will segfault too.
- self.mc.cmp_op(0, r.r3.value, 0, imm=True)
+ def propagate_memoryerror_if_reg_is_null(self, reg_loc):
+ self.mc.cmp_op(0, reg_loc.value, 0, imm=True)
self.mc.b_cond_abs(self.propagate_exception_path, c.EQ)
def write_new_force_index(self):
diff --git a/rpython/jit/backend/ppc/regalloc.py b/rpython/jit/backend/ppc/regalloc.py
--- a/rpython/jit/backend/ppc/regalloc.py
+++ b/rpython/jit/backend/ppc/regalloc.py
@@ -533,8 +533,9 @@
res = self.rm.force_allocate_reg(op)
return [res]
- def prepare_call_malloc_gc(self, op):
- return self._prepare_call(op)
+ def prepare_check_memory_error(self, op):
+ loc = self.ensure_reg(op.getarg(0))
+ return [loc]
def _prepare_guard(self, op, args=None):
if args is None:
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
@@ -22,6 +22,7 @@
from rpython.jit.backend.detect_cpu import autodetect
from rpython.jit.backend.llsupport import jitframe
from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
+from rpython.jit.backend.llsupport.llmodel import MissingLatestDescrError
from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler
@@ -4391,6 +4392,12 @@
'float', descr=calldescr)
assert longlong.getrealfloat(res) == expected
+ def test_check_memory_error(self):
+ self.execute_operation(
+ rop.CHECK_MEMORY_ERROR, [InputArgInt(12345)], 'void')
+ py.test.raises(MissingLatestDescrError, self.execute_operation,
+ rop.CHECK_MEMORY_ERROR, [InputArgInt(0)], 'void')
+
def test_compile_loop_with_target(self):
looptoken = JitCellToken()
targettoken1 = TargetToken()
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
@@ -292,9 +292,6 @@
return rawstart
def _build_propagate_exception_path(self):
- if not self.cpu.propagate_exception_descr:
- return # not supported (for tests, or non-translated)
- #
self.mc = codebuf.MachineCodeBlockWrapper()
self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
#
@@ -1532,15 +1529,9 @@
# ----------
- def genop_call_malloc_gc(self, op, arglocs, result_loc):
- self._genop_call(op, arglocs, result_loc)
- self.propagate_memoryerror_if_eax_is_null()
-
- def propagate_memoryerror_if_eax_is_null(self):
- # if self.propagate_exception_path == 0 (tests), this may jump to 0
- # and segfaults. too bad. the alternative is to continue anyway
- # with eax==0, but that will segfault too.
- self.mc.TEST_rr(eax.value, eax.value)
+ def genop_discard_check_memory_error(self, op, arglocs):
+ reg = arglocs[0]
+ self.mc.TEST(reg, reg)
if WORD == 4:
self.mc.J_il(rx86.Conditions['Z'], self.propagate_exception_path)
self.mc.add_pending_relocation()
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -902,9 +902,10 @@
consider_call_release_gil_i = _consider_call_release_gil
consider_call_release_gil_f = _consider_call_release_gil
consider_call_release_gil_n = _consider_call_release_gil
-
- def consider_call_malloc_gc(self, op):
- self._consider_call(op)
+
+ def consider_check_memory_error(self, op):
+ x = self.rm.make_sure_var_in_reg(op.getarg(0))
+ self.perform_discard(op, [x])
def _consider_call_assembler(self, op):
locs = self.locs_for_call_assembler(op)
diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -356,9 +356,6 @@
self.mc = None
def _build_propagate_exception_path(self):
- if not self.cpu.propagate_exception_descr:
- return
-
self.mc = InstrBuilder()
#
# read and reset the current exception
@@ -487,7 +484,7 @@
# Check that we don't get NULL; if we do, we always interrupt the
# current loop, as a "good enough" approximation (same as
# emit_call_malloc_gc()).
- self.propagate_memoryerror_if_r2_is_null(True)
+ self.propagate_memoryerror_if_reg_is_null(r.r2, True)
self._pop_core_regs_from_jitframe(mc, saved_regs)
self._pop_fp_regs_from_jitframe(mc)
@@ -797,12 +794,12 @@
self.mc.BRC(condition, l.imm(off)) # branch over XGR
self.mc.XGR(result_loc, result_loc)
- def propagate_memoryerror_if_r2_is_null(self, pop_one_stackframe=False):
+ def propagate_memoryerror_if_reg_is_null(self, reg, pop_one_stackframe=False):
# if self.propagate_exception_path == 0 (tests), this may jump to 0
# and segfaults. too bad. the alternative is to continue anyway
- # with r2==0, but that will segfault too.
+ # with reg==0, but that will segfault too.
jmp_pos = self.mc.get_relative_pos()
- # bails to propagate exception path if r2 != 0
+ # bails to propagate exception path if reg != 0
self.mc.reserve_cond_jump()
self.mc.load_imm(r.RETURN, self.propagate_exception_path)
@@ -812,7 +809,7 @@
curpos = self.mc.currpos()
pmc = OverwritingBuilder(self.mc, jmp_pos, 1)
- pmc.CGIJ(r.r2, l.imm(0), c.NE, l.imm(curpos - jmp_pos))
+ pmc.CGIJ(reg, l.imm(0), c.NE, l.imm(curpos - jmp_pos))
pmc.overwrite()
def regalloc_push(self, loc, already_pushed):
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -421,9 +421,8 @@
class AllocOpAssembler(object):
_mixin_ = True
- def emit_call_malloc_gc(self, op, arglocs, regalloc):
- self._emit_call(op, arglocs)
- self.propagate_memoryerror_if_r2_is_null()
+ def emit_check_memory_error(self, op, arglocs, regalloc):
+ self.propagate_memoryerror_if_reg_is_null(arglocs[0])
def emit_call_malloc_nursery(self, op, arglocs, regalloc):
# registers r.RES and r.RSZ are allocated for this call
diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -828,8 +828,9 @@
prepare_call_f = _prepare_call
prepare_call_n = _prepare_call
- def prepare_call_malloc_gc(self, op):
- return self._prepare_call_default(op)
+ def prepare_check_memory_error(self, op):
+ loc = self.ensure_reg(op.getarg(0))
+ return [loc]
def prepare_call_malloc_nursery(self, op):
self.rm.force_allocate_reg(op, selected_reg=r.RES)
diff --git a/rpython/jit/backend/zarch/test/test_pool.py b/rpython/jit/backend/zarch/test/test_pool.py
--- a/rpython/jit/backend/zarch/test/test_pool.py
+++ b/rpython/jit/backend/zarch/test/test_pool.py
@@ -40,7 +40,7 @@
def test_constant_in_call_malloc(self):
c = ConstPtr(rffi.cast(llmemory.GCREF, 0xdeadbeef1234))
- self.ensure_can_hold(rop.CALL_MALLOC_GC, [c], descr=self.calldescr)
+ self.ensure_can_hold(rop.COND_CALL, [c], descr=self.calldescr)
assert self.const_in_pool(c)
assert self.const_in_pool(ConstPtr(rffi.cast(llmemory.GCREF, 0xdeadbeef1234)))
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -379,7 +379,7 @@
rop.CALL_RELEASE_GIL_F,
rop.CALL_RELEASE_GIL_N,
rop.QUASIIMMUT_FIELD,
- rop.CALL_MALLOC_GC,
+ rop.CHECK_MEMORY_ERROR,
rop.CALL_MALLOC_NURSERY,
rop.CALL_MALLOC_NURSERY_VARSIZE,
rop.CALL_MALLOC_NURSERY_VARSIZE_FRAME,
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -345,7 +345,8 @@
opnum == rop.ENTER_PORTAL_FRAME or # no effect whatsoever
opnum == rop.LEAVE_PORTAL_FRAME or # no effect whatsoever
opnum == rop.COPYSTRCONTENT or # no effect on GC struct/array
- opnum == rop.COPYUNICODECONTENT): # no effect on GC struct/array
+ opnum == rop.COPYUNICODECONTENT or # no effect on GC struct/array
+ opnum == rop.CHECK_MEMORY_ERROR): # may only abort the whole loop
return
if rop.is_call(op.opnum):
if rop.is_call_assembler(op.getopnum()):
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -400,6 +400,12 @@
def _force_elements(self, op, optforce, descr):
self.size = -1
+ # at this point we have just written the
+ # 'op = CALL_I(..., OS_RAW_MALLOC_VARSIZE_CHAR)'.
+ # Emit now a CHECK_MEMORY_ERROR resop.
+ check_op = ResOperation(rop.CHECK_MEMORY_ERROR, [op])
+ optforce.emit_operation(check_op)
+ #
buffer = self._get_buffer()
for i in range(len(buffer.offsets)):
# write the value
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1818,7 +1818,7 @@
[i1]
label(i1)
i2 = call_i('malloc', 20, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
+ check_memory_error(i2)
raw_store(i2, 0, i1, descr=rawarraydescr_char)
raw_store(i2, 1, 123, descr=rawarraydescr_char)
raw_store(i2, 2, 456, descr=rawarraydescr_char)
@@ -1844,7 +1844,7 @@
[i1]
label(i1)
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
+ check_memory_error(i2)
raw_store(i2, 0, i1, descr=rawarraydescr)
setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
call_n('free', i2, descr=raw_free_descr)
@@ -1867,7 +1867,7 @@
[i1]
label(i1)
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
+ check_memory_error(i2)
raw_store(i2, 0, i1, descr=rawarraydescr)
i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr_char)
call_n('free', i2, descr=raw_free_descr)
@@ -1930,7 +1930,7 @@
label(i0, i1)
# these ops are generated by VirtualRawBufferValue._really_force
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
+ check_memory_error(i2)
raw_store(i2, 0, 42, descr=rawarraydescr_char)
raw_store(i2, 5, 4242, descr=rawarraydescr_char)
# this is generated by VirtualRawSliceValue._really_force
@@ -1959,7 +1959,7 @@
call_n('free', i0, descr=raw_free_descr)
label(i2)
i3 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
+ check_memory_error(i3)
raw_store(i3, 0, i2, descr=rawarraydescr)
jump(i3)
"""
@@ -2032,6 +2032,7 @@
expected = """
[f1]
i0 = call_i('malloc', 16, descr=raw_malloc_descr)
+ check_memory_error(i0)
escape_n(i0)
i1 = int_add(i0, 8)
setarrayitem_raw(i1, 0, f1, descr=rawarraydescr_float)
@@ -8802,14 +8803,22 @@
ops = """
[i1]
i0 = call_i(123, 10, descr=raw_malloc_descr)
+ guard_no_exception() []
jump(i0)
"""
- self.optimize_loop(ops, ops)
+ expected = """
+ [i1]
+ i0 = call_i(123, 10, descr=raw_malloc_descr)
+ check_memory_error(i0)
+ jump(i0)
+ """
+ self.optimize_loop(ops, expected)
def test_raw_buffer_int_is_true(self):
ops = """
[iinp]
i0 = call_i(123, 10, descr=raw_malloc_descr)
+ guard_no_exception() []
i1 = int_is_true(i0)
guard_true(i1) []
i2 = int_is_zero(i0)
@@ -8819,6 +8828,7 @@
expected = """
[i2]
i0 = call_i(123, 10, descr=raw_malloc_descr)
+ check_memory_error(i0)
jump(i0)
"""
self.optimize_loop(ops, expected)
@@ -8877,6 +8887,7 @@
ops = """
[i0]
i = call_i('malloc', 10, descr=raw_malloc_descr)
+ guard_no_exception() []
is = int_add(i, 8)
escape_n(i)
i1 = int_add(i0, 1)
@@ -8888,6 +8899,7 @@
expected = """
[i0]
i = call_i('malloc', 10, descr=raw_malloc_descr)
+ check_memory_error(i)
escape_n(i)
i1 = int_add(i0, 1)
i2 = int_lt(i1, 100)
@@ -8955,6 +8967,7 @@
ops = """
[i0, p0]
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+ guard_no_exception() []
setarrayitem_raw(i2, 0, 13, descr=rawarraydescr)
setfield_gc(p0, i2, descr=valuedescr)
i1 = int_add(i0, 1)
@@ -8976,12 +8989,20 @@
ops = """
[]
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+ guard_no_exception() []
guard_value(i2, 12345) []
jump()
"""
+ expected = """
+ []
+ i2 = call_i('malloc', 10, descr=raw_malloc_descr)
+ check_memory_error(i2)
+ guard_value(i2, 12345) []
+ jump()
+ """
# getting InvalidLoop would be a good idea, too.
# (this test was written to show it would previously crash)
- self.optimize_loop(ops, ops)
+ self.optimize_loop(ops, expected)
def test_unroll_constant_null_1(self):
ops = """
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -1157,7 +1157,7 @@
'CALL_RELEASE_GIL/*d/fin',
# release the GIL and "close the stack" for asmgcc
'CALL_PURE/*d/rfin', # removed before it's passed to the backend
- 'CALL_MALLOC_GC/*d/r', # like CALL, but NULL => propagate MemoryError
+ 'CHECK_MEMORY_ERROR/1/n', # after a CALL: NULL => propagate MemoryError
'CALL_MALLOC_NURSERY/1/r', # nursery malloc, const number of bytes, zeroed
'CALL_MALLOC_NURSERY_VARSIZE/3d/r',
'CALL_MALLOC_NURSERY_VARSIZE_FRAME/1/r',
diff --git a/rpython/rlib/rvmprof/src/vmprof_config.h b/rpython/rlib/rvmprof/src/vmprof_config.h
--- a/rpython/rlib/rvmprof/src/vmprof_config.h
+++ b/rpython/rlib/rvmprof/src/vmprof_config.h
@@ -4,7 +4,7 @@
# define HAVE_SIGNAL_H
#endif
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
#ifdef __i386__
#define PC_FROM_UCONTEXT uc_mcontext.mc_eip
#else
More information about the pypy-commit
mailing list