Commit 6d194f48 authored by simonmar's avatar simonmar
Browse files

[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.
parent a8428524
......@@ -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 */
......
......@@ -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)
......
......@@ -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);
}
......
......@@ -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
#-----------------------------------------------------------------------------
......
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment