<div dir="ltr"><div class="gmail_default" style="font-family:tahoma,sans-serif">Thanks for a clear writeup, Alexis.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">My instinct is to do it all with closure types, not pointer comparison.</div><div class="gmail_default" style="font-family:tahoma,sans-serif"></div><div class="gmail_default" style="font-family:tahoma,sans-serif">
<li><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p>Con: Adding more closure types unnecessarily pollutes code that branches on closure types, like the garbage collector.</p></blockquote><div>
</div></li><li><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p>Con: Adding more closure types unnecessarily pollutes code that branches on closure types, like the garbage collector.</p></blockquote></li></div><li><div>I don't get this. Different stack frames might have different layouts (e.g a catch frame has a fixed size with with exactly two (or whatever) pointers, etc). This isn't pollution. Just as every heap closure has a closure type that describes its layout, so does every stack frame.</div></li><div><br></div><div><div style="font-family:tahoma,sans-serif" class="gmail_default">Perhaps you mean that in fact all stack frames share a single layout, with a bitmap to describe it? That seems sub-optimal for these special frames where we statically know the entire shape!</div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default">Perhaps you mean that many stack frames share a common layout, so that the case analysis on closure type might have many cases all pointing to the same GC code. But if so, isn't that true for heap closures too? If we are concerned about that, we could have two "type" fields in the info table, one exclusively concerned with layout, so that the GC could just branch on that and only have a few cases to consider, and one with a finer granularity.</div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default">In short, why are the design considerations for stack frames different to heap objects? I think of a stack frame simply as a heap object that happens to be allocated on the stack</div><div style="font-family:tahoma,sans-serif" class="gmail_default"><br></div><div style="font-family:tahoma,sans-serif" class="gmail_default">Simon<br></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 26 Jun 2023 at 21:21, Alexis King <<a href="mailto:lexi.lambda@gmail.com">lexi.lambda@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><p>Hello all,</p>
<p>I am tinkering with the RTS again while trying to fix <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/23513" target="_blank">#23513</a>,
and every time I touch the exceptions/continuations code, I find myself
waffling about whether to introduce more closure types. I’d like to get
a second opinion so I can stop changing my mind!</p>
<p>Currently, we have distinct closure types for certain special stack frames, like <code>CATCH_FRAME</code>, <code>ATOMICALLY_FRAME</code>, and <code>UNDERFLOW_FRAME</code>. However, there are other special stack frames that <em>don’t</em> get their own closure types: there is no <code>MASK_ASYNC_EXCEPTIONS_FRAME</code> or <code>PROMPT_FRAME</code>.
Instead, when code needs to recognize these frames on the stack, it
just looks for a known infotable pointer. That is, instead of writing</p>
<div id="m_-1320621509735610816gmail-cb1" style="margin-left:40px"><pre><code><span id="m_-1320621509735610816gmail-cb1-1"><a aria-hidden="true"></a><span>if</span> (frame->header.info->i.type == PROMPT_FRAME) { ... }</span></code></pre></div>
<p>we write</p>
<div id="m_-1320621509735610816gmail-cb2" style="margin-left:40px"><pre><code><span id="m_-1320621509735610816gmail-cb2-1"><a aria-hidden="true"></a><span>if</span> (*frame == &stg_prompt_frame_info) { ... }</span></code></pre></div>
<p>which works out because there’s only one info table that’s used for all prompt frames.</p>
<p>There are a handful of stack frames that are recognized in this way
by some part of the RTS, but the criteria used to determine which frames
get their own types and which don’t is not particularly clear. For some
frames, like <code>UPDATE_FRAME</code>, the closure type is necessary because it is shared between several infotables. But other types, like <code>CATCH_FRAME</code> and <code>UNDERFLOW_FRAME</code>, are only ever used by precisely one infotable.</p>
<p>I think one can make the following arguments for/against using separate closure types for these stack frames:</p>
<ul><li><p>Pro: It’s helpful to have separate types for particularly special frames like <code>UNDERFLOW_FRAME</code> because it makes it easier to remember which special cases to handle when walking the stack.</p></li><li><p>Pro: Branching on stack frame closure types using <code>switch</code> is easier to read than comparing infotable pointers.</p></li><li><p>Con: Adding more closure types unnecessarily pollutes code that branches on closure types, like the garbage collector.</p></li><li><p>Con: Using special closure types for these frames might make it
seem like they have some special layout when in fact they are just
ordinary stack frames.</p></li></ul>
<p>Does anyone have any opinions about this? I’m personally okay with
the status quo, but the inconsistency makes me constantly second-guess
whether someone else might feel strongly that I ought to be doing things
the other way!</p>
<p>Thanks,<br>
Alexis</p></div>
_______________________________________________<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-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div>