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

Commits:

4 changed files:

Changes:

  • compiler/GHC/ByteCode/Types.hs
    ... ... @@ -203,7 +203,7 @@ A stack with a BCO stack frame at the top looks like:
    203 203
     
    
    204 204
     In the case of bytecode objects found on the heap (e.g. thunks and functions),
    
    205 205
     the bytecode may refer to free variables recorded in the BCO closure itself.
    
    206
    -By contrast, in /case continuation/ BCOsthe code may additionally refer to free
    
    206
    +By contrast, in /case continuation/ BCOs the code may additionally refer to free
    
    207 207
     variables in their stack frame. These are references by way of statically known
    
    208 208
     stack offsets (tracked using `BCEnv` in `StgToByteCode`).
    
    209 209
     
    

  • compiler/GHC/Driver/Config.hs
    ... ... @@ -33,7 +33,7 @@ initSimpleOpts dflags = SimpleOpts
    33 33
     data EvalStep
    
    34 34
       -- | ... at every breakpoint tick
    
    35 35
       = EvalStepSingle
    
    36
    -  -- | ... after any return stmt
    
    36
    +  -- | ... after any evaluation to WHNF
    
    37 37
       | EvalStepOut
    
    38 38
       -- | ... only on explicit breakpoints
    
    39 39
       | EvalStepNone
    

  • compiler/GHC/StgToByteCode.hs
    ... ... @@ -1407,25 +1407,49 @@ ensuring that we stop exactly when we return to the continuation.
    1407 1407
     
    
    1408 1408
     However, case continuation BCOs (produced by PUSH_ALTS and which merely compute
    
    1409 1409
     which case alternative BCO to enter next) contain no user-facing breakpoint
    
    1410
    -ticks (BRK_FUN):
    
    1410
    +ticks (BRK_FUN). While we could in principle add breakpoints in case continuation
    
    1411
    +BCOs, there are a few reasons why this is not an attractive option:
    
    1411 1412
     
    
    1412 1413
       1) It's not useful to a user stepping through the program to always have a
    
    1413 1414
       breakpoint after the scrutinee is evaluated but before the case alternative
    
    1414 1415
       is selected. The source span associated with such a breakpoint would also be
    
    1415 1416
       slightly awkward to choose.
    
    1416 1417
     
    
    1417
    -  2) It's not easy to add a source-tick before the case alternatives because in
    
    1418
    +  2) It's not easy to add a breakpoint tick before the case alternatives because in
    
    1418 1419
       essentially all internal representations they are given as a list of Alts
    
    1419 1420
       rather than an expression.
    
    1420 1421
     
    
    1421
    -To provide the debugger a way to enable at runtime the case continuation
    
    1422
    -breakpoints despite the lack of BRK_FUNs, we introduce at the start
    
    1423
    -of every case continuation BCO a BRK_ALTS instruction.
    
    1424
    -
    
    1425
    -The BRK_ALTS instruction, if enabled (by its single arg), ensures we stop at
    
    1426
    -the breakpoint heading the case alternative we take. Under the hood, this means
    
    1427
    -that when BRK_ALTS is enabled we set TSO_STOP_NEXT_BREAKPOINT just before
    
    1428
    -selecting the alternative.
    
    1422
    +To provide the debugger a way to break in a case continuation
    
    1423
    +despite the BCOs' lack of BRK_FUNs, we introduce an alternative
    
    1424
    +type of breakpoint, represented by the BRK_ALTS instruction,
    
    1425
    +at the start of every case continuation BCO. For instance,
    
    1426
    +
    
    1427
    +    case x of
    
    1428
    +      0# -> ...
    
    1429
    +      _  -> ...
    
    1430
    +
    
    1431
    +will produce a continuation of the form (N.B. the below bytecode
    
    1432
    +is simplified):
    
    1433
    +
    
    1434
    +    PUSH_ALTS P
    
    1435
    +      BRK_ALTS 0
    
    1436
    +      TESTEQ_I 0 lblA
    
    1437
    +      PUSH_BCO
    
    1438
    +        BRK_FUN 0
    
    1439
    +        -- body of 0# alternative
    
    1440
    +      ENTER
    
    1441
    +      
    
    1442
    +      lblA:
    
    1443
    +      PUSH_BCO
    
    1444
    +        BRK_FUN 1
    
    1445
    +        -- body of wildcard alternative
    
    1446
    +      ENTER
    
    1447
    +
    
    1448
    +When enabled (by its single boolean operand), the BRK_ALTS instruction causes
    
    1449
    +the program to break at the next encountered breakpoint (implemented
    
    1450
    +by setting the TSO's TSO_STOP_NEXT_BREAKPOINT flag). Since the case
    
    1451
    +continuation BCO will ultimately jump to one of the alternatives (each of
    
    1452
    +which having its own BRK_FUN) we are guaranteed to stop in the taken alternative.
    
    1429 1453
     
    
    1430 1454
     It's important that BRK_ALTS (just like BRK_FUN) is the first instruction of
    
    1431 1455
     the BCO, since that's where the debugger will look to enable it at runtime.
    

  • rts/Interpreter.c
    ... ... @@ -351,7 +351,7 @@ To achieve this, when the flag is set as the interpreter is re-entered:
    351 351
     
    
    352 352
           (2a) For PUSH_ALT BCOs, the breakpoint instruction will be BRK_ALTS
    
    353 353
               (as explained in Note [Debugger: BRK_ALTS]) and it can be enabled by
    
    354
    -          overriding its first argument to 1.
    
    354
    +          setting its first operand to 1.
    
    355 355
     
    
    356 356
           (2b) Otherwise, the instruction will be BRK_FUN and the breakpoint can be
    
    357 357
                enabled by setting the associated BreakArray at the associated tick