[pypy-svn] r67444 - in pypy/trunk/pypy/jit/backend: llsupport x86
arigo at codespeak.net
arigo at codespeak.net
Thu Sep 3 13:08:34 CEST 2009
Author: arigo
Date: Thu Sep 3 13:08:34 2009
New Revision: 67444
Modified:
pypy/trunk/pypy/jit/backend/llsupport/llmodel.py
pypy/trunk/pypy/jit/backend/x86/assembler.py
pypy/trunk/pypy/jit/backend/x86/runner.py
Log:
Move most of the support for exception out of the x86 backend, into
llsupport. This is also needed to handle correctly the write barrier
case mentioned in llmodel.py.
Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original)
+++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Thu Sep 3 13:08:34 2009
@@ -1,8 +1,10 @@
import sys
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.rlib.objectmodel import we_are_translated, specialize
from pypy.jit.metainterp.history import BoxInt, BoxPtr, set_future_values
-from pypy.jit.metainterp.typesystem import llhelper
from pypy.jit.backend.model import AbstractCPU
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
@@ -19,7 +21,7 @@
class AbstractLLCPU(AbstractCPU):
- ts = llhelper
+ from pypy.jit.metainterp.typesystem import llhelper as ts
def __init__(self, rtyper, stats, translate_support_code=False,
gcdescr=None):
@@ -37,6 +39,11 @@
translate_support_code)
self._setup_prebuilt_error('ovf', OverflowError)
self._setup_prebuilt_error('zer', ZeroDivisionError)
+ if translate_support_code:
+ self._setup_exception_handling_translated()
+ else:
+ self._setup_exception_handling_untranslated()
+ self.clear_exception()
def set_class_sizes(self, class_sizes):
self.class_sizes = class_sizes
@@ -56,6 +63,91 @@
llmemory.cast_ptr_to_adr(ll_inst.typeptr))
setattr(self, '_%s_error_inst' % prefix, ll_inst)
+
+ def _setup_exception_handling_untranslated(self):
+ # for running un-translated only, all exceptions occurring in the
+ # llinterpreter are stored in '_exception_emulator', which is then
+ # read back by the machine code reading at the address given by
+ # pos_exception() and pos_exc_value().
+ _exception_emulator = lltype.malloc(rffi.CArray(lltype.Signed), 2,
+ zero=True, flavor='raw')
+ self._exception_emulator = _exception_emulator
+
+ def _store_exception(lle):
+ self._last_exception = lle # keepalive
+ tp_i = rffi.cast(lltype.Signed, lle.args[0])
+ v_i = rffi.cast(lltype.Signed, lle.args[1])
+ _exception_emulator[0] = tp_i
+ _exception_emulator[1] = v_i
+
+ self.debug_ll_interpreter = LLInterpreter(self.rtyper)
+ self.debug_ll_interpreter._store_exception = _store_exception
+
+ def pos_exception():
+ return rffi.cast(lltype.Signed, _exception_emulator)
+
+ def pos_exc_value():
+ return (rffi.cast(lltype.Signed, _exception_emulator) +
+ rffi.sizeof(lltype.Signed))
+
+ def save_exception():
+ # copy from _exception_emulator to the real attributes on self
+ tp_i = _exception_emulator[0]
+ v_i = _exception_emulator[1]
+ _exception_emulator[0] = 0
+ _exception_emulator[1] = 0
+ self.saved_exception = tp_i
+ self.saved_exc_value = self._cast_int_to_gcref(v_i)
+
+ self.pos_exception = pos_exception
+ self.pos_exc_value = pos_exc_value
+ self.save_exception = save_exception
+
+
+ def _setup_exception_handling_translated(self):
+
+ def pos_exception():
+ addr = llop.get_exception_addr(llmemory.Address)
+ return llmemory.cast_adr_to_int(addr)
+
+ def pos_exc_value():
+ addr = llop.get_exc_value_addr(llmemory.Address)
+ return llmemory.cast_adr_to_int(addr)
+
+ def save_exception():
+ addr = llop.get_exception_addr(llmemory.Address)
+ exception = rffi.cast(lltype.Signed, addr.address[0])
+ addr.address[0] = llmemory.NULL
+ addr = llop.get_exc_value_addr(llmemory.Address)
+ exc_value = rffi.cast(llmemory.GCREF, addr.address[0])
+ addr.address[0] = llmemory.NULL
+ # from now on, the state is again consistent -- no more RPython
+ # exception is set. The following code produces a write barrier
+ # in the assignment to self.saved_exc_value, as needed.
+ self.saved_exception = exception
+ self.saved_exc_value = exc_value
+
+ self.pos_exception = pos_exception
+ self.pos_exc_value = pos_exc_value
+ self.save_exception = save_exception
+
+ _SAVE_EXCEPTION_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
+
+ def get_save_exception_int(self):
+ f = llhelper(self._SAVE_EXCEPTION_FUNC, self.save_exception)
+ return rffi.cast(lltype.Signed, f)
+
+ def get_exception(self):
+ return self.saved_exception
+
+ def get_exc_value(self):
+ return self.saved_exc_value
+
+ def clear_exception(self):
+ self.saved_exception = 0
+ self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO)
+
+
# ------------------- helpers and descriptions --------------------
@staticmethod
Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py Thu Sep 3 13:08:34 2009
@@ -5,7 +5,6 @@
from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory
from pypy.rpython.lltypesystem.rclass import OBJECT
from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.annotation import model as annmodel
from pypy.tool.uid import fixid
from pypy.jit.backend.logger import Logger
from pypy.jit.backend.x86.regalloc import (RegAlloc, WORD, REGS, TempBox,
@@ -79,10 +78,6 @@
assert self.mcstack[self.counter - 1] is mc
self.counter -= 1
-EXCEPTION_STORAGE = lltype.GcStruct('EXCEPTION_STORAGE',
- ('type', lltype.Signed),
- ('value', llmemory.GCREF))
-
class Assembler386(object):
mc = None
@@ -97,10 +92,6 @@
self.malloc_array_func_addr = 0
self.malloc_str_func_addr = 0
self.malloc_unicode_func_addr = 0
- # The '_exception_emulator' is only used when non-translated.
- # The '_exception_copy' is preallocated, so non-moving.
- self._exception_emulator = lltype.malloc(EXCEPTION_STORAGE, zero=True)
- self._exception_copy = lltype.malloc(EXCEPTION_STORAGE, zero=True)
self.mcstack = MachineCodeStack()
self.logger = Logger(cpu.ts)
self.fail_boxes_int = lltype.malloc(lltype.GcArray(lltype.Signed),
@@ -631,50 +622,20 @@
self.mc.TEST(loc, loc)
self.implement_guard(addr, op, self.mc.JZ)
- def pos_exception(self):
- if we_are_translated():
- addr = llop.get_exception_addr(llmemory.Address)
- return llmemory.cast_adr_to_int(addr)
- else:
- i = rffi.cast(lltype.Signed, self._exception_emulator)
- return i + 0 # xxx hard-coded offset of 'type' when non-translated
-
- def pos_exc_value(self):
- if we_are_translated():
- addr = llop.get_exc_value_addr(llmemory.Address)
- return llmemory.cast_adr_to_int(addr)
- else:
- i = rffi.cast(lltype.Signed, self._exception_emulator)
- return i + 4 # xxx hard-coded offset of 'value' when non-translated
-
- def pos_exception_copy(self):
- i = rffi.cast(lltype.Signed, self._exception_copy)
- if we_are_translated():
- return i + llmemory.offsetof(EXCEPTION_STORAGE, 'type')
- else:
- return i + 0 # xxx hard-coded offset of 'type' when non-translated
-
- def pos_exc_value_copy(self):
- i = rffi.cast(lltype.Signed, self._exception_copy)
- if we_are_translated():
- return i + llmemory.offsetof(EXCEPTION_STORAGE, 'value')
- else:
- return i + 4 # xxx hard-coded offset of 'value' when non-translated
-
def genop_guard_guard_no_exception(self, op, ign_1, addr, locs, ign_2):
- self.mc.CMP(heap(self.pos_exception()), imm(0))
+ self.mc.CMP(heap(self.cpu.pos_exception()), imm(0))
self.implement_guard(addr, op, self.mc.JNZ)
def genop_guard_guard_exception(self, op, ign_1, addr, locs, resloc):
loc = locs[0]
loc1 = locs[1]
- self.mc.MOV(loc1, heap(self.pos_exception()))
+ self.mc.MOV(loc1, heap(self.cpu.pos_exception()))
self.mc.CMP(loc1, loc)
self.implement_guard(addr, op, self.mc.JNE)
if resloc is not None:
- self.mc.MOV(resloc, heap(self.pos_exc_value()))
- self.mc.MOV(heap(self.pos_exception()), imm(0))
- self.mc.MOV(heap(self.pos_exc_value()), imm(0))
+ self.mc.MOV(resloc, heap(self.cpu.pos_exc_value()))
+ self.mc.MOV(heap(self.cpu.pos_exception()), imm(0))
+ self.mc.MOV(heap(self.cpu.pos_exc_value()), imm(0))
def genop_guard_guard_no_overflow(self, op, ign_1, addr, locs, resloc):
self.implement_guard(addr, op, self.mc.JO)
@@ -740,7 +701,9 @@
imm(len(locs) * WORD)),
eax)
if exc:
- self.generate_exception_handling(eax)
+ # note that we don't have to save and restore eax, ecx and edx here
+ addr = self.cpu.get_save_exception_int()
+ self.mc.CALL(rel32(addr))
# don't break the following code sequence!
mc = self.mc._mc
self.places_to_patch_framesize.append(mc.tell())
@@ -753,16 +716,6 @@
mc.POP(ebp)
mc.RET()
- def generate_exception_handling(self, loc):
- self.mc.MOV(loc, heap(self.pos_exception()))
- self.mc.MOV(heap(self.pos_exception_copy()), loc)
- self.mc.MOV(loc, heap(self.pos_exc_value()))
- self.mc.MOV(heap(self.pos_exc_value_copy()), loc)
- # clean up the original exception, we don't want
- # to enter more rpython code with exc set
- self.mc.MOV(heap(self.pos_exception()), imm(0))
- self.mc.MOV(heap(self.pos_exc_value()), imm(0))
-
@specialize.arg(3)
def implement_guard(self, addr, guard_op, emit_jump):
emit_jump(rel32(addr))
Modified: pypy/trunk/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/runner.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/runner.py Thu Sep 3 13:08:34 2009
@@ -21,16 +21,6 @@
gcdescr=None):
AbstractLLCPU.__init__(self, rtyper, stats, translate_support_code,
gcdescr)
- if not translate_support_code:
- self.current_interpreter = LLInterpreter(self.rtyper)
-
- def _store_exception(lle):
- tp_i = self.cast_ptr_to_int(lle.args[0])
- v_i = lltype.cast_opaque_ptr(llmemory.GCREF, lle.args[1])
- self.assembler._exception_emulator.type = tp_i
- self.assembler._exception_emulator.value = v_i
-
- self.current_interpreter._store_exception = _store_exception
TP = lltype.GcArray(llmemory.GCREF)
self._bootstrap_cache = {}
self._guard_list = []
@@ -45,16 +35,6 @@
def setup_once(self):
pass
- def get_exception(self):
- return self.assembler._exception_copy.type
-
- def get_exc_value(self):
- return self.assembler._exception_copy.value
-
- def clear_exception(self):
- self.assembler._exception_copy.type = 0
- self.assembler._exception_copy.value= lltype.nullptr(llmemory.GCREF.TO)
-
def compile_operations(self, tree, bridge=None):
old_loop = tree._x86_compiled
if old_loop:
@@ -116,7 +96,7 @@
prev_interpreter = None
if not self.translate_support_code:
prev_interpreter = LLInterpreter.current_interpreter
- LLInterpreter.current_interpreter = self.current_interpreter
+ LLInterpreter.current_interpreter = self.debug_ll_interpreter
res = 0
try:
self.caught_exception = None
More information about the Pypy-commit
mailing list