X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FStgStdThunks.cmm;h=be859995981d18236975aa8301f790a3d6b2a525;hp=342a6eb1648a608065fed24371f102c385386767;hb=890f22ef8eff8dbb5b31fa221dfce65a7b84c202;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1 diff --git a/rts/StgStdThunks.cmm b/rts/StgStdThunks.cmm index 342a6eb..be85999 100644 --- a/rts/StgStdThunks.cmm +++ b/rts/StgStdThunks.cmm @@ -32,19 +32,45 @@ #ifdef PROFILING #define SAVE_CCCS(fs) StgHeader_ccs(Sp-fs) = W_[CCCS] #define GET_SAVED_CCCS W_[CCCS] = StgHeader_ccs(Sp) -#define RET_BITMAP 3 -#define RET_FRAMESIZE 2 +#define RET_PARAMS W_ unused1, W_ unused2 #else #define SAVE_CCCS(fs) /* empty */ #define GET_SAVED_CCCS /* empty */ -#define RET_BITMAP 0 -#define RET_FRAMESIZE 0 +#define RET_PARAMS #endif -#define SELECTOR_CODE_UPD(offset) \ - INFO_TABLE_RET(stg_sel_ret_##offset##_upd, RET_FRAMESIZE, RET_BITMAP, RET_SMALL) \ +/* + * TODO: On return, we can use a more efficient + * untagging (we know the constructor tag). + * + * When entering stg_sel_#_upd, we know R1 points to its closure, + * so it's untagged. + * The payload might be a thunk or a constructor, + * so we enter it. + * + * When returning, we know for sure it is a constructor, + * so we untag it before accessing the field. + * + */ +#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(R1,offset); \ + R1 = StgClosure_payload(UNTAG(R1),offset); \ GET_SAVED_CCCS; \ Sp = Sp + SIZEOF_StgHeader; \ ENTER(); \ @@ -60,9 +86,9 @@ ENTER_CCS_THUNK(R1); \ SAVE_CCCS(WITHUPD_FRAME_SIZE); \ W_[Sp-WITHUPD_FRAME_SIZE] = stg_sel_ret_##offset##_upd_info; \ - R1 = StgThunk_payload(R1,0); \ Sp = Sp - WITHUPD_FRAME_SIZE; \ - jump %GET_ENTRY(R1); \ + R1 = StgThunk_payload(R1,0); \ + 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. */ @@ -85,12 +111,12 @@ SELECTOR_CODE_UPD(14) SELECTOR_CODE_UPD(15) #define SELECTOR_CODE_NOUPD(offset) \ - INFO_TABLE_RET(stg_sel_ret_##offset##_noupd, RET_FRAMESIZE, RET_BITMAP, RET_SMALL) \ + INFO_TABLE_RET(stg_sel_ret_##offset##_noupd, RET_SMALL, RET_PARAMS) \ { \ - R1 = StgClosure_payload(R1,offset); \ + R1 = StgClosure_payload(UNTAG(R1),offset); \ GET_SAVED_CCCS; \ Sp = Sp + SIZEOF_StgHeader; \ - jump %GET_ENTRY(R1); \ + ENTER(); \ } \ \ INFO_TABLE_SELECTOR(stg_sel_##offset##_noupd, offset, THUNK_SELECTOR, "stg_sel_noupd", "stg_sel_noupd")\ @@ -103,8 +129,11 @@ SELECTOR_CODE_UPD(15) ENTER_CCS_THUNK(R1); \ SAVE_CCCS(NOUPD_FRAME_SIZE); \ W_[Sp-NOUPD_FRAME_SIZE] = stg_sel_ret_##offset##_noupd_info; \ - R1 = StgThunk_payload(R1,0); \ Sp = Sp - NOUPD_FRAME_SIZE; \ + R1 = StgThunk_payload(R1,0); \ + if (GETTAG(R1) != 0) { \ + jump RET_LBL(stg_sel_ret_##offset##_noupd); \ + } \ jump %GET_ENTRY(R1); \ } @@ -143,7 +172,7 @@ SELECTOR_CODE_NOUPD(15) * in the compiler that means stg_ap_1 is generated occasionally (ToDo) */ -INFO_TABLE(stg_ap_1_upd,1,1,THUNK_1_0,"stg_ap_1_upd_info","stg_ap_1_upd_info") +INFO_TABLE(stg_ap_1_upd,1,0,THUNK_1_0,"stg_ap_1_upd_info","stg_ap_1_upd_info") { TICK_ENT_DYN_THK(); STK_CHK_NP(SIZEOF_StgUpdateFrame+WDS(1));