Ben Gamari pushed to branch wip/decode-orig-update-frames at Glasgow Haskell Compiler / GHC
Commits:
-
d0789dfe
by Ben Gamari at 2026-06-21T10:19:10-04:00
3 changed files:
- libraries/ghc-internal/cbits/Stack.cmm
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
Changes:
| ... | ... | @@ -3,6 +3,10 @@ |
| 3 | 3 | |
| 4 | 4 | #include "Cmm.h"
|
| 5 | 5 | |
| 6 | +#if !defined(UnregisterisedCompiler)
|
|
| 7 | +import CLOSURE stg_orig_thunk_info_frame_info;
|
|
| 8 | +#endif
|
|
| 9 | + |
|
| 6 | 10 | // StgStack_marking was not available in the Stage0 compiler at the time of
|
| 7 | 11 | // writing. Because, it has been added to derivedConstants when Stack.cmm was
|
| 8 | 12 | // developed.
|
| ... | ... | @@ -168,6 +172,18 @@ getStackInfoTableAddrzh(P_ stack) { |
| 168 | 172 | return (info);
|
| 169 | 173 | }
|
| 170 | 174 | |
| 175 | +// (StgInfoTable*) getOrigThunkInfoPtrzh(StgStack* stack, StgWord offsetWords)
|
|
| 176 | +getOrigThunkInfoPtrzh(P_ stack, W_ offsetWords) {
|
|
| 177 | + P_ p;
|
|
| 178 | + p = StgStack_sp(stack) + WDS(offsetWords);
|
|
| 179 | + ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
|
|
| 180 | + if (%INFO_PTR(UNTAG(p)) == stg_orig_thunk_info_frame_info) {
|
|
| 181 | + return (StgOrigThunkInfoFrame_info_ptr(UNTAG(p)));
|
|
| 182 | + } else {
|
|
| 183 | + return (NULL);
|
|
| 184 | + }
|
|
| 185 | +}
|
|
| 186 | + |
|
| 171 | 187 | // (StgClosure*) getStackClosurezh(StgStack* stack, StgWord offsetWords)
|
| 172 | 188 | getStackClosurezh(P_ stack, W_ offsetWords) {
|
| 173 | 189 | P_ ptr;
|
| ... | ... | @@ -568,6 +568,17 @@ data GenStackFrame b = |
| 568 | 568 | , stack_payload :: ![GenStackField b]
|
| 569 | 569 | }
|
| 570 | 570 | |
| 571 | + -- | An @stg_orig_thunk_info_frame@ pushed by @-forig-thunk-info@. It records
|
|
| 572 | + -- the original info table of the thunk being updated (in 'orig_info_tbl'),
|
|
| 573 | + -- which is otherwise lost when the thunk is blackholed.
|
|
| 574 | + -- See @Note [Original thunk info table frames]@ in "GHC.StgToCmm.Bind".
|
|
| 575 | + | OrigThunkInfo
|
|
| 576 | + { info_tbl :: !StgInfoTable
|
|
| 577 | + -- ^ the frame's own (RTS) info table
|
|
| 578 | + , orig_info_tbl :: !(Ptr StgInfoTable)
|
|
| 579 | + -- ^ the original info table of the thunk being updated
|
|
| 580 | + }
|
|
| 581 | + |
|
| 571 | 582 | | RetFun
|
| 572 | 583 | { info_tbl :: !StgInfoTable
|
| 573 | 584 | , retFunSize :: !Word
|
| ... | ... | @@ -192,6 +192,16 @@ foreign import prim "getInfoTableAddrszh" getInfoTableAddrs# :: StackSnapshot# - |
| 192 | 192 | |
| 193 | 193 | foreign import prim "getStackInfoTableAddrzh" getStackInfoTableAddr# :: StackSnapshot# -> Addr#
|
| 194 | 194 | |
| 195 | +foreign import prim "getOrigThunkInfoPtrzh" getOrigThunkInfoPtr# :: StackSnapshot# -> Word# -> Addr#
|
|
| 196 | + |
|
| 197 | +-- | @'Just' itbl@ if the frame at the given offset is an
|
|
| 198 | +-- @stg_orig_thunk_info_frame@ (where @itbl@ is the recorded original thunk
|
|
| 199 | +-- info table), otherwise 'Nothing'.
|
|
| 200 | +origThunkInfoFrame :: StackSnapshot# -> WordOffset -> Maybe (Ptr StgInfoTable)
|
|
| 201 | +origThunkInfoFrame stackSnapshot# index =
|
|
| 202 | + let p = Ptr (getOrigThunkInfoPtr# stackSnapshot# (wordOffsetToWord# index))
|
|
| 203 | + in if p == nullPtr then Nothing else Just p
|
|
| 204 | + |
|
| 195 | 205 | -- | Get the 'StgInfoTable' of the stack frame.
|
| 196 | 206 | -- Additionally, provides 'InfoProv' for the 'StgInfoTable' if there is any.
|
| 197 | 207 | getInfoTableOnStack :: StackSnapshot# -> WordOffset -> IO (StgInfoTable, Maybe InfoProv)
|
| ... | ... | @@ -380,6 +390,15 @@ unpackStackFrameTo (StackSnapshot stackSnapshot#, index) unpackUnderflowFrame fi |
| 380 | 390 | bco = bco',
|
| 381 | 391 | bcoArgs = bcoArgs'
|
| 382 | 392 | }
|
| 393 | + RET_SMALL
|
|
| 394 | + | Just orig_itbl <- origThunkInfoFrame stackSnapshot# index -> do
|
|
| 395 | + orig_info_prov <- lookupIPE (castPtr orig_itbl)
|
|
| 396 | + finaliseStackFrame
|
|
| 397 | + OrigThunkInfo
|
|
| 398 | + { info_tbl = info,
|
|
| 399 | + orig_info_tbl = orig_itbl
|
|
| 400 | + }
|
|
| 401 | + orig_info_prov
|
|
| 383 | 402 | RET_SMALL ->
|
| 384 | 403 | let payload' = decodeSmallBitmap getSmallBitmap# stackSnapshot# index offsetStgClosurePayload
|
| 385 | 404 | in
|