Changes between Version 20 and Version 21 of Plugins/ReinitializeGlobals


Ignore:
Timestamp:
Jul 12, 2013 8:57:57 PM (2 years 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 ===