[Git][ghc/ghc][wip/romes/step-out-5] Complete implementation of step-out RTS level

Rodrigo Mesquita pushed to branch wip/romes/step-out-5 at Glasgow Haskell Compiler / GHC Commits: 9efbbddb by Rodrigo Mesquita at 2025-06-16T11:15:11+01:00 Complete implementation of step-out RTS level - - - - - 1 changed file: - rts/Interpreter.c Changes: ===================================== rts/Interpreter.c ===================================== @@ -595,77 +595,67 @@ interpretBCO (Capability* cap) debugBelch("\n\n"); ); - // On entering interpretBCO, check if the step-out flag is set for this - // thread. If yes, push a step-out frame between the first frame and second - // frame. - // - // This frame will be responsible for enabling the first breakpoint that - // comes after it is evaluated (i.e. for breaking right after evaluation of - // this bco returns). - // - // See Note [Debugger: Step-out] for details - // TODOOOOOOOOOOOOOOOO UPDATES + /* If the "step-out" flag is set for this thread, find the *continuation* + * BCO on the stack and activate its breakpoint specifically. Be careful to + * use SafeSp macros to handle stack underflows. + * + * See Note [Debugger: Step-out] + */ if (cap->r.rCurrentTSO->flags & TSO_STOP_AFTER_RETURN) { - StgPtr frame; StgBCO* bco; StgWord16* bco_instrs; - frame = Sp; - - frame += stack_frame_sizeW((StgClosure *)frame); // ignore first BCO because this is the one we are stopped at. We only want to stop at the next one up the stack. - - // Insert the stg_stop_after_ret_frame after the first frame that is NOT a - // case continuation BCO. - // - // Do /not/ insert a step-out frame between case continuation - // frames and their parent BCO frame. Case continuation BCOs may have - // non-local stack references. See Note [Case continuation BCOs]. - - // UPDATE COMMENTS: NOW FIND STOP FRAME AND ACTIVATE IT - while (get_itbl((StgClosure*)frame)->type != RET_BCO) - { // TODO: HANDLE IF STACK BOTTOM - frame += stack_frame_sizeW((StgClosure *)frame); - printf("Wasn't right, keep going\n"); - } - - printf("Found frame\n"); + StgHalfWord type; - // TODO: Handle stack bottom edge case!? if frame == STACK BOTTOM... - // stack underflow *and* overflow... + /* Store the entry Sp; traverse the stack modifying Sp (using Sp macros); + * restore Sp afterwards. */ + StgPtr restoreStackPointer = Sp; - // Then write it. - // ((StgStopAfterRetFrame*)frame)->enabled = 1; + /* The first BCO on the stack is the one we are already stopped at. + * Skip it. */ + Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp)); - // TODO: Write profiling info if needed + /* Traverse upwards until continuation BCO, or the end */ + while ((type = get_itbl((StgClosure*)Sp)->type) != RET_BCO + && type != STOP_FRAME) { + Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp)); + } - bco = (StgBCO*)(frame[1]); // BCO is first argument of RET_BCO frame - ASSERT(get_itbl((StgClosure*)bco)->type == BCO); - bco_instrs = (StgWord16*)(bco->instrs->payload); + ASSERT(type == RET_BCO || type == STOP_FRAME); + if (type == RET_BCO) { - if ((bco_instrs[0] /* BRK_FUN ALWAYS FIRST INSTR */ & 0xFF) == bci_BRK_FUN) { - printf("Found BRK FUN\n"); - printf("Enabling breakpoint of BCO: %p\n", bco); + bco = (StgBCO*)(SpW(1)); // BCO is first arg of a RET_BCO + ASSERT(get_itbl((StgClosure*)bco)->type == BCO); + bco_instrs = (StgWord16*)(bco->instrs->payload); - int brk_array, tick_index; - StgArrBytes *breakPoints; - StgPtr* ptrs; + /* A breakpoint instruction (BRK_FUN or BRK_ALTS) is always the first + * instruction in a BCO */ + if ((bco_instrs[0] & 0xFF) == bci_BRK_FUN) { + int brk_array, tick_index; + StgArrBytes *breakPoints; + StgPtr* ptrs; - ptrs = (StgPtr*)(&bco->ptrs->payload[0]); - brk_array = bco_instrs[1]; - tick_index = bco_instrs[6]; + ptrs = (StgPtr*)(&bco->ptrs->payload[0]); + brk_array = bco_instrs[1]; + tick_index = bco_instrs[6]; - breakPoints = (StgArrBytes *) BCO_PTR(brk_array); - // ACTIVATE - ((StgInt*)breakPoints->payload)[tick_index] = 0; + breakPoints = (StgArrBytes *) BCO_PTR(brk_array); + // ACTIVATE the breakpoint by tick index + ((StgInt*)breakPoints->payload)[tick_index] = 0; + } + else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) { + // ACTIVATE BRK_ALTS by setting its only argument to ON + bco_instrs[1] = 1; + } } - else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) { - printf("Found BRK INTERNAL\n"); - printf("Enabling breakpoint of BCO: %p\n", bco); - bco_instrs[1] = 1; // ACTIVATE + else /* type == STOP_FRAME */ { + /* No continuation frame to further stop at: Nothing to do */ } - // Frame was pushed, mark as done to not do it again + // Mark as done to not do it again cap->r.rCurrentTSO->flags &= ~TSO_STOP_AFTER_RETURN; + + Sp = restoreStackPointer; } // ------------------------------------------------------------------------ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9efbbddb8ffa2078ea38fc2b6de6d66e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9efbbddb8ffa2078ea38fc2b6de6d66e... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Rodrigo Mesquita (@alt-romes)