Changes between Version 1 and Version 2 of Commentary/Compiler/Backends/GHCi


Ignore:
Timestamp:
May 7, 2011 1:15:42 AM (3 years ago)
Author:
igloo
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/Backends/GHCi

    v1 v2  
    1616 * Find the smallest source fragment which causes the problem. 
    1717 
    18  * Using an RTS compiled with -DDEBUG (nb, that means the RTS from the previous stage!), run with +RTS -D2 to get a listing in great detail from the interpreter. Note that the listing is so voluminous that this is impractical unless you have been diligent in the previous step. 
     18 * Using an RTS compiled with `-DDEBUG`, run with `+RTS -Di` to get a listing in great detail from the interpreter. Note that the listing is so voluminous that this is impractical unless you have been diligent in the previous step. 
    1919 
    20  * At least in principle, using the trace and a bit of GDB poking around at the time of death, you can figure out what the problem is. In practice you quickly get depressed at the hopelessness of ever making sense of the mass of details. Well, I do, anyway. 
     20 * At least in principle, using the trace and a bit of GDB poking around at the time of death (See also [wiki:Debugging]), you can figure out what the problem is. In practice you quickly get depressed at the hopelessness of ever making sense of the mass of details. Well, I do, anyway. 
    2121 
    22  * +RTS -D2 tries hard to print useful descriptions of what's on the stack, and often succeeds. However, it has no way to map addresses to names in code/data loaded by our runtime linker. So the C function ghci_enquire is provided. Given an address, it searches the loaded symbol tables for symbols close to that address. You can run it from inside GDB: 
     22 * `+RTS -Di` tries hard to print useful descriptions of what's on the stack, and often succeeds. However, it has no way to map addresses to names in code/data loaded by our runtime linker. So the C function `ghci_enquire` is provided. Given an address, it searches the loaded symbol tables for symbols close to that address. You can run it from inside GDB: 
    2323 
    2424{{{ 
     
    3838}}}             
    3939 
    40  In this case the enquired-about address is PrelBase_ZMZN_static_entry. If no symbols are close to the given addr, nothing is printed. Not a great mechanism, but better than nothing. 
     40 In this case the enquired-about address is `PrelBase_ZMZN_static_entry`. If no symbols are close to the given addr, nothing is printed. Not a great mechanism, but better than nothing. 
    4141 
    42  * We have had various problems in the past due to the bytecode generator (compiler/ghci/ByteCodeGen.lhs) being confused about the true set of free variables of an expression. The compilation scheme for lets applies the BCO for the RHS of the let to its free variables, so if the free-var annotation is wrong or misleading, you end up with code which has wrong stack offsets, which is usually fatal. 
    43  
    44  * The baseline behaviour of the interpreter is to interpret BCOs, and hand all other closures back to the scheduler for evaluation. However, this causes a huge number of expensive context switches, so the interpreter knows how to enter the most common non-BCO closure types by itself. 
    45  
    46  These optimisations complicate the interpreter. If you think you have an interpreter problem, re-enable the define REFERENCE_INTERPRETER in ghc/rts/Interpreter.c. All optimisations are thereby disabled, giving the baseline I-only-know-how-to-enter-BCOs behaviour. 
     42 * We have had various problems in the past due to the bytecode generator (compiler/ghci/ByteCodeGen.lhs) being confused about the true set of free variables of an expression. The compilation scheme for `let`s applies the BCO for the RHS of the `let` to its free variables, so if the free-var annotation is wrong or misleading, you end up with code which has wrong stack offsets, which is usually fatal. 
    4743 
    4844 * Following the traces is often problematic because execution hops back and forth between the interpreter, which is traced, and compiled code, which you can't see. Particularly annoying is when the stack looks OK in the interpreter, then compiled code runs for a while, and later we arrive back in the interpreter, with the stack corrupted, and usually in a completely different place from where we left off. 
    4945 
    50  If this is biting you baaaad, it may be worth copying sources for the compiled functions causing the problem, into your interpreted module, in the hope that you stay in the interpreter more of the time. Of course this doesn't work very well if you've defined REFERENCE_INTERPRETER in ghc/rts/Interpreter.c. 
     46 If this is biting you baaaad, it may be worth copying sources for the compiled functions causing the problem, into your interpreted module, in the hope that you stay in the interpreter more of the time. 
    5147 
    52  * There are various commented-out pieces of code in Interpreter.c which can be used to get the stack sanity-checked after every entry, and even after after every bytecode instruction executed. Note that some bytecodes (PUSH_UBX) leave the stack in an unwalkable state, so the do_print_stack local variable is used to suppress the stack walk after them.  
     48 * There are various commented-out pieces of code in Interpreter.c which can be used to get the stack sanity-checked after every entry, and even after after every bytecode instruction executed. Note that some bytecodes (`PUSH_UBX`) leave the stack in an unwalkable state, so the `do_print_stack` local variable is used to suppress the stack walk after them.  
    5349 
    5450== Useful stuff to know about the interpreter == 
    5551 
    56 The code generation scheme is straightforward (naive, in fact). -ddump-bcos prints each BCO along with the Core it was generated from, which is very handy. 
     52The code generation scheme is straightforward (naive, in fact). `-ddump-bcos` prints each BCO along with the Core it was generated from, which is very handy. 
    5753 
    58  * Simple lets are compiled in-line. For the general case, let v = E in ..., E is compiled into a new BCO which takes as args its free variables, and v is bound to AP(the new BCO, free vars of E). 
     54 * Simple `let`s are compiled in-line. For the general case, `let v = E in ...`, the expression `E` is compiled into a new BCO which takes as args its free variables, and `v` is bound to `AP(the new BCO, free vars of E)`. 
    5955 
    60  * cases as usual, become: push the return continuation, enter the scrutinee. There is some magic to make all combinations of compiled/interpreted calls and returns work, described below. In the interpreted case, all case alts are compiled into a single big return BCO, which commences with instructions implementing a switch tree.  
     56 * `case`s as usual, become: push the return continuation, enter the scrutinee. There is some magic to make all combinations of compiled/interpreted calls and returns work, described below. In the interpreted case, all `case` alts are compiled into a single big return BCO, which commences with instructions implementing a switch tree.  
    6157 
    6258=== ARGCHECK magic ===