- p->mut_link = generations[bd->gen_no].mut_once_list;
- generations[bd->gen_no].mut_once_list = p;
- }
-}
-
-// @LDV profiling
-// We zero out the slop when PROFILING is on.
-// #ifndef DEBUG
-#if !defined(DEBUG) && !defined(PROFILING)
-#define updateWithIndirection(info, ind_info, p1, p2, and_then) \
- { \
- bdescr *bd; \
- \
- bd = Bdescr((P_)p1); \
- if (bd->gen_no == 0) { \
- ((StgInd *)p1)->indirectee = p2; \
- SET_INFO(p1,ind_info); \
- TICK_UPD_NEW_IND(); \
- and_then; \
- } else { \
- ((StgIndOldGen *)p1)->indirectee = p2; \
- if (info != &stg_BLACKHOLE_BQ_info) { \
- ACQUIRE_SM_LOCK; \
- ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
- generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1; \
- RELEASE_SM_LOCK; \
- } \
- SET_INFO(p1,&stg_IND_OLDGEN_info); \
- TICK_UPD_OLD_IND(); \
- and_then; \
- } \
- }
-#elif defined(PROFILING)
-// @LDV profiling
-// We call LDV_recordDead_FILL_SLOP_DYNAMIC(p1) regardless of the generation in
-// which p1 resides.
-//
-// Note:
-// After all, we do *NOT* need to call LDV_recordCreate() for both IND and
-// IND_OLDGEN closures because they are inherently used. But, it corrupts
-// the invariants that every closure keeps its creation time in the profiling
-// field. So, we call LDV_recordCreate().
-
-#define updateWithIndirection(info, ind_info, p1, p2, and_then) \
- { \
- bdescr *bd; \
- \
- LDV_recordDead_FILL_SLOP_DYNAMIC((p1)); \
- bd = Bdescr((P_)p1); \
- if (bd->gen_no == 0) { \
- ((StgInd *)p1)->indirectee = p2; \
- SET_INFO(p1,ind_info); \
- LDV_recordCreate((p1)); \
- TICK_UPD_NEW_IND(); \
- and_then; \
- } else { \
- ((StgIndOldGen *)p1)->indirectee = p2; \
- if (info != &stg_BLACKHOLE_BQ_info) { \
- ACQUIRE_SM_LOCK; \
- ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
- generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1; \
- RELEASE_SM_LOCK; \
- } \
- SET_INFO(p1,&stg_IND_OLDGEN_info); \
- LDV_recordCreate((p1)); \
- and_then; \
- } \
- }
-
-#else
-
-/* In the DEBUG case, we also zero out the slop of the old closure,
- * so that the sanity checker can tell where the next closure is.
- *
- * Two important invariants: we should never try to update a closure
- * to point to itself, and the closure being updated should not
- * already have been updated (the mutable list will get messed up
- * otherwise).
- */
-#define updateWithIndirection(info, ind_info, p1, p2, and_then) \
- { \
- bdescr *bd; \
- \
- ASSERT( p1 != p2 && !closure_IND(p1) ); \
- bd = Bdescr((P_)p1); \
- if (bd->gen_no == 0) { \
- ((StgInd *)p1)->indirectee = p2; \
- SET_INFO(p1,ind_info); \
- TICK_UPD_NEW_IND(); \
- and_then; \
- } else { \
- if (info != &stg_BLACKHOLE_BQ_info) { \
- { \
- StgInfoTable *inf = get_itbl(p1); \
- nat np = inf->layout.payload.ptrs, \
- nw = inf->layout.payload.nptrs, i; \
- if (inf->type != THUNK_SELECTOR) { \
- for (i = 0; i < np + nw; i++) { \
- ((StgClosure *)p1)->payload[i] = 0; \
- } \
- } \
- } \
- ACQUIRE_SM_LOCK; \
- ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list; \
- generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1; \
- RELEASE_SM_LOCK; \
- } \
- ((StgIndOldGen *)p1)->indirectee = p2; \
- SET_INFO(p1,&stg_IND_OLDGEN_info); \
- TICK_UPD_OLD_IND(); \
- and_then; \
- } \
- }
-#endif
-
-/* Static objects all live in the oldest generation
- */
-#define updateWithStaticIndirection(info, p1, p2) \
- { \
- ASSERT( p1 != p2 && !closure_IND(p1) ); \
- ASSERT( ((StgMutClosure*)p1)->mut_link == NULL ); \
- \
- ACQUIRE_SM_LOCK; \
- ((StgMutClosure *)p1)->mut_link = oldest_gen->mut_once_list; \
- oldest_gen->mut_once_list = (StgMutClosure *)p1; \
- RELEASE_SM_LOCK; \
- \
- ((StgInd *)p1)->indirectee = p2; \
- SET_INFO((StgInd *)p1, &stg_IND_STATIC_info); \
- TICK_UPD_STATIC_IND(); \
- }
-
-#if defined(TICKY_TICKY) || defined(PROFILING)
-INLINE_HEADER void
-updateWithPermIndirection(const StgInfoTable *info, StgClosure *p1, StgClosure *p2)
-{
- bdescr *bd;
-
- ASSERT( p1 != p2 && !closure_IND(p1) );
-
-#ifdef PROFILING
- // @LDV profiling
- // Destroy the old closure.
- // Nb: LDV_* stuff cannot mix with ticky-ticky
- LDV_recordDead_FILL_SLOP_DYNAMIC(p1);
-#endif
- bd = Bdescr((P_)p1);
- if (bd->gen_no == 0) {
- ((StgInd *)p1)->indirectee = p2;
- SET_INFO(p1,&stg_IND_PERM_info);
-#ifdef PROFILING
- // @LDV profiling
- // We have just created a new closure.
- LDV_recordCreate(p1);
-#endif
- TICK_UPD_NEW_PERM_IND(p1);
- } else {
- ((StgIndOldGen *)p1)->indirectee = p2;
- if (info != &stg_BLACKHOLE_BQ_info) {
- ACQUIRE_SM_LOCK;
- ((StgIndOldGen *)p1)->mut_link = generations[bd->gen_no].mut_once_list;
- generations[bd->gen_no].mut_once_list = (StgMutClosure *)p1;
- RELEASE_SM_LOCK;
- }
- SET_INFO(p1,&stg_IND_OLDGEN_PERM_info);
-#ifdef PROFILING
- // @LDV profiling
- // We have just created a new closure.
- LDV_recordCreate(p1);
-#endif
- TICK_UPD_OLD_PERM_IND();