Author: Maciej Fijalkowski <fij...@gmail.com> Branch: optresult Changeset: r77769:22d1b419809f Date: 2015-06-02 16:14 +0200 http://bitbucket.org/pypy/pypy/changeset/22d1b419809f/
Log: an attempt to fix exception handling in the new model diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -684,7 +684,7 @@ @staticmethod def check_consistency_of_branch(operations, seen): "NOT_RPYTHON" - for op in operations: + for num, op in enumerate(operations): for i in range(op.numargs()): box = op.getarg(i) if not isinstance(box, Const): diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -326,11 +326,11 @@ @arguments("label") def opimpl_catch_exception(self, target): """This is a no-op when run normally. We can check that - last_exc_value_box is None; it should have been set to None + last_exc_value is a null ptr; it should have been set to None by the previous instruction. If the previous instruction raised instead, finishframe_exception() should have been called and we would not be there.""" - assert self.metainterp.last_exc_value_box is None + assert not self.metainterp.last_exc_value @arguments("label") def opimpl_goto(self, target): @@ -1270,10 +1270,10 @@ @arguments("box", "label") def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target): metainterp = self.metainterp - last_exc_value_box = metainterp.last_exc_value_box - assert last_exc_value_box is not None + last_exc_value = metainterp.last_exc_value + assert last_exc_value assert metainterp.class_of_last_exc_is_const - if not metainterp.cpu.ts.instanceOf(last_exc_value_box, vtablebox): + if not metainterp.cpu.ts.instanceOf(ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, last_exc_value)), vtablebox): self.pc = next_exc_target @arguments("box", "orgpc") @@ -1284,29 +1284,30 @@ self.metainterp.generate_guard(rop.GUARD_CLASS, exc_value_box, [clsbox], resumepc=orgpc) self.metainterp.class_of_last_exc_is_const = True - self.metainterp.last_exc_value_box = exc_value_box + self.metainterp.last_exc_value = exc_value_box.getref(rclass.OBJECTPTR) + self.metainterp.last_exc_box = exc_value_box self.metainterp.popframe() self.metainterp.finishframe_exception() @arguments() def opimpl_reraise(self): - assert self.metainterp.last_exc_value_box is not None + assert self.metainterp.last_exc_value self.metainterp.popframe() self.metainterp.finishframe_exception() @arguments() def opimpl_last_exception(self): # Same comment as in opimpl_goto_if_exception_mismatch(). - exc_value_box = self.metainterp.last_exc_value_box - assert exc_value_box is not None + exc_value = self.metainterp.last_exc_value + assert exc_value assert self.metainterp.class_of_last_exc_is_const - return self.metainterp.cpu.ts.cls_of_box(exc_value_box) + return self.metainterp.cpu.ts.cls_of_box(ConstPtr(exc_value)) @arguments() def opimpl_last_exc_value(self): - exc_value_box = self.metainterp.last_exc_value_box - assert exc_value_box is not None - return exc_value_box + exc_value = self.metainterp.last_exc_value + assert exc_value + return ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, exc_value)) @arguments("box") def opimpl_debug_fatalerror(self, box): @@ -1503,7 +1504,7 @@ self.metainterp.clear_exception() op = self.metainterp.execute_and_record_varargs(opnum, argboxes, descr=descr) - if pure and self.metainterp.last_exc_value_box is None and op: + if pure and not self.metainterp.last_exc_value and op: op = self.metainterp.record_result_of_call_pure(op) exc = exc and not isinstance(op, Const) if exc: @@ -1868,6 +1869,7 @@ portal_call_depth = 0 cancel_count = 0 exported_state = None + last_exc_box = None def __init__(self, staticdata, jitdriver_sd): self.staticdata = staticdata @@ -1878,7 +1880,7 @@ # during recursion we can also see other jitdrivers. self.portal_trace_positions = [] self.free_frames_list = [] - self.last_exc_value_box = None + self.last_exc_value = lltype.nullptr(rclass.OBJECT) self.forced_virtualizable = None self.partial_trace = None self.retracing_from = -1 @@ -1937,7 +1939,7 @@ def finishframe(self, resultbox): # handle a non-exceptional return from the current frame - self.last_exc_value_box = None + self.last_exc_value = lltype.nullptr(rclass.OBJECT) self.popframe() if self.framestack: if resultbox is not None: @@ -1963,7 +1965,7 @@ assert False def finishframe_exception(self): - excvaluebox = self.last_exc_value_box + excvalue = self.last_exc_value while self.framestack: frame = self.framestack[-1] code = frame.bytecode @@ -1978,10 +1980,10 @@ raise ChangeFrame self.popframe() try: - self.compile_exit_frame_with_exception(excvaluebox) + self.compile_exit_frame_with_exception(self.last_exc_box) except SwitchToBlackhole, stb: self.aborted_tracing(stb.reason) - raise jitexc.ExitFrameWithExceptionRef(self.cpu, excvaluebox.getref_base()) + raise jitexc.ExitFrameWithExceptionRef(self.cpu, lltype.cast_opaque_ptr(llmemory.GCREF, excvalue)) def check_recursion_invariant(self): portal_call_depth = -1 @@ -2105,7 +2107,7 @@ @specialize.argtype(2) def _record_helper_nonpure_varargs(self, opnum, resvalue, descr, argboxes): if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST and - self.last_exc_value_box is None and + not self.last_exc_value and self._all_constants_varargs(argboxes)): return history.newconst(resvalue) # record the operation @@ -2173,22 +2175,17 @@ def execute_ll_raised(self, llexception, constant=False): # Exception handling: when execute.do_call() gets an exception it # calls metainterp.execute_raised(), which puts it into - # 'self.last_exc_value_box'. This is used shortly afterwards + # 'self.last_exc_value'. This is used shortly afterwards # to generate either GUARD_EXCEPTION or GUARD_NO_EXCEPTION, and also # to handle the following opcodes 'goto_if_exception_mismatch'. - llexception = self.cpu.ts.cast_to_ref(llexception) - if constant: - exc_value_box = self.cpu.ts.get_exc_value_const(llexception) - else: - exc_value_box = self.cpu.ts.get_exc_value_box(llexception) - self.last_exc_value_box = exc_value_box + self.last_exc_value = llexception self.class_of_last_exc_is_const = constant # 'class_of_last_exc_is_const' means that the class of the value # stored in the exc_value Box can be assumed to be a Const. This # is only True after a GUARD_EXCEPTION or GUARD_CLASS. def clear_exception(self): - self.last_exc_value_box = None + self.last_exc_value = lltype.nullptr(rclass.OBJECT) def aborted_tracing(self, reason): self.staticdata.profiler.count(reason) @@ -2747,28 +2744,30 @@ self.virtualref_boxes[i+1] = self.cpu.ts.CONST_NULL def handle_possible_exception(self): - if self.last_exc_value_box is not None: - exception_box = self.cpu.ts.cls_of_box(self.last_exc_value_box) + if self.last_exc_value: + exception_box = ConstInt(heaptracker.adr2int( + llmemory.cast_ptr_to_adr(self.last_exc_value.typeptr))) op = self.generate_guard(rop.GUARD_EXCEPTION, None, [exception_box]) + self.last_exc_box = op + op.setref_base(lltype.cast_opaque_ptr(llmemory.GCREF, + self.last_exc_value)) assert op is not None - op.result = self.last_exc_value_box self.class_of_last_exc_is_const = True self.finishframe_exception() else: self.generate_guard(rop.GUARD_NO_EXCEPTION, None, []) def handle_possible_overflow_error(self): - if self.last_exc_value_box is not None: + if self.last_exc_value: self.generate_guard(rop.GUARD_OVERFLOW, None) - assert isinstance(self.last_exc_value_box, Const) assert self.class_of_last_exc_is_const self.finishframe_exception() else: self.generate_guard(rop.GUARD_NO_OVERFLOW, None) def assert_no_exception(self): - assert self.last_exc_value_box is None + assert self.last_exc_value def rebuild_state_after_failure(self, resumedescr, deadframe): vinfo = self.jitdriver_sd.virtualizable_info @@ -3046,7 +3045,7 @@ self.clear_exception() executor.execute_varargs(self.cpu, self, rop.CALL_N, allboxes, descr) - if self.last_exc_value_box is not None: + if self.last_exc_value: # cannot trace this! it raises, so we have to follow the # exception-catching path, but the trace doesn't contain # the call at all @@ -3065,7 +3064,7 @@ self.reason = reason self.raising_exception = raising_exception # ^^^ must be set to True if the SwitchToBlackhole is raised at a - # point where the exception on metainterp.last_exc_value_box + # point where the exception on metainterp.last_exc_value # is supposed to be raised. The default False means that it # should just be copied into the blackhole interp, but not raised. diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py --- a/rpython/jit/metainterp/typesystem.py +++ b/rpython/jit/metainterp/typesystem.py @@ -79,14 +79,6 @@ def get_exception_box(self, etype): return history.ConstInt(etype) - def get_exc_value_box(self, evalue): - from rpython.jit.metainterp.resoperation import InputArgRef - - return InputArgRef(evalue) - - def get_exc_value_const(self, evalue): - return history.ConstPtr(evalue) - def get_exception_obj(self, evaluebox): # only works when translated obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit