
Hi, I've been looking at BLACKHOLE closures and how the indirectee field is used and I have a few questions: Looking at evacuate for BLACKHOLE closures: case BLACKHOLE: { StgClosure *r; const StgInfoTable *i; r = ((StgInd*)q)->indirectee; if (GET_CLOSURE_TAG(r) == 0) { i = r->header.info; if (IS_FORWARDING_PTR(i)) { r = (StgClosure *)UN_FORWARDING_PTR(i); i = r->header.info; } if (i == &stg_TSO_info || i == &stg_WHITEHOLE_info || i == &stg_BLOCKING_QUEUE_CLEAN_info || i == &stg_BLOCKING_QUEUE_DIRTY_info) { copy(p,info,q,sizeofW(StgInd),gen_no); return; } ASSERT(i != &stg_IND_info); } q = r; *p = r; goto loop; } It seems like indirectee can be a TSO, WHITEHOLE, BLOCKING_QUEUE_CLEAN, BLOCKING_QUEUE_DIRTY, and it can't be IND. I'm wondering what does it mean for a BLACKHOLE to point to a - TSO - WHITEHOLE - BLOCKING_QUEUE_CLEAN - BLOCKING_QUEUE_DIRTY Is this documented somewhere or otherwise could someone give a few pointers on where to look in the code? Secondly, I also looked at the BLACKHOLE entry code, and it seems like it has a different assumption about what can indirectee field point to: INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE") (P_ node) { W_ r, info, owner, bd; P_ p, bq, msg; TICK_ENT_DYN_IND(); /* tick */ retry: p = StgInd_indirectee(node); if (GETTAG(p) != 0) { return (p); } info = StgHeader_info(p); if (info == stg_IND_info) { // This could happen, if e.g. we got a BLOCKING_QUEUE that has // just been replaced with an IND by another thread in // wakeBlockingQueue(). goto retry; } if (info == stg_TSO_info || info == stg_BLOCKING_QUEUE_CLEAN_info || info == stg_BLOCKING_QUEUE_DIRTY_info) { ("ptr" msg) = ccall allocate(MyCapability() "ptr", BYTES_TO_WDS(SIZEOF_MessageBlackHole)); SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM); MessageBlackHole_tso(msg) = CurrentTSO; MessageBlackHole_bh(msg) = node; (r) = ccall messageBlackHole(MyCapability() "ptr", msg "ptr"); if (r == 0) { goto retry; } else { StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16; StgTSO_block_info(CurrentTSO) = msg; jump stg_block_blackhole(node); } } else { ENTER(p); } } The difference is, when the tag of indirectee is 0, evacuate assumes that indirectee can't point to an IND, but BLACKHOLE entry code thinks it's possible and there's even a comment about why. (I don't understand the comment yet) I'm wondering if this code is correct, and why. Again any pointers would be appreciated. Thanks, Ömer