diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-03-17 14:49:39 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-03-17 14:49:39 +0000 |
commit | f8f4cb3f3a46e0495917a927cefe906531b7b38e (patch) | |
tree | d73d7f883bda109e68dca56cc9ab6e5258aa8e6d /rts/StgStdThunks.cmm | |
parent | 0ee0be109fd00ec629f7a2ad6a597885a0c9d5b4 (diff) | |
download | haskell-f8f4cb3f3a46e0495917a927cefe906531b7b38e.tar.gz |
FIX biographical profiling (#3039, probably #2297)
Since we introduced pointer tagging, we no longer always enter a
closure to evaluate it. However, the biographical profiler relies on
closures being entered in order to mark them as "used", so we were
getting spurious amounts of data attributed to VOID. It turns out
there are various places that need to be fixed, and I think at least
one of them was also wrong before pointer tagging (CgCon.cgReturnDataCon).
Diffstat (limited to 'rts/StgStdThunks.cmm')
-rw-r--r-- | rts/StgStdThunks.cmm | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/rts/StgStdThunks.cmm b/rts/StgStdThunks.cmm index fecbb4c3c0..be85999598 100644 --- a/rts/StgStdThunks.cmm +++ b/rts/StgStdThunks.cmm @@ -52,7 +52,22 @@ * so we untag it before accessing the field. * */ -#define SELECTOR_CODE_UPD(offset) \ +#ifdef PROFILING +// When profiling, we cannot shortcut by checking the tag, +// because LDV profiling relies on entering closures to mark them as +// "used". +#define SEL_ENTER(offset) \ + R1 = UNTAG(R1); \ + jump %GET_ENTRY(R1); +#else +#define SEL_ENTER(offset) \ + if (GETTAG(R1) != 0) { \ + jump RET_LBL(stg_sel_ret_##offset##_upd); \ + } \ + jump %GET_ENTRY(R1); +#endif + +#define SELECTOR_CODE_UPD(offset) \ INFO_TABLE_RET(stg_sel_ret_##offset##_upd, RET_SMALL, RET_PARAMS) \ { \ R1 = StgClosure_payload(UNTAG(R1),offset); \ @@ -73,10 +88,7 @@ W_[Sp-WITHUPD_FRAME_SIZE] = stg_sel_ret_##offset##_upd_info; \ Sp = Sp - WITHUPD_FRAME_SIZE; \ R1 = StgThunk_payload(R1,0); \ - if (GETTAG(R1) != 0) { \ - jump RET_LBL(stg_sel_ret_##offset##_upd); \ - } \ - jump %GET_ENTRY(R1); \ + SEL_ENTER(offset); \ } /* NOTE: no need to ENTER() here, we know the closure cannot evaluate to a function, because we're going to do a field selection on the result. */ |