diff options
author | Simon Marlow <marlowsd@gmail.com> | 2013-09-17 21:48:39 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2013-10-01 11:10:08 +0100 |
commit | 11b5ce550d1a9bc84dd97629e1cca0b356054898 (patch) | |
tree | 5446e455f6165f50291c8877fdead17b74cae13f /rts | |
parent | 56084d76eb1b57ad96a9e1c55f3d3e2d134f98d5 (diff) | |
download | haskell-11b5ce550d1a9bc84dd97629e1cca0b356054898.tar.gz |
Remove use of R9, and fix associated bugs
We were passing the function address to stg_gc_prim_p in R9, which was
wrong because the call was a high-level call and didn't declare R9 as
a parameter. Passing R9 as an argument is the right way, but
unfortunately that exposed another bug: we were using the same macro
in some low-level Cmm, where it is illegal to call functions with
arguments (see Note [syntax of cmm files]). So we now have low-level
variants of STK_CHK() and STK_CHK_P() for use in low-level Cmm code.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Exception.cmm | 8 | ||||
-rw-r--r-- | rts/HeapStackCheck.cmm | 40 | ||||
-rw-r--r-- | rts/PrimOps.cmm | 2 |
3 files changed, 33 insertions, 17 deletions
diff --git a/rts/Exception.cmm b/rts/Exception.cmm index 25da0d6d80..2e18a7aa42 100644 --- a/rts/Exception.cmm +++ b/rts/Exception.cmm @@ -64,7 +64,7 @@ INFO_TABLE_RET(stg_unmaskAsyncExceptionszh_ret, RET_SMALL, W_ info_ptr) /* Eagerly raise a blocked exception, if there is one */ if (StgTSO_blocked_exceptions(CurrentTSO) != END_TSO_QUEUE) { - STK_CHK_P (WDS(2), stg_unmaskAsyncExceptionszh_ret_info, R1); + STK_CHK_P_LL (WDS(2), stg_unmaskAsyncExceptionszh_ret_info, R1); /* * We have to be very careful here, as in killThread#, since * we are about to raise an async exception in the current @@ -129,7 +129,7 @@ INFO_TABLE_RET(stg_maskUninterruptiblezh_ret, RET_SMALL, W_ info_ptr) stg_maskAsyncExceptionszh /* explicit stack */ { /* Args: R1 :: IO a */ - STK_CHK_P( WDS(1)/* worst case */, stg_maskAsyncExceptionszh, R1); + STK_CHK_P_LL (WDS(1)/* worst case */, stg_maskAsyncExceptionszh, R1); if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_BLOCKEX) == 0) { /* avoid growing the stack unnecessarily */ @@ -157,7 +157,7 @@ stg_maskAsyncExceptionszh /* explicit stack */ stg_maskUninterruptiblezh /* explicit stack */ { /* Args: R1 :: IO a */ - STK_CHK_P( WDS(1)/* worst case */, stg_maskAsyncExceptionszh, R1); + STK_CHK_P_LL (WDS(1)/* worst case */, stg_maskAsyncExceptionszh, R1); if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_BLOCKEX) == 0) { /* avoid growing the stack unnecessarily */ @@ -191,7 +191,7 @@ stg_unmaskAsyncExceptionszh /* explicit stack */ P_ io; io = R1; - STK_CHK_P (WDS(4), stg_unmaskAsyncExceptionszh, io); + STK_CHK_P_LL (WDS(4), stg_unmaskAsyncExceptionszh, io); /* 4 words: one for the unblock frame, 3 for setting up the * stack to call maybePerformBlockedException() below. */ diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm index e130cb3660..d826529aef 100644 --- a/rts/HeapStackCheck.cmm +++ b/rts/HeapStackCheck.cmm @@ -172,38 +172,54 @@ __stg_gc_enter_1 (P_ node) code in a few common cases. -------------------------------------------------------------------------- */ -stg_gc_prim () +stg_gc_prim (W_ fun) { - W_ fun; - fun = R9; call stg_gc_noregs (); jump fun(); } -stg_gc_prim_p (P_ arg) +stg_gc_prim_p (P_ arg, W_ fun) { - W_ fun; - fun = R9; call stg_gc_noregs (); jump fun(arg); } -stg_gc_prim_pp (P_ arg1, P_ arg2) +stg_gc_prim_pp (P_ arg1, P_ arg2, W_ fun) { - W_ fun; - fun = R9; call stg_gc_noregs (); jump fun(arg1,arg2); } -stg_gc_prim_n (W_ arg) +stg_gc_prim_n (W_ arg, W_ fun) { - W_ fun; - fun = R9; call stg_gc_noregs (); jump fun(arg); } +stg_gc_prim_p_ll_ret +{ + W_ fun; + P_ arg; + fun = Sp(2); + arg = Sp(1); + Sp_adj(3); + R1 = arg; + jump fun [R1]; +} + +stg_gc_prim_p_ll +{ + W_ fun; + P_ arg; + fun = R2; + arg = R1; + Sp_adj(-3); + Sp(2) = fun; + Sp(1) = arg; + Sp(0) = stg_gc_prim_p_ll_ret; + jump stg_gc_noregs []; +} + /* ----------------------------------------------------------------------------- stg_enter_checkbh is just like stg_enter, except that we also call checkBlockingQueues(). The point of this is that the GC can diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index e278bb70ab..e539c7cde3 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -2069,7 +2069,7 @@ stg_noDuplicatezh /* no arg list: explicit stack layout */ jump %ENTRY_CODE(Sp(0)) []; } - STK_CHK(WDS(1), stg_noDuplicatezh); + STK_CHK_LL (WDS(1), stg_noDuplicatezh); // leave noDuplicate frame in case the current // computation is suspended and restarted (see above). |