<div dir="ltr">Added comments: <a href="https://phabricator.haskell.org/D4517">https://phabricator.haskell.org/D4517</a><br></div><div class="gmail_extra"><br><div class="gmail_quote">On 20 March 2018 at 14:58, Simon Marlow <span dir="ltr"><<a href="mailto:marlowsd@gmail.com" target="_blank">marlowsd@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Omer,<br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 20 March 2018 at 13:05, Ömer Sinan Ağacan <span dir="ltr"><<a href="mailto:omeragacan@gmail.com" target="_blank">omeragacan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I've been looking at BLACKHOLE closures and how the indirectee field is used<br>
and I have a few questions:<br>
<br>
Looking at evacuate for BLACKHOLE closures:<br>
<br>
    case BLACKHOLE:<br>
    {<br>
        StgClosure *r;<br>
        const StgInfoTable *i;<br>
        r = ((StgInd*)q)->indirectee;<br>
        if (GET_CLOSURE_TAG(r) == 0) {<br>
            i = r-><a href="http://header.info" rel="noreferrer" target="_blank">header.info</a>;<br>
            if (IS_FORWARDING_PTR(i)) {<br>
                r = (StgClosure *)UN_FORWARDING_PTR(i);<br>
                i = r-><a href="http://header.info" rel="noreferrer" target="_blank">header.info</a>;<br>
            }<br>
            if (i == &stg_TSO_info<br>
                || i == &stg_WHITEHOLE_info<br>
                || i == &stg_BLOCKING_QUEUE_CLEAN_info<br>
                || i == &stg_BLOCKING_QUEUE_DIRTY_info<wbr>) {<br>
                copy(p,info,q,sizeofW(StgInd),<wbr>gen_no);<br>
                return;<br>
            }<br>
            ASSERT(i != &stg_IND_info);<br>
        }<br>
        q = r;<br>
        *p = r;<br>
        goto loop;<br>
    }<br>
<br>
It seems like indirectee can be a TSO, WHITEHOLE, BLOCKING_QUEUE_CLEAN,<br>
BLOCKING_QUEUE_DIRTY, and it can't be IND. I'm wondering what does it mean for<br>
a BLACKHOLE to point to a<br>
<br>
- TSO<br>
- WHITEHOLE<br>
- BLOCKING_QUEUE_CLEAN<br>
- BLOCKING_QUEUE_DIRTY<br></blockquote><div><br></div></div></div><div>That sounds right to me. <br> </div><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Is this documented somewhere or otherwise could someone give a few pointers on<br>
where to look in the code?<br></blockquote><div><br></div></span><div>Unfortunately I don't think we have good documentation for this, but you should look at the comments around messageBlackHole in Messages.c.<br></div><div><div class="h5"><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Secondly, I also looked at the BLACKHOLE entry code, and it seems like it has a<br>
different assumption about what can indirectee field point to:<br>
<br>
    INFO_TABLE(stg_BLACKHOLE,1,0,B<wbr>LACKHOLE,"BLACKHOLE","BLACKHOL<wbr>E")<br>
        (P_ node)<br>
    {<br>
        W_ r, info, owner, bd;<br>
        P_ p, bq, msg;<br>
<br>
        TICK_ENT_DYN_IND(); /* tick */<br>
<br>
    retry:<br>
        p = StgInd_indirectee(node);<br>
        if (GETTAG(p) != 0) {<br>
            return (p);<br>
        }<br>
<br>
        info = StgHeader_info(p);<br>
        if (info == stg_IND_info) {<br>
            // This could happen, if e.g. we got a BLOCKING_QUEUE that has<br>
            // just been replaced with an IND by another thread in<br>
            // wakeBlockingQueue().<br>
            goto retry;<br>
        }<br>
<br>
        if (info == stg_TSO_info ||<br>
            info == stg_BLOCKING_QUEUE_CLEAN_info ||<br>
            info == stg_BLOCKING_QUEUE_DIRTY_info)<br>
        {<br>
            ("ptr" msg) = ccall allocate(MyCapability() "ptr",<br>
                                         BYTES_TO_WDS(SIZEOF_MessageBl<wbr>ackHole));<br>
<br>
            SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM);<br>
            MessageBlackHole_tso(msg) = CurrentTSO;<br>
            MessageBlackHole_bh(msg) = node;<br>
<br>
            (r) = ccall messageBlackHole(MyCapability(<wbr>) "ptr", msg "ptr");<br>
<br>
            if (r == 0) {<br>
                goto retry;<br>
            } else {<br>
                StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16;<br>
                StgTSO_block_info(CurrentTSO) = msg;<br>
                jump stg_block_blackhole(node);<br>
            }<br>
        }<br>
        else<br>
        {<br>
            ENTER(p);<br>
        }<br>
    }<br>
<br>
The difference is, when the tag of indirectee is 0, evacuate assumes that<br>
indirectee can't point to an IND, but BLACKHOLE entry code thinks it's possible<br>
and there's even a comment about why. (I don't understand the comment yet) I'm<br>
wondering if this code is correct, and why. Again any pointers would be<br>
appreciated.<br></blockquote><br></div></div></div><div class="gmail_quote">Taking a quick look at the code, my guess is that:<br></div><div class="gmail_quote">- a BLOCKING_QUEUE gets overwritten by an IND in wakeBlockingQueue()<br></div><div class="gmail_quote">- but when this happens, the indirectee of the BLACKHOLE will also be overwritten to point to the value<br><br></div><div class="gmail_quote">At runtime a thread might see an intermediate state because these mutations are happening in another thread, so we might follow the indirectee and see the IND. But this state can't be observed by the GC, because all mutator threads have stopped at a safe point.<br></div><br><div class="gmail_quote"><div>Cheers<span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888"><div>Simon<br><br></div></font></span><span class=""><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Thanks,<br>
<br>
Ömer<br>
______________________________<wbr>_________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/ghc-devs</a><br>
</blockquote></span></div><br></div></div>
</blockquote></div><br></div>