X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStgMiscClosures.hc;h=13a8809a9b2c0b420cc937c3a35fb2283a11a595;hb=e030a747f89512121e582d302986ff6732ebb0c6;hp=ed17edf583c4ab16b22d16f0f016ec8265ecd4ca;hpb=3e39d84d579ed32be0db9955265500a82d21e4c6;p=ghc-hetmet.git diff --git a/ghc/rts/StgMiscClosures.hc b/ghc/rts/StgMiscClosures.hc index ed17edf..13a8809 100644 --- a/ghc/rts/StgMiscClosures.hc +++ b/ghc/rts/StgMiscClosures.hc @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: StgMiscClosures.hc,v 1.55 2000/12/14 16:32:40 sewardj Exp $ + * $Id: StgMiscClosures.hc,v 1.80 2002/09/17 12:34:31 simonmar Exp $ * * (c) The GHC Team, 1998-2000 * @@ -7,11 +7,11 @@ * * ---------------------------------------------------------------------------*/ +#include "Stg.h" #include "Rts.h" #include "RtsUtils.h" #include "RtsFlags.h" #include "StgMiscClosures.h" -#include "HeapStackCheck.h" /* for stg_gen_yield */ #include "Storage.h" #include "StoragePriv.h" #include "Profiling.h" @@ -23,8 +23,8 @@ # include "StgRun.h" /* for StgReturn and register saving */ #endif -#ifdef HAVE_STDIO_H -#include +#ifdef HAVE_STDLIB_H +#include #endif /* ToDo: make the printing of panics more win32-friendly, i.e., @@ -36,14 +36,12 @@ Template for the entry code of non-enterable closures. */ -#define NON_ENTERABLE_ENTRY_CODE(type) \ -STGFUN(stg_##type##_entry) \ -{ \ - FB_ \ - DUMP_ERRMSG(#type " object entered!\n"); \ - STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE); \ - return NULL; \ - FE_ \ +#define NON_ENTERABLE_ENTRY_CODE(type) \ +STGFUN(stg_##type##_entry) \ +{ \ + FB_ \ + STGCALL1(barf, #type " object entered!\n"); \ + FE_ \ } @@ -51,14 +49,12 @@ STGFUN(stg_##type##_entry) \ Support for the bytecode interpreter. -------------------------------------------------------------------------- */ -#ifdef GHCI - /* 9 bits of return code for constructors created by the interpreter. */ FN_(stg_interp_constr_entry) { /* R1 points at the constructor */ FB_ - STGCALL2(fprintf,stderr,"stg_interp_constr_entry (direct return)!\n"); + /* STGCALL2(fprintf,stderr,"stg_interp_constr_entry (direct return)!\n"); */ /* Pointless, since SET_TAG doesn't do anything */ SET_TAG( GET_TAG(GET_INFO(R1.cl))); JMP_(ENTRY_CODE((P_)(*Sp))); @@ -77,7 +73,7 @@ FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ } /* Some info tables to be used when compiled code returns a value to the interpreter, i.e. the interpreter pushes one of these onto the stack before entering a value. What the code does is to - impedance-match the compiled return convention (in R1/F1/D1 etc) to + impedance-match the compiled return convention (in R1p/R1n/F1/D1 etc) to the interpreter's convention (returned value is on top of stack), and then cause the scheduler to enter the interpreter. @@ -87,7 +83,7 @@ FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ } ptr to one of these info tables. The info table code, both direct and vectored, must: - * push R1/F1/D1 on the stack + * push R1/F1/D1 on the stack, and its tag if necessary * push the BCO (so it's now on the stack twice) * Yield, ie, go to the scheduler. @@ -108,8 +104,9 @@ FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ } haven't got a good story about that yet. */ -/* When the returned value is in R1 ... */ -#define STG_CtoI_RET_R1_Template(label) \ +/* When the returned value is in R1 and it is a pointer, so doesn't + need tagging ... */ +#define STG_CtoI_RET_R1p_Template(label) \ IFN_(label) \ { \ StgPtr bco; \ @@ -123,22 +120,137 @@ FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ } FE_ \ } -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_0_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_1_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_2_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_3_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_4_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_5_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_6_entry); -STG_CtoI_RET_R1_Template(stg_ctoi_ret_R1_7_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_0_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_1_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_2_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_3_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_4_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_5_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_6_entry); +STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_7_entry); + +VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1p,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); + + + +/* When the returned value is in R1 and it isn't a pointer. */ +#define STG_CtoI_RET_R1n_Template(label) \ + IFN_(label) \ + { \ + StgPtr bco; \ + FB_ \ + bco = ((StgPtr*)Sp)[1]; \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = (StgPtr)R1.i; \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = (StgPtr)1; /* tag */ \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = bco; \ + JMP_(stg_yield_to_interpreter); \ + FE_ \ + } + +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_0_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_1_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_2_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_3_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_4_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_5_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_6_entry); +STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_7_entry); + +VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1n,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); + -VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); /* When the returned value is in F1 ... */ -/* TODO */ +#define STG_CtoI_RET_F1_Template(label) \ + IFN_(label) \ + { \ + StgPtr bco; \ + FB_ \ + bco = ((StgPtr*)Sp)[1]; \ + Sp -= sizeofW(StgFloat); \ + ASSIGN_FLT((W_*)Sp, F1); \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgFloat); \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = bco; \ + JMP_(stg_yield_to_interpreter); \ + FE_ \ + } + +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_0_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_1_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_2_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_3_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_4_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_5_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_6_entry); +STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_7_entry); + +VEC_POLY_INFO_TABLE(stg_ctoi_ret_F1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); + + /* When the returned value is in D1 ... */ -/* TODO */ +#define STG_CtoI_RET_D1_Template(label) \ + IFN_(label) \ + { \ + StgPtr bco; \ + FB_ \ + bco = ((StgPtr*)Sp)[1]; \ + Sp -= sizeofW(StgDouble); \ + ASSIGN_DBL((W_*)Sp, D1); \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgDouble); \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = bco; \ + JMP_(stg_yield_to_interpreter); \ + FE_ \ + } + +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_0_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_1_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_2_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_3_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_4_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_5_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_6_entry); +STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_7_entry); + +VEC_POLY_INFO_TABLE(stg_ctoi_ret_D1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); + + +/* When the returned value a VoidRep ... */ +#define STG_CtoI_RET_V_Template(label) \ + IFN_(label) \ + { \ + StgPtr bco; \ + FB_ \ + bco = ((StgPtr*)Sp)[1]; \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = 0; /* VoidRep tag */ \ + Sp -= 1; \ + ((StgPtr*)Sp)[0] = bco; \ + JMP_(stg_yield_to_interpreter); \ + FE_ \ + } + +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_0_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_1_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_2_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_3_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_4_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_5_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_6_entry); +STG_CtoI_RET_V_Template(stg_ctoi_ret_V_7_entry); + +VEC_POLY_INFO_TABLE(stg_ctoi_ret_V,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_); /* The other way round: when the interpreter returns a value to @@ -160,7 +272,7 @@ VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, /* Entering a BCO. Heave it on the stack and defer to the scheduler. */ -INFO_TABLE(stg_BCO_info,stg_BCO_entry,3,0,BCO,,EF_,"BCO","BCO"); +INFO_TABLE(stg_BCO_info,stg_BCO_entry,4,0,BCO,,EF_,"BCO","BCO"); STGFUN(stg_BCO_entry) { FB_ Sp -= 1; @@ -169,33 +281,30 @@ STGFUN(stg_BCO_entry) { FE_ } -#endif /* GHCI */ - /* ----------------------------------------------------------------------------- Entry code for an indirection. -------------------------------------------------------------------------- */ -INFO_TABLE(stg_IND_info,stg_IND_entry,1,0,IND,,EF_,0,0); +INFO_TABLE(stg_IND_info,stg_IND_entry,1,0,IND,,EF_,"IND","IND"); STGFUN(stg_IND_entry) { FB_ - TICK_ENT_IND(Node); /* tick */ - + TICK_ENT_DYN_IND(Node); /* tick */ R1.p = (P_) ((StgInd*)R1.p)->indirectee; TICK_ENT_VIA_NODE(); - JMP_(ENTRY_CODE(*R1.p)); + JMP_(GET_ENTRY(R1.cl)); FE_ } -INFO_TABLE(stg_IND_STATIC_info,stg_IND_STATIC_entry,1,0,IND_STATIC,,EF_,0,0); +INFO_TABLE(stg_IND_STATIC_info,stg_IND_STATIC_entry,1,0,IND_STATIC,,EF_,"IND_STATIC","IND_STATIC"); STGFUN(stg_IND_STATIC_entry) { FB_ - TICK_ENT_IND(Node); /* tick */ + TICK_ENT_STATIC_IND(Node); /* tick */ R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee; TICK_ENT_VIA_NODE(); - JMP_(ENTRY_CODE(*R1.p)); + JMP_(GET_ENTRY(R1.cl)); FE_ } @@ -204,13 +313,15 @@ STGFUN(stg_IND_PERM_entry) { FB_ /* Don't add INDs to granularity cost */ - /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */ + /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */ #if defined(TICKY_TICKY) && !defined(PROFILING) /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */ TICK_ENT_PERM_IND(R1.p); /* tick */ #endif + LDV_ENTER((StgInd *)R1.p); + /* Enter PAP cost centre -- lexical scoping only */ ENTER_CCS_PAP_CL(R1.cl); @@ -226,7 +337,7 @@ STGFUN(stg_IND_PERM_entry) # ifdef PROFILING # error Profiling and ticky-ticky do not mix at present! # endif /* PROFILING */ - SET_INFO((StgInd*)R1.p,&IND_info); + SET_INFO((StgInd*)R1.p,&stg_IND_info); #endif /* TICKY_TICKY */ R1.p = (P_) ((StgInd*)R1.p)->indirectee; @@ -237,33 +348,34 @@ STGFUN(stg_IND_PERM_entry) TICK_ENT_VIA_NODE(); #endif - JMP_(ENTRY_CODE(*R1.p)); + JMP_(GET_ENTRY(R1.cl)); FE_ } -INFO_TABLE(stg_IND_OLDGEN_info,stg_IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,0,0); +INFO_TABLE(stg_IND_OLDGEN_info,stg_IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,"IND_OLDGEN","IND_OLDGEN"); STGFUN(stg_IND_OLDGEN_entry) { FB_ - TICK_ENT_IND(Node); /* tick */ - + TICK_ENT_STATIC_IND(Node); /* tick */ R1.p = (P_) ((StgInd*)R1.p)->indirectee; TICK_ENT_VIA_NODE(); - JMP_(ENTRY_CODE(*R1.p)); + JMP_(GET_ENTRY(R1.cl)); FE_ } -INFO_TABLE(stg_IND_OLDGEN_PERM_info,stg_IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,0,0); +INFO_TABLE(stg_IND_OLDGEN_PERM_info,stg_IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,"IND_OLDGEN_PERM","IND_OLDGEN_PERM"); STGFUN(stg_IND_OLDGEN_PERM_entry) { FB_ - /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */ + /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */ #if defined(TICKY_TICKY) && !defined(PROFILING) /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */ TICK_ENT_PERM_IND(R1.p); /* tick */ #endif - + + LDV_ENTER((StgInd *)R1.p); + /* Enter PAP cost centre -- lexical scoping only */ ENTER_CCS_PAP_CL(R1.cl); @@ -272,39 +384,11 @@ STGFUN(stg_IND_OLDGEN_PERM_entry) # ifdef PROFILING # error Profiling and ticky-ticky do not mix at present! # endif /* PROFILING */ - SET_INFO((StgInd*)R1.p,&IND_OLDGEN_info); + SET_INFO((StgInd*)R1.p,&stg_IND_OLDGEN_info); #endif /* TICKY_TICKY */ R1.p = (P_) ((StgInd*)R1.p)->indirectee; TICK_ENT_VIA_NODE(); - JMP_(ENTRY_CODE(*R1.p)); - FE_ -} - -/* ----------------------------------------------------------------------------- - Entry code for CAFs - - This code assumes R1 is in a register for now. - -------------------------------------------------------------------------- */ - -INFO_TABLE(stg_CAF_UNENTERED_info,stg_CAF_UNENTERED_entry,1,3,CAF_UNENTERED,,EF_,0,0); -STGFUN(stg_CAF_UNENTERED_entry) -{ - FB_ - /* ToDo: implement directly in GHC */ - Sp -= 1; - Sp[0] = R1.w; - JMP_(stg_yield_to_interpreter); - FE_ -} - -/* 0,4 is entirely bogus; _do not_ rely on this info */ -INFO_TABLE(stg_CAF_ENTERED_info,stg_CAF_ENTERED_entry,0,4,CAF_ENTERED,,EF_,0,0); -STGFUN(stg_CAF_ENTERED_entry) -{ - FB_ - R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */ - TICK_ENT_VIA_NODE(); JMP_(GET_ENTRY(R1.cl)); FE_ } @@ -337,9 +421,9 @@ STGFUN(stg_BLACKHOLE_entry) #ifdef SMP { bdescr *bd = Bdescr(R1.p); - if (bd->back != (bdescr *)BaseReg) { - if (bd->gen->no >= 1 || bd->step->no >= 1) { - CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info); + if (bd->u.back != (bdescr *)BaseReg) { + if (bd->gen_no >= 1 || bd->step->no >= 1) { + CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info); } else { EXTFUN_RTS(stg_gc_enter_1_hponly); JMP_(stg_gc_enter_1_hponly); @@ -349,28 +433,43 @@ STGFUN(stg_BLACKHOLE_entry) #endif TICK_ENT_BH(); + // Actually this is not necessary because R1.p is about to be destroyed. + LDV_ENTER((StgClosure *)R1.p); + /* Put ourselves on the blocking queue for this black hole */ #if defined(GRAN) || defined(PAR) - /* in fact, only difference is the type of the end-of-queue marker! */ + // in fact, only difference is the type of the end-of-queue marker! CurrentTSO->link = END_BQ_QUEUE; ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO; #else CurrentTSO->link = END_TSO_QUEUE; ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO; #endif - /* jot down why and on what closure we are blocked */ + // jot down why and on what closure we are blocked CurrentTSO->why_blocked = BlockedOnBlackHole; CurrentTSO->block_info.closure = R1.cl; - /* closure is mutable since something has just been added to its BQ */ - recordMutable((StgMutClosure *)R1.cl); + /* Change the BLACKHOLE into a BLACKHOLE_BQ */ +#ifdef PROFILING + + // The size remains the same, so we call LDV_recordDead() - no need to fill slop. + LDV_recordDead((StgClosure *)R1.p, BLACKHOLE_sizeW()); +#endif + // + // Todo: maybe use SET_HDR() and remove LDV_recordCreate()? + // ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info; +#ifdef PROFILING + LDV_recordCreate((StgClosure *)R1.p); +#endif - /* PAR: dumping of event now done in blockThread -- HWL */ + // closure is mutable since something has just been added to its BQ + recordMutable((StgMutClosure *)R1.cl); - /* stg_gen_block is too heavyweight, use a specialised one */ - BLOCK_NP(1); + // PAR: dumping of event now done in blockThread -- HWL + // stg_gen_block is too heavyweight, use a specialised one + BLOCK_NP(1); FE_ } @@ -386,9 +485,9 @@ STGFUN(stg_BLACKHOLE_BQ_entry) #ifdef SMP { bdescr *bd = Bdescr(R1.p); - if (bd->back != (bdescr *)BaseReg) { - if (bd->gen->no >= 1 || bd->step->no >= 1) { - CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info); + if (bd->u.back != (bdescr *)BaseReg) { + if (bd->gen_no >= 1 || bd->step->no >= 1) { + CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info); } else { EXTFUN_RTS(stg_gc_enter_1_hponly); JMP_(stg_gc_enter_1_hponly); @@ -398,6 +497,7 @@ STGFUN(stg_BLACKHOLE_BQ_entry) #endif TICK_ENT_BH(); + LDV_ENTER((StgClosure *)R1.p); /* Put ourselves on the blocking queue for this black hole */ CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue; @@ -430,7 +530,7 @@ STGFUN(stg_BLACKHOLE_BQ_entry) #if defined(PAR) || defined(GRAN) -INFO_TABLE(stg_RBH_info, stg_RBH_entry,1,1,RBH,,EF_,0,0); +INFO_TABLE(stg_RBH_info, stg_RBH_entry,1,1,RBH,,EF_,"RBH","RBH"); STGFUN(stg_RBH_entry) { FB_ @@ -454,13 +554,13 @@ STGFUN(stg_RBH_entry) FE_ } -INFO_TABLE(stg_RBH_Save_0_info, stg_RBH_Save_0_entry,0,2,CONSTR,,EF_,0,0); +INFO_TABLE(stg_RBH_Save_0_info, stg_RBH_Save_0_entry,0,2,CONSTR,,EF_,"RBH_Save_0","RBH_Save_0"); NON_ENTERABLE_ENTRY_CODE(RBH_Save_0); -INFO_TABLE(stg_RBH_Save_1_info, stg_RBH_Save_1_entry,1,1,CONSTR,,EF_,0,0); +INFO_TABLE(stg_RBH_Save_1_info, stg_RBH_Save_1_entry,1,1,CONSTR,,EF_,"RBH_Save_1","RBH_Save_1"); NON_ENTERABLE_ENTRY_CODE(RBH_Save_1); -INFO_TABLE(stg_RBH_Save_2_info, stg_RBH_Save_2_entry,2,0,CONSTR,,EF_,0,0); +INFO_TABLE(stg_RBH_Save_2_info, stg_RBH_Save_2_entry,2,0,CONSTR,,EF_,"RBH_Save_2","RBH_Save_2"); NON_ENTERABLE_ENTRY_CODE(RBH_Save_2); #endif /* defined(PAR) || defined(GRAN) */ @@ -477,9 +577,9 @@ STGFUN(stg_CAF_BLACKHOLE_entry) #ifdef SMP { bdescr *bd = Bdescr(R1.p); - if (bd->back != (bdescr *)BaseReg) { - if (bd->gen->no >= 1 || bd->step->no >= 1) { - CMPXCHG(R1.cl->header.info, &CAF_BLACKHOLE_info, &WHITEHOLE_info); + if (bd->u.back != (bdescr *)BaseReg) { + if (bd->gen_no >= 1 || bd->step->no >= 1) { + CMPXCHG(R1.cl->header.info, &stg_CAF_BLACKHOLE_info, &stg_WHITEHOLE_info); } else { EXTFUN_RTS(stg_gc_enter_1_hponly); JMP_(stg_gc_enter_1_hponly); @@ -489,33 +589,36 @@ STGFUN(stg_CAF_BLACKHOLE_entry) #endif TICK_ENT_BH(); + LDV_ENTER((StgClosure *)R1.p); - /* Put ourselves on the blocking queue for this black hole */ + // Put ourselves on the blocking queue for this black hole #if defined(GRAN) || defined(PAR) - /* in fact, only difference is the type of the end-of-queue marker! */ + // in fact, only difference is the type of the end-of-queue marker! CurrentTSO->link = END_BQ_QUEUE; ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO; #else CurrentTSO->link = END_TSO_QUEUE; ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO; #endif - /* jot down why and on what closure we are blocked */ + // jot down why and on what closure we are blocked CurrentTSO->why_blocked = BlockedOnBlackHole; CurrentTSO->block_info.closure = R1.cl; - /* closure is mutable since something has just been added to its BQ */ - recordMutable((StgMutClosure *)R1.cl); - /* Change the CAF_BLACKHOLE into a BLACKHOLE_BQ */ + + // Change the CAF_BLACKHOLE into a BLACKHOLE_BQ_STATIC ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info; - /* PAR: dumping of event now done in blockThread -- HWL */ + // closure is mutable since something has just been added to its BQ + recordMutable((StgMutClosure *)R1.cl); - /* stg_gen_block is too heavyweight, use a specialised one */ + // PAR: dumping of event now done in blockThread -- HWL + + // stg_gen_block is too heavyweight, use a specialised one BLOCK_NP(1); FE_ } #ifdef TICKY_TICKY -INFO_TABLE(stg_SE_BLACKHOLE_info, stg_SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,0,0); +INFO_TABLE(stg_SE_BLACKHOLE_info, stg_SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,"SE_BLACKHOLE","SE_BLACKHOLE"); STGFUN(stg_SE_BLACKHOLE_entry) { FB_ @@ -524,7 +627,7 @@ STGFUN(stg_SE_BLACKHOLE_entry) FE_ } -INFO_TABLE(SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,0,0); +INFO_TABLE(stg_SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,"CAF_BLACKHOLE","CAF_BLACKHOLE"); STGFUN(stg_SE_CAF_BLACKHOLE_entry) { FB_ @@ -535,7 +638,7 @@ STGFUN(stg_SE_CAF_BLACKHOLE_entry) #endif #ifdef SMP -INFO_TABLE(stg_WHITEHOLE_info, stg_WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,0,0); +INFO_TABLE(stg_WHITEHOLE_info, stg_WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,"WHITEHOLE","WHITEHOLE"); STGFUN(stg_WHITEHOLE_entry) { FB_ @@ -558,7 +661,7 @@ NON_ENTERABLE_ENTRY_CODE(TSO); one is a real bug. -------------------------------------------------------------------------- */ -INFO_TABLE(stg_EVACUATED_info,stg_EVACUATED_entry,1,0,EVACUATED,,EF_,0,0); +INFO_TABLE(stg_EVACUATED_info,stg_EVACUATED_entry,1,0,EVACUATED,,EF_,"EVACUATED","EVACUATED"); NON_ENTERABLE_ENTRY_CODE(EVACUATED); /* ----------------------------------------------------------------------------- @@ -572,7 +675,12 @@ NON_ENTERABLE_ENTRY_CODE(EVACUATED); INFO_TABLE(stg_WEAK_info,stg_WEAK_entry,0,4,WEAK,,EF_,"WEAK","WEAK"); NON_ENTERABLE_ENTRY_CODE(WEAK); -INFO_TABLE_CONSTR(stg_DEAD_WEAK_info,stg_DEAD_WEAK_entry,0,1,0,CONSTR,,EF_,"DEAD_WEAK","DEAD_WEAK"); +// It's important when turning an existing WEAK into a DEAD_WEAK +// (which is what finalizeWeak# does) that we don't lose the link +// field and break the linked list of weak pointers. Hence, we give +// DEAD_WEAK 4 non-pointer fields, the same as WEAK. + +INFO_TABLE_CONSTR(stg_DEAD_WEAK_info,stg_DEAD_WEAK_entry,0,4,0,CONSTR,,EF_,"DEAD_WEAK","DEAD_WEAK"); NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK); /* ----------------------------------------------------------------------------- @@ -582,7 +690,7 @@ NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK); finalizer in a weak pointer object. -------------------------------------------------------------------------- */ -INFO_TABLE_CONSTR(stg_NO_FINALIZER_info,stg_NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0); +INFO_TABLE_CONSTR(stg_NO_FINALIZER_info,stg_NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"NO_FINALIZER","NO_FINALIZER"); NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER); SET_STATIC_HDR(stg_NO_FINALIZER_closure,stg_NO_FINALIZER_info,0/*CC*/,,EI_) @@ -622,7 +730,7 @@ NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR); end of a linked TSO queue. -------------------------------------------------------------------------- */ -INFO_TABLE_CONSTR(stg_END_TSO_QUEUE_info,stg_END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0); +INFO_TABLE_CONSTR(stg_END_TSO_QUEUE_info,stg_END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_TSO_QUEUE","END_TSO_QUEUE"); NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE); SET_STATIC_HDR(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE_info,0/*CC*/,,EI_) @@ -636,26 +744,26 @@ SET_STATIC_HDR(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE_info,0/*CC*/,,EI_) an END_MUT_LIST closure. -------------------------------------------------------------------------- */ -INFO_TABLE_CONSTR(stg_END_MUT_LIST_info,stg_END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0); +INFO_TABLE_CONSTR(stg_END_MUT_LIST_info,stg_END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_MUT_LIST","END_MUT_LIST"); NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST); SET_STATIC_HDR(stg_END_MUT_LIST_closure,stg_END_MUT_LIST_info,0/*CC*/,,EI_) , /*payload*/{} }; -INFO_TABLE(stg_MUT_CONS_info, stg_MUT_CONS_entry, 1, 1, MUT_VAR, , EF_, 0, 0); +INFO_TABLE(stg_MUT_CONS_info, stg_MUT_CONS_entry, 1, 1, MUT_CONS, , EF_, "MUT_CONS", "MUT_CONS"); NON_ENTERABLE_ENTRY_CODE(MUT_CONS); /* ----------------------------------------------------------------------------- Exception lists -------------------------------------------------------------------------- */ -INFO_TABLE_CONSTR(stg_END_EXCEPTION_LIST_info,stg_END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0); +INFO_TABLE_CONSTR(stg_END_EXCEPTION_LIST_info,stg_END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_EXCEPTION_LIST","END_EXCEPTION_LIST"); NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST); SET_STATIC_HDR(stg_END_EXCEPTION_LIST_closure,stg_END_EXCEPTION_LIST_info,0/*CC*/,,EI_) , /*payload*/{} }; -INFO_TABLE(stg_EXCEPTION_CONS_info, stg_EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, 0, 0); +INFO_TABLE(stg_EXCEPTION_CONS_info, stg_EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, "EXCEPTION_CONS", "EXCEPTION_CONS"); NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS); /* ----------------------------------------------------------------------------- @@ -717,7 +825,7 @@ STGFUN(stg_error_entry) \ just enter the top stack word to start the thread. (see deleteThread) * -------------------------------------------------------------------------- */ -INFO_TABLE(stg_dummy_ret_info, stg_dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, 0, 0); +INFO_TABLE(stg_dummy_ret_info, stg_dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, "DUMMY_RET", "DUMMY_RET"); STGFUN(stg_dummy_ret_entry) { W_ ret_addr; @@ -755,7 +863,7 @@ STGFUN(stg_forceIO_ret_entry) } #else INFO_TABLE_SRT_BITMAP(stg_forceIO_ret_info,stg_forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0); -STGFUN(forceIO_ret_entry) +STGFUN(stg_forceIO_ret_entry) { StgClosure *rval; FB_ @@ -768,7 +876,7 @@ STGFUN(forceIO_ret_entry) } #endif -INFO_TABLE(stg_forceIO_info,stg_forceIO_entry,1,0,FUN_STATIC,,EF_,0,0); +INFO_TABLE(stg_forceIO_info,stg_forceIO_entry,1,0,FUN_STATIC,,EF_,"FORCE_IO","FORCE_IO"); FN_(stg_forceIO_entry) { FB_ @@ -806,8 +914,8 @@ static INFO_TBL_CONST StgInfoTable izh_static_info; #define Char_hash_static_info czh_static_info #define Int_hash_static_info izh_static_info #else -#define Char_hash_static_info PrelBase_Czh_static_info -#define Int_hash_static_info PrelBase_Izh_static_info +#define Char_hash_static_info GHCziBase_Czh_static_info +#define Int_hash_static_info GHCziBase_Izh_static_info #endif #define CHARLIKE_HDR(n) \