Author: Richard Plangger <planri...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit