summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2013-09-17 21:48:39 +0100
committerSimon Marlow <marlowsd@gmail.com>2013-10-01 11:10:08 +0100
commit11b5ce550d1a9bc84dd97629e1cca0b356054898 (patch)
tree5446e455f6165f50291c8877fdead17b74cae13f /rts
parent56084d76eb1b57ad96a9e1c55f3d3e2d134f98d5 (diff)
downloadhaskell-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.cmm8
-rw-r--r--rts/HeapStackCheck.cmm40
-rw-r--r--rts/PrimOps.cmm2
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).