summaryrefslogtreecommitdiff
path: root/rts/StgStdThunks.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2013-10-11 10:35:14 +0100
committerSimon Marlow <marlowsd@gmail.com>2013-10-11 10:37:02 +0100
commit83be3d7b8881eca63adf834e425e6799e572bd1f (patch)
treec810919459e70599b51e094be3d7e8024c4f1307 /rts/StgStdThunks.cmm
parent8ea8c371f345e3a265d425b37e793d8b553a1588 (diff)
downloadhaskell-83be3d7b8881eca63adf834e425e6799e572bd1f.tar.gz
Fix a bug in the canned selector code when profiling.
Diffstat (limited to 'rts/StgStdThunks.cmm')
-rw-r--r--rts/StgStdThunks.cmm22
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; \
} \