Author: Armin Rigo <[email protected]>
Branch: remove-globals-in-jit
Changeset: r58939:eec649fe33e0
Date: 2012-11-16 10:02 +0100
http://bitbucket.org/pypy/pypy/changeset/eec649fe33e0/
Log: More work on exceptions. Propagate MemoryError.
diff --git a/pypy/jit/backend/llsupport/llmodel.py
b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.llinterp import LLInterpreter
-from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.annlowlevel import llhelper, cast_instance_to_base_ptr
from pypy.rlib.objectmodel import we_are_translated, specialize
from pypy.jit.metainterp import history
from pypy.jit.codewriter import heaptracker, longlong
@@ -45,10 +45,6 @@
self._setup_exception_handling_untranslated()
self.asmmemmgr = AsmMemoryManager()
self.setup()
- if translate_support_code:
- self._setup_on_leave_jitted_translated()
- else:
- self._setup_on_leave_jitted_untranslated()
def setup(self):
pass
@@ -81,24 +77,34 @@
return (rffi.cast(lltype.Signed, _exception_emulator) +
rffi.sizeof(lltype.Signed))
- def save_exception():
- # copy from _exception_emulator to the real attributes on self
- v_i = _exception_emulator[1]
+ self._memoryerror_emulated = rffi.cast(llmemory.GCREF, -123)
+ self.deadframe_memoryerror = lltype.malloc(jitframe.DEADFRAME, 0)
+ self.deadframe_memoryerror.jf_guard_exc = self._memoryerror_emulated
+
+ def propagate_exception():
+ exc = _exception_emulator[1]
_exception_emulator[0] = 0
_exception_emulator[1] = 0
- self.saved_exc_value = rffi.cast(llmemory.GCREF, v_i)
-
- def save_exception_memoryerr():
- save_exception()
- if not self.saved_exc_value:
- self.saved_exc_value = "memoryerror!" # for tests
+ if not exc:
+ deadframe = self.deadframe_memoryerror
+ assert self.propagate_exception_v >= 0
+ faildescr = self.get_fail_descr_from_number(
+ self.propagate_exception_v)
+ if not deadframe.jf_descr:
+ deadframe.jf_descr = faildescr.hide(self)
+ else:
+ assert deadframe.jf_descr == faildescr.hide(self)
+ else:
+ deadframe = lltype.malloc(jitframe.DEADFRAME, 0)
+ deadframe.jf_guard_exc = rffi.cast(llmemory.GCREF, exc)
+ deadframe.jf_descr = self.get_fail_descr_from_number(
+ self.propagate_exception_v)
+ return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe)
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
- self.save_exception = save_exception
- self.save_exception_memoryerr = save_exception_memoryerr
self.insert_stack_check = lambda: (0, 0, 0)
-
+ self._propagate_exception = propagate_exception
def _setup_exception_handling_translated(self):
xxxxxxxxxxx
@@ -147,51 +153,15 @@
self.save_exception_memoryerr = save_exception_memoryerr
self.insert_stack_check = insert_stack_check
- def _setup_on_leave_jitted_untranslated(self):
- # assume we don't need a backend leave in this case
- self.on_leave_jitted_save_exc = self.save_exception
- self.on_leave_jitted_memoryerr = self.save_exception_memoryerr
- self.on_leave_jitted_noexc = lambda : None
+ PROPAGATE_EXCEPTION = lltype.Ptr(lltype.FuncType([], llmemory.GCREF))
- def _setup_on_leave_jitted_translated(self):
- on_leave_jitted_hook = self.get_on_leave_jitted_hook()
- save_exception = self.save_exception
- save_exception_memoryerr = self.save_exception_memoryerr
-
- def on_leave_jitted_noexc():
- on_leave_jitted_hook()
-
- def on_leave_jitted_save_exc():
- save_exception()
- on_leave_jitted_hook()
-
- def on_leave_jitted_memoryerr():
- save_exception_memoryerr()
- on_leave_jitted_hook()
-
- self.on_leave_jitted_noexc = on_leave_jitted_noexc
- self.on_leave_jitted_save_exc = on_leave_jitted_save_exc
- self.on_leave_jitted_memoryerr = on_leave_jitted_memoryerr
-
- def get_on_leave_jitted_hook(self):
- # this function needs to be overridden for things to work with
- # our framework GCs
- translation_time_error
-
- _ON_JIT_LEAVE_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
-
- def get_on_leave_jitted_int(self, save_exception,
- default_to_memoryerror=False):
- if default_to_memoryerror:
- f = llhelper(self._ON_JIT_LEAVE_FUNC,
self.on_leave_jitted_memoryerr)
- elif save_exception:
- f = llhelper(self._ON_JIT_LEAVE_FUNC,
self.on_leave_jitted_save_exc)
- else:
- f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc)
- return rffi.cast(lltype.Signed, f)
+ def get_propagate_exception(self):
+ return llhelper(self.PROPAGATE_EXCEPTION, self._propagate_exception)
def grab_exc_value(self, deadframe):
deadframe = lltype.cast_opaque_ptr(jitframe.DEADFRAMEPTR, deadframe)
+ if not we_are_translated() and deadframe == self.deadframe_memoryerror:
+ return "memoryerror!" # for tests
return deadframe.jf_guard_exc
def set_savedata_ref(self, deadframe, data):
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2943,7 +2943,7 @@
x = self.cpu.get_latest_value_float(deadframe, 0)
assert longlong.getrealfloat(x) == 1.25 + 3.25
called.append(self.cpu.get_latest_descr(deadframe))
- return longlong.getfloatstorage(13.5)
+ return 13.5
FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.GCREF],
lltype.Float))
@@ -3369,7 +3369,7 @@
deadframe = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1)
fail = self.cpu.get_latest_descr(deadframe)
assert fail.identifier == excdescr.identifier
- exc = self.cpu.grab_exc_value()
+ exc = self.cpu.grab_exc_value(deadframe)
assert exc == "memoryerror!"
def test_math_sqrt(self):
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -262,11 +262,12 @@
return # not supported (for tests, or non-translated)
#
self.mc = codebuf.MachineCodeBlockWrapper()
- # call on_leave_jitted_save_exc()
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True,
- default_to_memoryerror=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())
self.mc.CALL(imm(addr))
- self.mc.MOV_ri(eax.value, self.cpu.propagate_exception_v)
+ #
self._call_footer()
rawstart = self.mc.materialize(self.cpu.asmmemmgr, [])
self.propagate_exception_path = rawstart
@@ -333,6 +334,7 @@
addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
mc.CALL(imm(addr))
#
+ xxxxxxxxxxxxxxxx
mc.MOV_ri(eax.value, self.cpu.propagate_exception_v)
#
# footer -- note the ADD, which skips the return address of this
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1470,7 +1470,7 @@
num = self.cpu.get_fail_descr_number(tokens[0].finishdescr)
setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num)
#
- exc_descr = compile.PropagateExceptionDescr()
+ exc_descr = compile.propagate_exception_descr
num = self.cpu.get_fail_descr_number(exc_descr)
self.cpu.propagate_exception_v = num
#
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit