Rodrigo Mesquita pushed to branch wip/romes/top-level-bcos-tag at Glasgow Haskell Compiler / GHC
Commits:
-
0784224f
by Rodrigo Mesquita at 2025-05-21T18:56:32+01:00
3 changed files:
Changes:
... | ... | @@ -173,11 +173,80 @@ newtype AddrPtr = AddrPtr (RemotePtr ()) |
173 | 173 | --------------------------------------------------------------------------------
|
174 | 174 | |
175 | 175 | Note [Case continuation BCOs]
|
176 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
177 | - |
|
176 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
177 | + |
|
178 | +Consider the following stack with a BCO stack frame at the top:
|
|
179 | + |
|
180 | + (an StgBCO)
|
|
181 | + | ... | +---> +---------[1]--+
|
|
182 | + +------------------+ | | info_tbl_ptr | ------+
|
|
183 | + | OTHER FRAME | | +--------------+ |
|
|
184 | + +------------------+ | | StgArrBytes* | <--- the byte code
|
|
185 | + | ... | | +--------------+ |
|
|
186 | + +------------------+ | | ... | |
|
|
187 | + | fvs1 | | |
|
|
188 | + +------------------+ | |
|
|
189 | + | ... | | (StgInfoTable) |
|
|
190 | + +------------------+ | +----------+ <---+
|
|
191 | + | args1 | | | ... |
|
|
192 | + +------------------+ | +----------+
|
|
193 | + | some StgBCO* | -----+ | type=BCO |
|
|
194 | + +------------------+ +----------+
|
|
195 | + Sp | stg_apply_interp | -----+ | ... |
|
|
196 | + +------------------+ |
|
|
197 | + |
|
|
198 | + | (StgInfoTable)
|
|
199 | + +----> +--------------+
|
|
200 | + | ... |
|
|
201 | + +--------------+
|
|
202 | + | type=RET_BCO |
|
|
203 | + +--------------+
|
|
204 | + | ... |
|
|
205 | + |
|
206 | + |
|
207 | +The code for a BCO heap object makes use of arguments and free variables which
|
|
208 | +can typically be found within the BCO stack frame. In the code, these variables
|
|
209 | +are referenced via a statically known stack offset (tracked using `BCEnv` in
|
|
210 | +`StgToByteCode`).
|
|
211 | + |
|
212 | +However, in /case continuation/ BCOs, the code may additionally refer to free
|
|
213 | +variables that are outside of the BCO's stack frame. Instead, some free
|
|
214 | +variables of a case continuation BCO may only be found in the stack frame of a
|
|
215 | +parent BCO:
|
|
216 | + |
|
217 | + f x y = case x of ... -> ... y ...
|
|
218 | + |
|
219 | + ==>
|
|
220 | + |
|
221 | + <ParentBCOFrame>
|
|
222 | + ...
|
|
223 | + <CaseContinuationBCOFrame>
|
|
224 | + |
|
225 | +Similarly, references to these non-local/out-of-frame variables are done in
|
|
226 | +terms of stack offsets, but they rely on the position of another frame to be fixed.
|
|
227 | +(See Note [PUSH_L underflow] for more information about references to previous frames and nested BCOs)
|
|
228 | + |
|
229 | +TODO
|
|
230 | + |
|
231 | +to arguments or free variables in
|
|
232 | +the stack using a stack pointer offset .
|
|
233 | + |
|
234 | +A BCO closure is typically headed by the stg_BCO info table pointer.
|
|
235 | +...
|
|
236 | + |
|
237 | +A BCO can be constructed using the stg_BCO info table, OR using the stg
|
|
178 | 238 | Does the BCO code depend on stack-pointer-relative offsets?
|
179 | 239 | ... why
|
180 | 240 | ... example
|
241 | + |
|
242 | +...
|
|
243 | + |
|
244 | + <parentBCOFrame>
|
|
245 | + ...
|
|
246 | + <inserted>
|
|
247 | + ...
|
|
248 | + <childBCOFrame>
|
|
249 | + |
|
181 | 250 | -}
|
182 | 251 | |
183 | 252 | data UnlinkedBCO
|
... | ... | @@ -203,14 +203,14 @@ PUSH_L instruction. |
203 | 203 | |
204 | 204 | |---------|
|
205 | 205 | | BCO_1 | -<-┐
|
206 | -|---------|
|
|
206 | +|---------| |
|
|
207 | 207 | ......... |
|
208 | 208 | |---------| | PUSH_L <n>
|
209 | 209 | | BCO_N | ->-┘
|
210 | 210 | |---------|
|
211 | 211 | |
212 | 212 | Here BCO_N is syntactically nested within the code for BCO_1 and will result
|
213 | -in code that references the prior stack frame of BCO_1 for some of it's local
|
|
213 | +in code that references the prior stack frame of BCO_1 for some of its local
|
|
214 | 214 | variables. If a stack overflow happens between the creation of the stack frame
|
215 | 215 | for BCO_1 and BCO_N the RTS might move BCO_N to a new stack chunk while leaving
|
216 | 216 | BCO_1 in place, invalidating a simple offset based reference to the outer stack
|
... | ... | @@ -524,14 +524,35 @@ interpretBCO (Capability* cap) |
524 | 524 | //
|
525 | 525 | // We have a BCO application to perform. Stack looks like:
|
526 | 526 | //
|
527 | - // | .... |
|
|
528 | - // +---------------+
|
|
529 | - // | arg1 |
|
|
530 | - // +---------------+
|
|
531 | - // | BCO |
|
|
532 | - // +---------------+
|
|
533 | - // Sp | RET_BCO |
|
|
534 | - // +---------------+
|
|
527 | + //
|
|
528 | + // (an StgBCO)
|
|
529 | + // +---> +---------[1]--+
|
|
530 | + // | | stg_BCO_info | ------+
|
|
531 | + // | +--------------+ |
|
|
532 | + // | | StgArrBytes* | <--- the byte code
|
|
533 | + // | ... | | +--------------+ |
|
|
534 | + // +------------------+ | | ... | |
|
|
535 | + // | fvs1 | | |
|
|
536 | + // +------------------+ | |
|
|
537 | + // | ... | | (StgInfoTable) |
|
|
538 | + // +------------------+ | +----------+ <---+
|
|
539 | + // | args1 | | | ... |
|
|
540 | + // +------------------+ | +----------+
|
|
541 | + // | some StgBCO* | -----+ | type=BCO |
|
|
542 | + // +------------------+ +----------+
|
|
543 | + // Sp | stg_apply_interp | -----+ | ... |
|
|
544 | + // +------------------+ |
|
|
545 | + // |
|
|
546 | + // | (StgInfoTable)
|
|
547 | + // +----> +--------------+
|
|
548 | + // | ... |
|
|
549 | + // +--------------+
|
|
550 | + // | type=RET_BCO |
|
|
551 | + // +--------------+
|
|
552 | + // | ... |
|
|
553 | + //
|
|
554 | + // [1] An StgBCO's info table pointer may also be stg_CASE_CONT_BCO_info.
|
|
555 | + // See Note [Case continuation BCOs].
|
|
535 | 556 | //
|
536 | 557 | else if (SpW(0) == (W_)&stg_apply_interp_info) {
|
537 | 558 | obj = UNTAG_CLOSURE((StgClosure *)ReadSpW(1));
|
... | ... | @@ -469,6 +469,7 @@ INFO_TABLE_RET( stg_dead_thread, RET_SMALL, |
469 | 469 | non-local variables in its code (using a stack offset) and those that do not.
|
470 | 470 | Only case-continuation BCOs should use non-local variables.
|
471 | 471 | Otherwise, `stg_BCO` and `stg_CASE_CONT_BCO` behave the same.
|
472 | + See Note [Case continuation BCOs].
|
|
472 | 473 | ------------------------------------------------------------------------- */
|
473 | 474 | |
474 | 475 | INFO_TABLE_FUN( stg_BCO, 3, 0, BCO, "BCO", "BCO", 0, ARG_BCO )
|