Thanks for the feedback.

On Fri, Jul 5, 2013 at 6:03 PM, Simon Peyton-Jones <simonpj@microsoft.com> wrote:

A UniqSupply has a single shared Int behind the scenes, so it’s really no different.


A UniqSupply also has the splitting "magic"; that's what's makes it an attractive for this use case.
 

 

Simon Marlow may want to comment on your proposed solutions. Personally I think Option 1 is most attractive. Yes, the API changes, but in a decent way and one that may be useful for other things. 

 

I wasn't thinking beyond this trouble with the two libHSghc images; the idea of encasing the entire plugin in a call does sound "useful for other things". Indeed, we may want to enforce this with some abstract types and functions, `mkPlugin` and `mkPluginPass`, for future-proofness.

Even so, Option 1 suffers from the same laziness issues as Option 2. Our synchronization steps happen when control passes back and forth between the compiler and the plugin under the assumption that the global variables of the "inactive" one won't be changing.  If a plugin pass forces a compiler's thunk (or vice versa) and that thunk allocates a FastString, then that breaks our assumption (…there go the missiles).  Avoiding this sort of incoherency-due-to-unsafePerfomIO-and-laziness seems very delicate and is why I'm favoring Options 3, 5, and 6.

Now I think of it, why can’t ‘install’ do the workAroundGloblals call?  Then clients would not need to.  Maybe I’m not thinking straight

I'm not sure what you mean here. It is key that 'reinitializeGlobals` is called from the plugin — that's how we access the dynamically loaded libHSghc's global variables.

I almost said "or else we couldn't access…" but then I thought that perhaps there is a way we can. If so, we could fully hide the reinitializeGlobals from the plugin author. The host compiler loads the plugin dynamically and then extracts the 'MyPluging.plugin` symbol. For reasons I don't understand, this also loads a second copy of libHSghc into memory. Can we use the same dynamic loading mechanisms to extract that second image's global variable symbols directly? Instead of requiring the plugin to alter those variables by calling 'reinitializeGlobals`?

In other words, we always "load" a tiny special plugin that does the 'reinitializeGlobals` call and is otherwise a noop. Since all plugins share the some dynamically loaded library, we just need 'reinitializeGlobals` to be called once, no matter how many plugins are loaded. Then the actual plugins wouldn't need to know about the whole fiasco.

I'd have to dig into the dynamic loading stuff to better estimate this… can anyone chime in?

Thanks for the brain food!

 

Simon

 

From: ghc-devs-bounces@haskell.org [mailto:ghc-devs-bounces@haskell.org] On Behalf Of Nicolas Frisby
Sent: 05 July 2013 18:14
To: ghc-devs@haskell.org
Subject: use UniqSupply in FastString?

 

Does it sound reasonable to change the FastString module to use a UniqSupply instead of using that Int for generating uniques?

 

I've been trying to let a statically-linked compiler shares its FastString table with plugins. Status, background info, options here: 

 

 

(I got a little ahead of myself with Option 2…)

 

Uniques for FastStrings are currently allocated linearly using a global Int variable. Because unsafePerformIO is used, it's difficult to keep the two global Ints in synch (one for the compiler, the other for the plugins). The danger is that the compiler and a plugin might allocate the same unique for distinct FastStrings — that'd break a major invariant. If we used UniqSupply, we'd avoid that danger, just about for free.

 

I'm not sure how robust/speedy UniqSupply is though. Considering its widespread use, I figured it'd be good enough by a pretty wide margin; FastString *creation* seems relatively infrequent.

 

Thanks for your input.