[pypy-commit] pypy default: Check for NULL returns from calls to the raw-malloc, even if they are
arigo
pypy.commits at gmail.com
Mon Jul 18 10:55:08 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r85757:54dc4d5466e7
Date: 2016-07-18 15:24 +0200
http://bitbucket.org/pypy/pypy/changeset/54dc4d5466e7/
Log: Check for NULL returns from calls to the raw-malloc, even if they
are usually removed by the optimizer. Done not as a regular guard,
because we don't know where to go if that guard fails, but instead
done with the same trick as CALL_MALLOC_GC: if it fails, we abort
the whole loop and raise MemoryError outside. It's still better than
the current situation, where a failing raw-malloc is ignored and
then we segfault when trying to use the NULL pointer.
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(): # for missing propagate_exception_descr
+ if res is None:
+ 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/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,25 @@
'float', descr=calldescr)
assert longlong.getrealfloat(res) == expected
+ def test_raw_malloc_out_of_memory(self):
+ def failing_malloc(size):
+ return 0
+ effectinfo = EffectInfo([], [], [], [], [], [],
+ EffectInfo.EF_CAN_RAISE,
+ EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR)
+ FPTR = self.Ptr(self.FuncType([lltype.Signed], lltype.Signed))
+ func_ptr = llhelper(FPTR, failing_malloc)
+ FUNC = deref(FPTR)
+ funcbox = self.get_funcbox(self.cpu, func_ptr)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ effectinfo)
+ # Executing a CALL_I to the OS_RAW_MALLOC_VARSIZE_CHAR should
+ # be special-cased so that a return value of 0 triggers a
+ # get-out-of-loop MemoryError, like a failing CALL_MALLOC_GC
+ py.test.raises(MissingLatestDescrError,
+ self.execute_operation, rop.CALL_I,
+ [funcbox, InputArgInt(12345)], 'void', descr=calldescr)
+
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)
#
@@ -303,7 +300,11 @@
self._store_and_reset_exception(self.mc, eax)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
self.mc.MOV_br(ofs, eax.value)
- propagate_exception_descr = rffi.cast(lltype.Signed,
+ if not self.cpu.propagate_exception_descr:
+ # for tests, or non-translated
+ propagate_exception_descr = 0
+ else:
+ propagate_exception_descr = rffi.cast(lltype.Signed,
cast_instance_to_gcref(self.cpu.propagate_exception_descr))
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
self.mc.MOV(RawEbpLoc(ofs), imm(propagate_exception_descr))
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
@@ -884,6 +884,8 @@
if oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP:
return self._consider_math_read_timestamp(op)
self._consider_call(op)
+ if oopspecindex == EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR:
+ self.assembler.propagate_memoryerror_if_eax_is_null()
consider_call_i = _consider_real_call
consider_call_r = _consider_real_call
consider_call_f = _consider_real_call
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,6 @@
[i1]
label(i1)
i2 = call_i('malloc', 20, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
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 +1843,6 @@
[i1]
label(i1)
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
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 +1865,6 @@
[i1]
label(i1)
i2 = call_i('malloc', 10, descr=raw_malloc_descr)
- #guard_no_exception() [] # XXX should appear
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 +1927,6 @@
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
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 +1955,6 @@
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
raw_store(i3, 0, i2, descr=rawarraydescr)
jump(i3)
"""
More information about the pypy-commit
mailing list