Changes between Version 20 and Version 21 of Plugins/ReinitializeGlobals


Ignore:
Timestamp:
Jul 12, 2013 8:57:57 PM (9 months ago)
Author:
nfrisby
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Plugins/ReinitializeGlobals

    v20 v21  
    33== Status == 
    44 
    5 After a few, unfortunately public, iterations, I'm pushing Solution 1. 
     5I'm deciding between 
    66 
    7   * Solution 1 is a lightweight solution, re-uses an existing mechanism, has a small footprint in the GHC source code, is totally transparent to the plugin author, and robustly handles corner cases.  
     7  * Solution 1 — using the `rts/Globals.c` mechanism for `FastString.string_table`, or 
    88 
    9   * Solution 2 only simplifies code, but it makes a user choose between (safely) using a plugin that involves `FastString.string_table` and using statically-linked GHC. 
     9  * Solution 2 — requiring a dynamically-linked ghc to (safely) use plugins that involve FastStrings. 
    1010 
    11 Solution 1 relies on the `rts/Globals.c`, which would be excised anyway if Solution 2 is ever viable… 
     11After a few, unfortunately public, iterations, I've chosen push Solution 1. 
     12 
     13  * It re-uses an existing mechanism, has a small footprint in the GHC source code, is totally transparent to the plugin author, and robustly handles corner cases.  
     14 
     15  * It handles any number of instances of libHSghc in a process, ''regardless of how they got there''. 
     16 
     17  * It puts no constraints on the rest of the user's installation — use whatever kind of ghc you like. On the other hand,   Solution 2 makes a user choose between (safely) using a plugin that involves `FastString.string_table` and using statically-linked GHC. 
     18 
     19I have one remaining concern: in the eventuality where ghci becomes its own dynamically-linked binary and ghc remains statically-linked, then my patch will be the only remaining use of the `rts/Globals.c` mechanism.  (For the record, that mechanism is vastly simpler than the RTS linker…) 
     20 
     21We can cross that bridge if/when we come to it, though. 
    1222 
    1323== Background == 
    14  
    15 === global variables used in GHC === 
    16  
    17 I performed a bunch of greps in search of global variables in the code base: 
    18  
    19 {{{ 
    20 # find possible top-level declarations of an IORef, MVar, some sort of pointer, global 
    21 $ find .. -type f -exec grep -nHE -e '^[^ ].*:: *IORef' {} /dev/null \; 
    22 $ find .. -type f -exec grep -nHE -e '^[^ ].*:: *MVar' {} /dev/null \; 
    23 $ find .. -type f -exec grep -nHE -e '^[^ ].*:: *[^ ]*Ptr' {} /dev/null \; 
    24 $ find .. -type f -exec grep -nHw -e global {} /dev/null \; 
    25 }}} 
    26  
    27 (also for `unsafe[^ ]*IO`, `inlinePerformIO`, and `unsafeInterleaveM`) 
    28  
    29 Manually combing the results, I found these legitimate hits: 
    30  
    31   * these three modules use the GLOBAL_VAR macro and were already supported by reinitializeGlobals: `StaticFlags`, `DynFlags`, `Linker` 
    32  
    33   * my focus: `FastString.string_table` 
    34  
    35   * I don't know what these are for: `Panic.interruptTargetThread`, `InteractiveEval.noBreakStablePtr` 
    3624 
    3725=== `CoreMonad.reinitializeGlobals` === 
     
    6048=== `FastString.string_table` === 
    6149 
    62 I'd like to let plugins correctly use this variable, since that would let them invoke some parts of the front-end (eg resolving `RdrName`s). 
     50I'd like to let plugins correctly use this variable, since that would let them invoke (parts of?) the front-end (eg resolving `RdrName`s). 
    6351 
    6452All the `FastString`s created during compilation are memoized in a hash table. For speedy comparison, each string is associated with a unique, which is allocated linearly whenever a `FastString` is created that has no corresponding entry in the hash table. This involves two pieces of global state, which are held in the same global variable. 
     
    7866It's straight-forward to have the two images share the array, but it is difficult to keep the two images' values of `Int` in synch.  The danger is that the two images could allocate the same unique for distinct `FastString`s — that'd break a major invariant. 
    7967 
    80 == Solutions == 
     68=== all global variables used in GHC === 
     69 
     70I performed a bunch of greps in search of global variables in the code base: 
     71 
     72{{{ 
     73# find possible top-level declarations of an IORef, MVar, some sort of pointer, global 
     74$ find .. -type f -exec grep -nHE -e '^[^ ].*:: *IORef' {} /dev/null \; 
     75$ find .. -type f -exec grep -nHE -e '^[^ ].*:: *MVar' {} /dev/null \; 
     76$ find .. -type f -exec grep -nHE -e '^[^ ].*:: *[^ ]*Ptr' {} /dev/null \; 
     77$ find .. -type f -exec grep -nHw -e global {} /dev/null \; 
     78}}} 
     79 
     80(also for `unsafe[^ ]*IO`, `inlinePerformIO`, and `unsafeInterleaveM`) 
     81 
     82Manually combing the results, I found these legitimate hits: 
     83 
     84  * these three modules use the GLOBAL_VAR macro and were already supported by reinitializeGlobals: `StaticFlags`, `DynFlags`, `Linker` 
     85 
     86  * my focus: `FastString.string_table` 
     87 
     88  * I don't know what these are for: `Panic.interruptTargetThread`, `InteractiveEval.noBreakStablePtr` 
     89 
     90The `FastString.string_table` is just a cache — it's very unlikely that anyone would ever desire two distinct copies of it. 
     91 
     92For the global variables, I'm not so sure about that: it's feasible to have intentionally distinct copies. 
     93 
     94== Solutions for `FastString.string_table` == 
    8195 
    8296=== Solution 1: the `Globals.c` mechanism ===