From: simonmar Date: Mon, 28 Feb 2005 17:01:23 +0000 (+0000) Subject: [project @ 2005-02-28 17:01:13 by simonmar] X-Git-Tag: Initial_conversion_from_CVS_complete~1008 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=6d194f48d7313fa8daa004b7b3e3a55ffa52f4a9 [project @ 2005-02-28 17:01:13 by simonmar] Optimisation: the update code only needs to check whether the closure being updated is a BLACKHOLE_BQ if it has been blackholed; which is only the case after lazy blackholing has taken place. So to avoid this unnecessary cost, we have two kinds of update frame: one which checks for BLACKHOLE_BQ and one that doesn't, and the lazy blackholing algorithm converts the latter kind into the former as it replaces thunks with blackholes. --- diff --git a/ghc/includes/StgMiscClosures.h b/ghc/includes/StgMiscClosures.h index 16d1483..18e9b63 100644 --- a/ghc/includes/StgMiscClosures.h +++ b/ghc/includes/StgMiscClosures.h @@ -37,6 +37,7 @@ /* Stack frames */ RTS_RET_INFO(stg_upd_frame_info); +RTS_RET_INFO(stg_bh_upd_frame_info); RTS_RET_INFO(stg_noupd_frame_info); RTS_RET_INFO(stg_seq_frame_info); RTS_RET_INFO(stg_catch_frame_info); @@ -45,6 +46,7 @@ RTS_RET_INFO(stg_atomically_frame_info); RTS_RET_INFO(stg_catch_stm_frame_info); RTS_ENTRY(stg_upd_frame_ret); +RTS_ENTRY(stg_bh_upd_frame_ret); RTS_ENTRY(stg_seq_frame_ret); /* Entry code for constructors created by the bytecode interpreter */ diff --git a/ghc/includes/Updates.h b/ghc/includes/Updates.h index 0845e20..034412e 100644 --- a/ghc/includes/Updates.h +++ b/ghc/includes/Updates.h @@ -28,12 +28,16 @@ UPD_PERM_IND(updclosure,heapptr) # define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \ UPD_PERM_IND(updclosure,heapptr); and_then +# define NOBH_UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \ + NOBH_UPD_PERM_IND(updclosure,heapptr); and_then #else # define SEMI ; # define UPD_IND(updclosure, heapptr) \ UPD_REAL_IND(updclosure,INFO_PTR(stg_IND_info),heapptr,SEMI) # define UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \ UPD_REAL_IND(updclosure,ind_info,heapptr,and_then) +# define NOBH_UPD_SPEC_IND(updclosure, ind_info, heapptr, and_then) \ + NOBH_UPD_REAL_IND(updclosure,ind_info,heapptr,and_then) #endif /* These macros have to work in both C and C--, so here's the @@ -71,6 +75,14 @@ and_then); \ BLOCK_END +#define NOBH_UPD_REAL_IND(updclosure, ind_info, heapptr, and_then) \ + BLOCK_BEGIN \ + updateWithIndirection(GET_INFO(updclosure), ind_info, \ + updclosure, \ + heapptr, \ + and_then); \ + BLOCK_END + #if defined(PROFILING) || defined(TICKY_TICKY) #define UPD_PERM_IND(updclosure, heapptr) \ BLOCK_BEGIN \ @@ -81,6 +93,13 @@ updclosure, \ heapptr); \ BLOCK_END + +#define NOBH_UPD_PERM_IND(updclosure, heapptr) \ + BLOCK_BEGIN \ + updateWithPermIndirection(GET_INFO(updclosure), \ + updclosure, \ + heapptr); \ + BLOCK_END #endif #if defined(RTS_SUPPORTS_THREADS) diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index a470f32..75f11a2 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -4121,6 +4121,11 @@ threadSqueezeStack(StgTSO *tso) // Todo: maybe use SET_HDR() and remove LDV_RECORD_CREATE()? SET_INFO(bh,&stg_BLACKHOLE_info); + // Set the update frame to stg_bh_upd_info, which + // checks for blackholes (the normal update frame + // doesn't check, for efficiency). + ((StgClosure *)frame)->header.info = &stg_bh_upd_frame_info; + // We pretend that bh has just been created. LDV_RECORD_CREATE(bh); } diff --git a/ghc/rts/Makefile b/ghc/rts/Makefile index fe7841c..15cbdd4 100644 --- a/ghc/rts/Makefile +++ b/ghc/rts/Makefile @@ -338,14 +338,10 @@ ifneq "$(BootingFromHc)" "YES" $(HC_POST_OPTS) %.$(way_)hc : %.cmm $(H_FILES) - $(HC_PRE_OPTS) $(HC) $(HC_OPTS) -C $< -o $@ - $(HC_POST_OPTS) %.$(way_)s : %.cmm $(H_FILES) - $(HC_PRE_OPTS) $(HC) $(HC_OPTS) -S $< -o $@ - $(HC_POST_OPTS) endif #----------------------------------------------------------------------------- diff --git a/ghc/rts/Updates.cmm b/ghc/rts/Updates.cmm index 02d1827..bec9b40 100644 --- a/ghc/rts/Updates.cmm +++ b/ghc/rts/Updates.cmm @@ -55,7 +55,7 @@ /* ToDo: it might be a PAP, so we should check... */ \ TICK_UPD_CON_IN_NEW(sizeW_fromITBL(%GET_STD_INFO(updatee))); \ \ - UPD_SPEC_IND(updatee, ind_info, R1, jump (ret)); \ + NOBH_UPD_SPEC_IND(updatee, ind_info, R1, jump (ret)); \ } UPD_FRAME_ENTRY_TEMPLATE(stg_upd_frame_0_ret,stg_IND_0_info,%RET_VEC(Sp(0),0)) @@ -102,6 +102,62 @@ INFO_TABLE_RET( stg_upd_frame, ) UPD_FRAME_ENTRY_TEMPLATE(,stg_IND_direct_info,%ENTRY_CODE(Sp(0))) +/* ----------------------------------------------------------------------------- + * Update frames that check for BLACKHOLE_BQ + * + * A normal update frame doesn't check whether the closure has been + * overwritten with BLACKHOLE_BQ, because it can't until lazy blackholing + * has happened. Lazy blackholing overwrites the update frames pointing + * to BLACKHOLE with stg_bh_upd_frame_info. + * -------------------------------------------------------------------------- */ + +#define BH_UPD_FRAME_ENTRY_TEMPLATE(label,ind_info,ret) \ + label \ + { \ + W_ updatee; \ + \ + updatee = StgUpdateFrame_updatee(Sp); \ + \ + /* remove the update frame from the stack */ \ + Sp = Sp + SIZEOF_StgUpdateFrame; \ + \ + /* ToDo: it might be a PAP, so we should check... */ \ + TICK_UPD_CON_IN_NEW(sizeW_fromITBL(%GET_STD_INFO(updatee))); \ + \ + UPD_SPEC_IND(updatee, ind_info, R1, jump (ret)); \ + } + +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_0_ret,stg_IND_0_info,%RET_VEC(Sp(0),0)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_1_ret,stg_IND_1_info,%RET_VEC(Sp(0),1)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_2_ret,stg_IND_2_info,%RET_VEC(Sp(0),2)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_3_ret,stg_IND_3_info,%RET_VEC(Sp(0),3)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_4_ret,stg_IND_4_info,%RET_VEC(Sp(0),4)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_5_ret,stg_IND_5_info,%RET_VEC(Sp(0),5)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_6_ret,stg_IND_6_info,%RET_VEC(Sp(0),6)) +BH_UPD_FRAME_ENTRY_TEMPLATE(stg_bh_upd_frame_7_ret,stg_IND_7_info,%RET_VEC(Sp(0),7)) + +#if MAX_VECTORED_RTN > 8 +#error MAX_VECTORED_RTN has changed: please modify stg_bh_upd_frame too. +#endif + +/* this bitmap indicates that the first word of an update frame is a + * non-pointer - this is the update frame link. (for profiling, + * there's a cost-centre-stack in there too). + */ + +INFO_TABLE_RET( stg_bh_upd_frame, + UPD_FRAME_WORDS, UPD_FRAME_BITMAP, UPDATE_FRAME, + stg_bh_upd_frame_0_ret, + stg_bh_upd_frame_1_ret, + stg_bh_upd_frame_2_ret, + stg_bh_upd_frame_3_ret, + stg_bh_upd_frame_4_ret, + stg_bh_upd_frame_5_ret, + stg_bh_upd_frame_6_ret, + stg_bh_upd_frame_7_ret + ) +UPD_FRAME_ENTRY_TEMPLATE(,stg_IND_direct_info,%ENTRY_CODE(Sp(0))) + /*----------------------------------------------------------------------------- Seq frames