Rodrigo Mesquita pushed to branch wip/romes/step-out-5 at Glasgow Haskell Compiler / GHC

Commits:

1 changed file:

Changes:

  • rts/Interpreter.c
    ... ... @@ -595,77 +595,67 @@ interpretBCO (Capability* cap)
    595 595
                  debugBelch("\n\n");
    
    596 596
                 );
    
    597 597
     
    
    598
    -    // On entering interpretBCO, check if the step-out flag is set for this
    
    599
    -    // thread. If yes, push a step-out frame between the first frame and second
    
    600
    -    // frame.
    
    601
    -    //
    
    602
    -    // This frame will be responsible for enabling the first breakpoint that
    
    603
    -    // comes after it is evaluated (i.e. for breaking right after evaluation of
    
    604
    -    // this bco returns).
    
    605
    -    //
    
    606
    -    // See Note [Debugger: Step-out] for details
    
    607
    -    // TODOOOOOOOOOOOOOOOO UPDATES
    
    598
    +    /* If the "step-out" flag is set for this thread, find the *continuation*
    
    599
    +     * BCO on the stack and activate its breakpoint specifically. Be careful to
    
    600
    +     * use SafeSp macros to handle stack underflows.
    
    601
    +     *
    
    602
    +     * See Note [Debugger: Step-out]
    
    603
    +     */
    
    608 604
         if (cap->r.rCurrentTSO->flags & TSO_STOP_AFTER_RETURN) {
    
    609 605
     
    
    610
    -      StgPtr frame;
    
    611 606
           StgBCO* bco;
    
    612 607
           StgWord16* bco_instrs;
    
    613
    -      frame = Sp;
    
    614
    -
    
    615
    -      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.
    
    616
    -
    
    617
    -      // Insert the stg_stop_after_ret_frame after the first frame that is NOT a
    
    618
    -      // case continuation BCO.
    
    619
    -      //
    
    620
    -      // Do /not/ insert a step-out frame between case continuation
    
    621
    -      // frames and their parent BCO frame. Case continuation BCOs may have
    
    622
    -      // non-local stack references. See Note [Case continuation BCOs].
    
    623
    -
    
    624
    -      // UPDATE COMMENTS: NOW FIND STOP FRAME AND ACTIVATE IT
    
    625
    -      while (get_itbl((StgClosure*)frame)->type != RET_BCO)
    
    626
    -      { // TODO: HANDLE IF STACK BOTTOM
    
    627
    -        frame += stack_frame_sizeW((StgClosure *)frame);
    
    628
    -        printf("Wasn't right, keep going\n");
    
    629
    -      }
    
    630
    -
    
    631
    -      printf("Found frame\n");
    
    608
    +      StgHalfWord type;
    
    632 609
     
    
    633
    -      // TODO: Handle stack bottom edge case!? if frame == STACK BOTTOM...
    
    634
    -      // stack underflow *and* overflow...
    
    610
    +      /* Store the entry Sp; traverse the stack modifying Sp (using Sp macros);
    
    611
    +       * restore Sp afterwards. */
    
    612
    +      StgPtr restoreStackPointer = Sp;
    
    635 613
     
    
    636
    -      // Then write it.
    
    637
    -      // ((StgStopAfterRetFrame*)frame)->enabled = 1;
    
    614
    +      /* The first BCO on the stack is the one we are already stopped at.
    
    615
    +       * Skip it. */
    
    616
    +      Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp));
    
    638 617
     
    
    639
    -      // TODO: Write profiling info if needed
    
    618
    +      /* Traverse upwards until continuation BCO, or the end */
    
    619
    +      while ((type = get_itbl((StgClosure*)Sp)->type) != RET_BCO
    
    620
    +                                             && type  != STOP_FRAME) {
    
    621
    +        Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp));
    
    622
    +      }
    
    640 623
     
    
    641
    -      bco = (StgBCO*)(frame[1]); // BCO is first argument of RET_BCO frame
    
    642
    -      ASSERT(get_itbl((StgClosure*)bco)->type == BCO);
    
    643
    -      bco_instrs = (StgWord16*)(bco->instrs->payload);
    
    624
    +      ASSERT(type == RET_BCO || type == STOP_FRAME);
    
    625
    +      if (type == RET_BCO) {
    
    644 626
     
    
    645
    -      if ((bco_instrs[0] /* BRK_FUN ALWAYS FIRST INSTR */ & 0xFF) == bci_BRK_FUN) {
    
    646
    -          printf("Found BRK FUN\n");
    
    647
    -          printf("Enabling breakpoint of BCO: %p\n", bco);
    
    627
    +        bco = (StgBCO*)(SpW(1)); // BCO is first arg of a RET_BCO
    
    628
    +        ASSERT(get_itbl((StgClosure*)bco)->type == BCO);
    
    629
    +        bco_instrs = (StgWord16*)(bco->instrs->payload);
    
    648 630
     
    
    649
    -          int brk_array, tick_index;
    
    650
    -          StgArrBytes *breakPoints;
    
    651
    -          StgPtr* ptrs;
    
    631
    +        /* A breakpoint instruction (BRK_FUN or BRK_ALTS) is always the first
    
    632
    +         * instruction in a BCO */
    
    633
    +        if ((bco_instrs[0] & 0xFF) == bci_BRK_FUN) {
    
    634
    +            int brk_array, tick_index;
    
    635
    +            StgArrBytes *breakPoints;
    
    636
    +            StgPtr* ptrs;
    
    652 637
     
    
    653
    -          ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
    
    654
    -          brk_array  = bco_instrs[1];
    
    655
    -          tick_index = bco_instrs[6];
    
    638
    +            ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
    
    639
    +            brk_array  = bco_instrs[1];
    
    640
    +            tick_index = bco_instrs[6];
    
    656 641
     
    
    657
    -          breakPoints = (StgArrBytes *) BCO_PTR(brk_array);
    
    658
    -          // ACTIVATE
    
    659
    -          ((StgInt*)breakPoints->payload)[tick_index] = 0;
    
    642
    +            breakPoints = (StgArrBytes *) BCO_PTR(brk_array);
    
    643
    +            // ACTIVATE the breakpoint by tick index
    
    644
    +            ((StgInt*)breakPoints->payload)[tick_index] = 0;
    
    645
    +        }
    
    646
    +        else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) {
    
    647
    +            // ACTIVATE BRK_ALTS by setting its only argument to ON
    
    648
    +            bco_instrs[1] = 1;
    
    649
    +        }
    
    660 650
           }
    
    661
    -      else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) {
    
    662
    -          printf("Found BRK INTERNAL\n");
    
    663
    -          printf("Enabling breakpoint of BCO: %p\n", bco);
    
    664
    -          bco_instrs[1] = 1; // ACTIVATE
    
    651
    +      else /* type == STOP_FRAME */ {
    
    652
    +        /* No continuation frame to further stop at: Nothing to do */
    
    665 653
           }
    
    666 654
     
    
    667
    -      // Frame was pushed, mark as done to not do it again
    
    655
    +      // Mark as done to not do it again
    
    668 656
           cap->r.rCurrentTSO->flags &= ~TSO_STOP_AFTER_RETURN;
    
    657
    +
    
    658
    +      Sp = restoreStackPointer;
    
    669 659
         }
    
    670 660
     
    
    671 661
         // ------------------------------------------------------------------------