X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FStgStdThunks.cmm;h=fecbb4c3c0f2a72b6ecf8fea2a363e48bc08442e;hp=db9c2542338ef4a63f418f29ee60c9132911a9c0;hb=45202530612593a0ba7a6c559a38dc1ff26670a4;hpb=d31dfb32ea936c22628b508c28a36c12e631430a diff --git a/rts/StgStdThunks.cmm b/rts/StgStdThunks.cmm index db9c254..fecbb4c 100644 --- a/rts/StgStdThunks.cmm +++ b/rts/StgStdThunks.cmm @@ -39,10 +39,23 @@ #define RET_PARAMS #endif +/* + * 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. + * + */ #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(); \ @@ -58,8 +71,11 @@ 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; \ + R1 = StgThunk_payload(R1,0); \ + if (GETTAG(R1) != 0) { \ + jump RET_LBL(stg_sel_ret_##offset##_upd); \ + } \ jump %GET_ENTRY(R1); \ } /* NOTE: no need to ENTER() here, we know the closure cannot evaluate to a function, @@ -85,10 +101,10 @@ SELECTOR_CODE_UPD(15) #define SELECTOR_CODE_NOUPD(offset) \ 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")\ @@ -101,8 +117,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); \ } @@ -141,7 +160,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));