diff options
author | Simon Marlow <marlowsd@gmail.com> | 2013-10-11 10:35:14 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2013-10-11 10:37:02 +0100 |
commit | 83be3d7b8881eca63adf834e425e6799e572bd1f (patch) | |
tree | c810919459e70599b51e094be3d7e8024c4f1307 /rts/StgStdThunks.cmm | |
parent | 8ea8c371f345e3a265d425b37e793d8b553a1588 (diff) | |
download | haskell-83be3d7b8881eca63adf834e425e6799e572bd1f.tar.gz |
Fix a bug in the canned selector code when profiling.
Diffstat (limited to 'rts/StgStdThunks.cmm')
-rw-r--r-- | rts/StgStdThunks.cmm | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/rts/StgStdThunks.cmm b/rts/StgStdThunks.cmm index 979f7498ca..ba15d3c1fc 100644 --- a/rts/StgStdThunks.cmm +++ b/rts/StgStdThunks.cmm @@ -49,9 +49,15 @@ * */ #ifdef PROFILING -// When profiling, we cannot shortcut by checking the tag, -// because LDV profiling relies on entering closures to mark them as -// "used". +/* When profiling, we cannot shortcut by checking the tag, + * because LDV profiling relies on entering closures to mark them as + * "used". + * + * Note [untag for prof]: when we enter a closure, the convention is + * that the closure pointer passed in the first argument is + * *untagged*. Without profiling we don't have to worry about this, + * because we never enter a tagged pointer. + */ #define NEED_EVAL(__x__) 1 #else #define NEED_EVAL(__x__) GETTAG(__x__) == 0 @@ -61,7 +67,7 @@ INFO_TABLE_SELECTOR(stg_sel_##offset##_upd, offset, THUNK_SELECTOR, "stg_sel_upd", "stg_sel_upd") \ (P_ node) \ { \ - P_ selectee, field; \ + P_ selectee, field, dest; \ TICK_ENT_DYN_THK(); \ STK_CHK_NP(node); \ UPD_BH_UPDATABLE(node); \ @@ -71,7 +77,8 @@ ENTER_CCS_THUNK(node); \ if (NEED_EVAL(selectee)) { \ SAVE_CCS; \ - (P_ constr) = call %GET_ENTRY(UNTAG_IF_PROF(selectee)) (selectee); \ + dest = UNTAG_IF_PROF(selectee); /* Note [untag for prof] */ \ + (P_ constr) = call %GET_ENTRY(dest) (dest); \ RESTORE_CCS; \ selectee = constr; \ } \ @@ -105,7 +112,7 @@ SELECTOR_CODE_UPD(15) INFO_TABLE_SELECTOR(stg_sel_##offset##_noupd, offset, THUNK_SELECTOR, "stg_sel_noupd", "stg_sel_noupd") \ (P_ node) \ { \ - P_ selectee, field; \ + P_ selectee, field, dest; \ TICK_ENT_DYN_THK(); \ STK_CHK_NP(node); \ UPD_BH_UPDATABLE(node); \ @@ -114,7 +121,8 @@ SELECTOR_CODE_UPD(15) ENTER_CCS_THUNK(node); \ if (NEED_EVAL(selectee)) { \ SAVE_CCS; \ - (P_ constr) = call %GET_ENTRY(UNTAG_IF_PROF(selectee)) (selectee); \ + dest = UNTAG_IF_PROF(selectee); /* Note [untag for prof] */ \ + (P_ constr) = call %GET_ENTRY(dest) (dest); \ RESTORE_CCS; \ selectee = constr; \ } \ |