Sebastian Graf pushed to branch wip/sg/enter-taggable-invariant at Glasgow Haskell Compiler / GHC
Commits:
-
5ba72999
by Sebastian Graf at 2026-07-31T18:25:31+02:00
-
3b6d6c34
by Sebastian Graf at 2026-07-31T18:25:31+02:00
-
3f7072d7
by Sebastian Graf at 2026-07-31T18:28:22+02:00
4 changed files:
- libraries/ghc-internal/cbits/StackCloningDecoding.cmm
- rts/CloneStack.c
- rts/sm/Evac.c
- rts/sm/NonMovingShortcut.c
Changes:
| ... | ... | @@ -9,7 +9,10 @@ stg_cloneMyStackzh () { |
| 9 | 9 | |
| 10 | 10 | ("ptr" clonedStack) = ccall cloneStack(MyCapability() "ptr", stgStack "ptr");
|
| 11 | 11 | |
| 12 | - return (clonedStack);
|
|
| 12 | + // The StackSnapshot# result carries the boxed-unlifted-primitive pointer
|
|
| 13 | + // tag; see Note [Pointer tagging of unlifted boxed primitives] in
|
|
| 14 | + // GHC.StgToCmm.Prim.
|
|
| 15 | + return (clonedStack + 1);
|
|
| 13 | 16 | }
|
| 14 | 17 | |
| 15 | 18 | stg_sendCloneStackMessagezh (gcptr threadId, gcptr mVarStablePtr) {
|
| ... | ... | @@ -108,7 +108,10 @@ void handleCloneStackMessage(Capability *cap, MessageCloneStack *msg){ |
| 108 | 108 | // Lift StackSnapshot# to StackSnapshot by applying it's constructor.
|
| 109 | 109 | // This is necessary because performTryPutMVar() puts the closure onto the
|
| 110 | 110 | // stack for evaluation and stacks can not be evaluated (entered).
|
| 111 | - HaskellObj result = rts_apply(cap, StackSnapshot_constructor_closure, (HaskellObj) newStackClosure);
|
|
| 111 | + // The constructor argument is a StackSnapshot#, which carries the
|
|
| 112 | + // boxed-unlifted-primitive pointer tag.
|
|
| 113 | + HaskellObj result = rts_apply(cap, StackSnapshot_constructor_closure,
|
|
| 114 | + TAG_CLOSURE(1, (StgClosure *) newStackClosure));
|
|
| 112 | 115 | |
| 113 | 116 | bool putMVarWasSuccessful = performTryPutMVar(cap, msg->result, result);
|
| 114 | 117 |
| ... | ... | @@ -1049,7 +1049,8 @@ loop: |
| 1049 | 1049 | mine = copyPart(p,(StgClosure *)stack, stack_sizeW(stack),
|
| 1050 | 1050 | sizeofW(StgStack), gen_no, tag);
|
| 1051 | 1051 | if (mine) {
|
| 1052 | - new_stack = (StgStack *)*p;
|
|
| 1052 | + // copyPart stores the forwarded reference with its tag.
|
|
| 1053 | + new_stack = (StgStack *)UNTAG_CLOSURE(*p);
|
|
| 1053 | 1054 | move_STACK(stack, new_stack);
|
| 1054 | 1055 | for (r = stack->sp, s = new_stack->sp;
|
| 1055 | 1056 | r < stack->stack + stack->stack_size;) {
|
| ... | ... | @@ -222,14 +222,23 @@ selectee_changed: |
| 222 | 222 | chain = p;
|
| 223 | 223 | p = val;
|
| 224 | 224 | goto selector_changed;
|
| 225 | - default:
|
|
| 225 | + default: {
|
|
| 226 | 226 | // Found a value, add the current selector to the chain and
|
| 227 | 227 | // update it.
|
| 228 | + // Re-establish the pointer tag for an evaluated constructor,
|
|
| 229 | + // as in eval_thunk_selector (rts/sm/Evac.c): the indirectees
|
|
| 230 | + // and the origin field installed by update_selector_chain
|
|
| 231 | + // carry the constructor tag.
|
|
| 232 | + const StgInfoTable *val_info = get_itbl(val);
|
|
| 233 | + if (val_info->type >= CONSTR && val_info->type <= CONSTR_NOCAF) {
|
|
| 234 | + val = TAG_CLOSURE(stg_min(TAG_MASK, 1 + val_info->srt), val);
|
|
| 235 | + }
|
|
| 228 | 236 | p->payload[0] = chain;
|
| 229 | 237 | chain = p;
|
| 230 | 238 | update_selector_chain(chain, origin, p0, val);
|
| 231 | 239 | return val;
|
| 232 | 240 | }
|
| 241 | + }
|
|
| 233 | 242 | }
|
| 234 | 243 | |
| 235 | 244 | case IND:
|