use UniqSupply in FastString?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
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:

  http://hackage.haskell.org/trac/ghc/wiki/Plugins/ReinitializeGlobals

(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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130705/16cb44ce/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Simon Peyton Jones
A UniqSupply has a single shared Int behind the scenes, so it's really no different.

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.

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

Simon

From: ghc-devs-bounces at haskell.org [mailto:ghc-devs-bounces at haskell.org] On Behalf Of Nicolas Frisby
Sent: 05 July 2013 18:14
To: ghc-devs at 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:

  http://hackage.haskell.org/trac/ghc/wiki/Plugins/ReinitializeGlobals

(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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130705/5e27071e/attachment-0001.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
Thanks for the feedback.

On Fri, Jul 5, 2013 at 6:03 PM, Simon Peyton-Jones <simonpj at 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 at haskell.org [mailto:ghc-devs-bounces at haskell.org]
> *On Behalf Of *Nicolas Frisby
> *Sent:* 05 July 2013 18:14
> *To:* ghc-devs at 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: ****
>
> ** **
>
>   http://hackage.haskell.org/trac/ghc/wiki/Plugins/ReinitializeGlobals****
>
> ** **
>
> (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.****
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130705/e276519a/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
>
> 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.
>

Realized: this is bogus, isn't it? There's nothing prevent a plugin from
being compiled with its own "static" copy of libHSghc, is there? There
could be more than two images of libHSghc in play at any given time.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130705/1e03279b/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Simon Marlow-7
In reply to this post by Simon Peyton Jones
I haven't been following this in detail, but I think you're encountering
the same problem we had with various top-level IORefs in the base
package.  The solution we have there is grotesque but it works.  Take a
look at libraries/base/GHC/Conc/Signal.hs, search for
getOrSetGHCConcSignalSignalHandlerStore.  There is some corresponding
RTS gunk to help with this in rts/Globals.c.

We can't make FastString use UniqSupply - it must use unsafePerformIO,
since the whole point is to hide the side effects behind a nice pure API.

Cheers,
        Simon


On 06/07/13 00:03, Simon Peyton-Jones wrote:

> A UniqSupply has a single shared Int behind the scenes, so it?s really
> no different.
>
> 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.
>
> 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
>
> Simon
>
> *From:*ghc-devs-bounces at haskell.org
> [mailto:ghc-devs-bounces at haskell.org] *On Behalf Of *Nicolas Frisby
> *Sent:* 05 July 2013 18:14
> *To:* ghc-devs at 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:
>
> http://hackage.haskell.org/trac/ghc/wiki/Plugins/ReinitializeGlobals
>
> (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.
>



Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
On Sat, Jul 6, 2013 at 1:48 AM, Simon Marlow <marlowsd at gmail.com> wrote:

> I haven't been following this in detail, but I think you're encountering
> the same problem we had with various top-level IORefs in the base package.
>  The solution we have there is grotesque but it works.  Take a look at
> libraries/base/GHC/Conc/**Signal.hs, search for
> getOrSetGHCConcSignalSignalHan**dlerStore.  There is some corresponding
> RTS gunk to help with this in rts/Globals.c.
>

Excellent. Thanks very much. This the most robust solution I envisioned,
but I didn't know enough about the low-level stuff to execute. I'm excited
to work through the code.


> We can't make FastString use UniqSupply - it must use unsafePerformIO,
> since the whole point is to hide the side effects behind a nice pure API.
>
>
tl;dr The rest of my reply is moot, since your RTS workaround is preferred.

I should have been clearer: I meant to use
unsafePerformIO-around-a-UniqSupply instead of using
unsafePerformIO-around-a-linearly-incremented-Int. The intent was to handle
a well-behaved coarse interleaving of the compiler and plugin ? as opposed
to parallel execution or fine-grain concurrency.

Thus, switching to unsafePerformIO-around-a-UniqSupply seemed at least as
"safe" as the current Int implementation, but with the splitting logic. Are
there any pitfalls in that logic?

Thanks again for the spot-on pointer.

Cheers,

>         Simon
>
>
>
> On 06/07/13 00:03, Simon Peyton-Jones wrote:
>
>> A UniqSupply has a single shared Int behind the scenes, so it?s really
>> no different.
>>
>> 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.
>>
>> 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
>>
>> Simon
>>
>> *From:*ghc-devs-bounces@**haskell.org <ghc-devs-bounces at haskell.org>
>> [mailto:ghc-devs-bounces@**haskell.org <ghc-devs-bounces at haskell.org>]
>> *On Behalf Of *Nicolas Frisby
>> *Sent:* 05 July 2013 18:14
>> *To:* ghc-devs at 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:
>>
>> http://hackage.haskell.org/**trac/ghc/wiki/Plugins/**ReinitializeGlobals<http://hackage.haskell.org/trac/ghc/wiki/Plugins/ReinitializeGlobals>
>>
>> (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.
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130706/9a035197/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Ian Lynagh-2
In reply to this post by Nicolas Frisby
On Fri, Jul 05, 2013 at 12:14:06PM -0500, Nicolas Frisby wrote:
>
> I've been trying to let a statically-linked compiler shares its FastString
> table with plugins.

Why not use a dynamically linked compiler?


Thanks
Ian
--
Ian Lynagh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/


Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
On Sat, Jul 6, 2013 at 2:55 PM, Ian Lynagh <ian at well-typed.com> wrote:

> On Fri, Jul 05, 2013 at 12:14:06PM -0500, Nicolas Frisby wrote:
> >
> > I've been trying to let a statically-linked compiler shares its
> FastString
> > table with plugins.
>
> Why not use a dynamically linked compiler?
>

I didn't stop to question the need for 'reinitializeGlobals`. I dove right
in to extending it based on my troubles with 7.6.3 (Joachim Breitner had
similar issues, with 7.6.3-ish I'm assuming) and have been learning about
the background as I go.

My 7.6.3 ghc was statically-linked, and I didn't question that aspect
either; though it seems to to be the default for that version's build
system.

If "platform supports plugins" implies "platform supports dynamically
linked ghc executable", then I suppose we could just make that a
prerequisite for Core plugins and rid ourselves of 'reinitializeGlobals`
all together.

Perhaps we could also discard the stuff in Globals.c. The header of that
file discusses ghci and dynamic-linking; I'm not up-to-date on that topic.
That'd be safe to rip out if "platform supports dynamic libraries" implies
"platform supports dynamically linked ghc executable", I think? but I'm
pretty oblivious about how ghci works and what it needs.

On the other hand, the Globals.c mechanism is lightweight and handles all
sorts of odd scenarios correctly. Maybe we should use it for all global
variables, just for robustness?

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130706/3d1b5066/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

use UniqSupply in FastString?

Nicolas Frisby
In reply to this post by Ian Lynagh-2
On Sat, Jul 6, 2013 at 2:55 PM, Ian Lynagh <ian at well-typed.com> wrote:

> On Fri, Jul 05, 2013 at 12:14:06PM -0500, Nicolas Frisby wrote:
> >
> > I've been trying to let a statically-linked compiler shares its
> FastString
> > table with plugins.
>
> Why not use a dynamically linked compiler?
>

My main concern with this option is having the plugins that need FastString
support work with an out-of-the-box ghc. If my plugin's prerequisite is
"first, go rebuild another copy of GHC", my plugin might as well not be a
plugin.

I'm still hoping for more responses to my other email on this topic, but
it's starting to seem that having the out-of-the-box ghc be a dynamically
link against libHSghc is not necessarily likely on all platforms that
support Core plugins.

Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130711/944880ac/attachment.htm>