<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">#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 class="gmail-sourceCode" id="gmail-cb1" style="margin-left:40px"><pre class="gmail-sourceCode gmail-c"><code class="gmail-sourceCode gmail-c"><span id="gmail-cb1-1"><a aria-hidden="true"></a><span class="gmail-cf">if</span> (frame->header.info->i.type == PROMPT_FRAME) { ... }</span></code></pre></div>
<p>we write</p>
<div class="gmail-sourceCode" id="gmail-cb2" style="margin-left:40px"><pre class="gmail-sourceCode gmail-c"><code class="gmail-sourceCode gmail-c"><span id="gmail-cb2-1"><a aria-hidden="true"></a><span class="gmail-cf">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>