X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FException.cmm;h=15b2c64d4fb0be10cf9e1cfef37f946ee0f3c37d;hb=fb570f4ae8d02ad25475d97d019cb93bf64d4d99;hp=62d544c350eacfeec56f35448b3c056306854328;hpb=178837a730c65349b32b29bd22356bacde110e18;p=ghc-hetmet.git diff --git a/rts/Exception.cmm b/rts/Exception.cmm index 62d544c..15b2c64 100644 --- a/rts/Exception.cmm +++ b/rts/Exception.cmm @@ -68,20 +68,38 @@ INFO_TABLE_RET( stg_unblockAsyncExceptionszh_ret, * we are about to raise an async exception in the current * thread, which might result in the thread being killed. */ + +#ifndef REG_R1 + /* + * raiseAsync assumes that the stack is in ThreadRunGHC state, + * i.e. with a return address on the top. In unreg mode, the + * return value for IO is on top of the return address, so we + * need to make a small adjustment here. + */ + Sp_adj(1); +#endif SAVE_THREAD_STATE(); r = foreign "C" maybePerformBlockedException (MyCapability() "ptr", CurrentTSO "ptr") [R1]; if (r != 0::CInt) { if (StgTSO_what_next(CurrentTSO) == ThreadKilled::I16) { - R1 = ThreadFinished; - jump StgReturn; + jump stg_threadFinished; } else { LOAD_THREAD_STATE(); ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16); jump %ENTRY_CODE(Sp(0)); } } +#ifndef REG_R1 + /* + * Readjust stack in unregisterised mode if we didn't raise an + * exception, see above + */ + else { + Sp_adj(-1); + } +#endif } #ifdef REG_R1 @@ -161,8 +179,7 @@ unblockAsyncExceptionszh_fast if (r != 0::CInt) { if (StgTSO_what_next(CurrentTSO) == ThreadKilled::I16) { - R1 = ThreadFinished; - jump StgReturn; + jump stg_threadFinished; } else { LOAD_THREAD_STATE(); ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16); @@ -210,8 +227,7 @@ killThreadzh_fast foreign "C" throwToSingleThreaded(MyCapability() "ptr", target "ptr", exception "ptr")[R1,R2]; if (StgTSO_what_next(CurrentTSO) == ThreadKilled::I16) { - R1 = ThreadFinished; - jump StgReturn; + jump stg_threadFinished; } else { LOAD_THREAD_STATE(); ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16); @@ -248,43 +264,11 @@ killThreadzh_fast -------------------------------------------------------------------------- */ #ifdef REG_R1 -#define CATCH_FRAME_ENTRY_TEMPLATE(label,ret) \ - label \ - { \ - Sp = Sp + SIZEOF_StgCatchFrame; \ - jump ret; \ - } -#else -#define CATCH_FRAME_ENTRY_TEMPLATE(label,ret) \ - label \ - { \ - W_ rval; \ - rval = Sp(0); \ - Sp = Sp + SIZEOF_StgCatchFrame; \ - Sp(0) = rval; \ - jump ret; \ - } -#endif - -#ifdef REG_R1 #define SP_OFF 0 #else #define SP_OFF 1 #endif -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_0_ret,%RET_VEC(Sp(SP_OFF),0)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_1_ret,%RET_VEC(Sp(SP_OFF),1)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_2_ret,%RET_VEC(Sp(SP_OFF),2)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_3_ret,%RET_VEC(Sp(SP_OFF),3)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_4_ret,%RET_VEC(Sp(SP_OFF),4)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_5_ret,%RET_VEC(Sp(SP_OFF),5)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_6_ret,%RET_VEC(Sp(SP_OFF),6)) -CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_7_ret,%RET_VEC(Sp(SP_OFF),7)) - -#if MAX_VECTORED_RTN > 8 -#error MAX_VECTORED_RTN has changed: please modify stg_catch_frame too. -#endif - #if defined(PROFILING) #define CATCH_FRAME_BITMAP 7 #define CATCH_FRAME_WORDS 4 @@ -300,16 +284,21 @@ CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_7_ret,%RET_VEC(Sp(SP_OFF),7)) INFO_TABLE_RET(stg_catch_frame, CATCH_FRAME_WORDS, CATCH_FRAME_BITMAP, - CATCH_FRAME, - stg_catch_frame_0_ret, - stg_catch_frame_1_ret, - stg_catch_frame_2_ret, - stg_catch_frame_3_ret, - stg_catch_frame_4_ret, - stg_catch_frame_5_ret, - stg_catch_frame_6_ret, - stg_catch_frame_7_ret) -CATCH_FRAME_ENTRY_TEMPLATE(,%ENTRY_CODE(Sp(SP_OFF))) + CATCH_FRAME) +#ifdef REG_R1 + { + Sp = Sp + SIZEOF_StgCatchFrame; + jump %ENTRY_CODE(Sp(SP_OFF)); + } +#else + { + W_ rval; + rval = Sp(0); + Sp = Sp + SIZEOF_StgCatchFrame; + Sp(0) = rval; + jump %ENTRY_CODE(Sp(SP_OFF)); + } +#endif /* ----------------------------------------------------------------------------- * The catch infotable @@ -363,13 +352,26 @@ INFO_TABLE(stg_raise,1,0,THUNK_1_0,"raise","raise") jump raisezh_fast; } +section "data" { + no_break_on_exception: W_[1]; +} + +INFO_TABLE_RET(stg_raise_ret, 1, 0, RET_SMALL) +{ + R1 = Sp(1); + Sp = Sp + WDS(2); + W_[no_break_on_exception] = 1; + jump raisezh_fast; +} + raisezh_fast { W_ handler; - W_ raise_closure; W_ frame_type; + W_ exception; /* args : R1 :: Exception */ + exception = R1; #if defined(PROFILING) /* Debugging tool: on raising an exception, show where we are. */ @@ -378,16 +380,39 @@ raisezh_fast * the info was only displayed for an *uncaught* exception. */ if (RtsFlags_ProfFlags_showCCSOnException(RtsFlags) != 0::I32) { - foreign "C" fprintCCS_stderr(W_[CCCS] "ptr"); + foreign "C" fprintCCS_stderr(W_[CCCS] "ptr") []; } #endif + if (W_[no_break_on_exception] != 0) { + W_[no_break_on_exception] = 0; + } else { + if (TO_W_(CInt[rts_stop_on_exception]) != 0) { + W_ ioAction; + // we don't want any further exceptions to be caught, + // until GHCi is ready to handle them. This prevents + // deadlock if an exception is raised in InteractiveUI, + // for exmplae. Perhaps the stop_on_exception flag should + // be per-thread. + W_[rts_stop_on_exception] = 0; + "ptr" ioAction = foreign "C" deRefStablePtr (W_[rts_breakpoint_io_action] "ptr") []; + Sp = Sp - WDS(6); + Sp(5) = exception; + Sp(4) = stg_raise_ret_info; + Sp(3) = exception; // the AP_STACK + Sp(2) = base_GHCziBase_True_closure; // dummy breakpoint info + Sp(1) = base_GHCziBase_True_closure; // True <=> a breakpoint + R1 = ioAction; + jump stg_ap_pppv_info; + } + } + /* Inform the Hpc that an exception has been thrown */ - foreign "C" hs_hpc_event("Raise",CurrentTSO); + foreign "C" hs_hpc_raise_event(CurrentTSO "ptr") []; retry_pop_stack: StgTSO_sp(CurrentTSO) = Sp; - frame_type = foreign "C" raiseExceptionHelper(BaseReg "ptr", CurrentTSO "ptr", R1 "ptr"); + frame_type = foreign "C" raiseExceptionHelper(BaseReg "ptr", CurrentTSO "ptr", exception "ptr") []; Sp = StgTSO_sp(CurrentTSO); if (frame_type == ATOMICALLY_FRAME) { /* The exception has reached the edge of a memory transaction. Check that @@ -401,14 +426,14 @@ retry_pop_stack: W_ trec, outer; W_ r; trec = StgTSO_trec(CurrentTSO); - r = foreign "C" stmValidateNestOfTransactions(trec "ptr"); + r = foreign "C" stmValidateNestOfTransactions(trec "ptr") []; "ptr" outer = foreign "C" stmGetEnclosingTRec(trec "ptr") []; - foreign "C" stmAbortTransaction(MyCapability() "ptr", trec "ptr"); - foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr"); + foreign "C" stmAbortTransaction(MyCapability() "ptr", trec "ptr") []; + foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr") []; if (outer != NO_TREC) { - foreign "C" stmAbortTransaction(MyCapability() "ptr", outer "ptr"); - foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", outer "ptr"); + foreign "C" stmAbortTransaction(MyCapability() "ptr", outer "ptr") []; + foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", outer "ptr") []; } StgTSO_trec(CurrentTSO) = NO_TREC; @@ -419,7 +444,7 @@ retry_pop_stack: } else { // Transaction was not valid: we retry the exception (otherwise continue // with a further call to raiseExceptionHelper) - "ptr" trec = foreign "C" stmStartTransaction(MyCapability() "ptr", NO_TREC "ptr"); + "ptr" trec = foreign "C" stmStartTransaction(MyCapability() "ptr", NO_TREC "ptr") []; StgTSO_trec(CurrentTSO) = trec; R1 = StgAtomicallyFrame_code(Sp); jump stg_ap_v_fast; @@ -434,16 +459,12 @@ retry_pop_stack: */ Sp = CurrentTSO + TSO_OFFSET_StgTSO_stack + WDS(TO_W_(StgTSO_stack_size(CurrentTSO))) - WDS(2); - Sp(1) = R1; /* save the exception */ + Sp(1) = exception; /* save the exception */ Sp(0) = stg_enter_info; /* so that GC can traverse this stack */ StgTSO_what_next(CurrentTSO) = ThreadKilled::I16; SAVE_THREAD_STATE(); /* inline! */ - /* The return code goes in BaseReg->rRet, and BaseReg is returned in R1 */ - StgRegTable_rRet(BaseReg) = ThreadFinished; - R1 = BaseReg; - - jump StgReturn; + jump stg_threadFinished; } /* Ok, Sp points to the enclosing CATCH_FRAME or CATCH_STM_FRAME. Pop everything @@ -492,7 +513,7 @@ retry_pop_stack: * token as arguments. */ Sp_adj(-1); - Sp(0) = R1; + Sp(0) = exception; R1 = handler; Sp_adj(-1); TICK_UNKNOWN_CALL();