ForeignPtr representation

2018-09-04 Thread David Feuer
I'm trying, and failing, to understand why ForeignPtr is defined the way it
is. It all seems rather complicated and redundant. I was thinking we might
want to switch to something simpler and more explicit, like this:

data ForeignPtr a = ForeignPtr {
  fptr :: !(Ptr a) -- What we point to
  froot :: MutableByteArray# RealWorld
  fwk :: MutVar# RealWorld Any -- The finalizers
  }

froot represents the object the ForeignPtr points into. When created by one
of the malloc variants, this will actually be the allocated byte array.
Otherwise, it will be a 0-length array.

fwk should be seen as having type

  fwk :: MutVar# RealWorld (Weak# (MutableByteArray# RealWorld))

but we can't express that directly right now. fwk is keyed on froot, and in
the malloc case also points to it, to prevent it from being freed
prematurely.

It seems that this representation requires a couple extra primitive
features from Weak#. I think that's okay: Weak# already has some primitive
features designed to support ForeignPtr.

1. An operation to add a Haskell finalizer to a Weak#, similar to the one
that adds a C finalizer.

2. A way to deal with mixed finalizers: either make the finalizer-adding
primops report distinguishable failure on mixing or arrange to run the C
finalizers after any Haskell finalizers (since C finalizers are much more
likely to actually invalidate the pointer).

3. A documented guarantee about the order in which the finalizers attached
to a particular Weak# run, compatible with the ForeignPtr documentation.
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


RE: ForeignPtr representation

2018-09-04 Thread Simon Peyton Jones via ghc-devs
Interesting.

Can you summarise how ForeignPtr is defined right now?   And point to any 
documentation about the specification of ForeignPtr, or Notes about its 
implementation?

So that we can compare with what your proposal.

What’s the connection with weak pointers?

Simon

From: ghc-devs  On Behalf Of David Feuer
Sent: 05 September 2018 00:23
To: ghc-devs 
Subject: ForeignPtr representation

I'm trying, and failing, to understand why ForeignPtr is defined the way it is. 
It all seems rather complicated and redundant. I was thinking we might want to 
switch to something simpler and more explicit, like this:

data ForeignPtr a = ForeignPtr {
  fptr :: !(Ptr a) -- What we point to
  froot :: MutableByteArray# RealWorld
  fwk :: MutVar# RealWorld Any -- The finalizers
  }

froot represents the object the ForeignPtr points into. When created by one of 
the malloc variants, this will actually be the allocated byte array. Otherwise, 
it will be a 0-length array.

fwk should be seen as having type

  fwk :: MutVar# RealWorld (Weak# (MutableByteArray# RealWorld))

but we can't express that directly right now. fwk is keyed on froot, and in the 
malloc case also points to it, to prevent it from being freed prematurely.

It seems that this representation requires a couple extra primitive features 
from Weak#. I think that's okay: Weak# already has some primitive features 
designed to support ForeignPtr.

1. An operation to add a Haskell finalizer to a Weak#, similar to the one that 
adds a C finalizer.

2. A way to deal with mixed finalizers: either make the finalizer-adding 
primops report distinguishable failure on mixing or arrange to run the C 
finalizers after any Haskell finalizers (since C finalizers are much more 
likely to actually invalidate the pointer).

3. A documented guarantee about the order in which the finalizers attached to a 
particular Weak# run, compatible with the ForeignPtr documentation.
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ForeignPtr representation

2018-09-06 Thread Simon Marlow
Wouldn't this mean that unpacking a ForeignPtr is one word longer than it
is now? That would have a big impact on ByteString.

What do you think is redundant in the current representation?

Cheers
Simon

On Wed, 5 Sep 2018 at 00:23, David Feuer  wrote:

> I'm trying, and failing, to understand why ForeignPtr is defined the way
> it is. It all seems rather complicated and redundant. I was thinking we
> might want to switch to something simpler and more explicit, like this:
>
> data ForeignPtr a = ForeignPtr {
>   fptr :: !(Ptr a) -- What we point to
>   froot :: MutableByteArray# RealWorld
>   fwk :: MutVar# RealWorld Any -- The finalizers
>   }
>
> froot represents the object the ForeignPtr points into. When created by
> one of the malloc variants, this will actually be the allocated byte array.
> Otherwise, it will be a 0-length array.
>
> fwk should be seen as having type
>
>   fwk :: MutVar# RealWorld (Weak# (MutableByteArray# RealWorld))
>
> but we can't express that directly right now. fwk is keyed on froot, and
> in the malloc case also points to it, to prevent it from being freed
> prematurely.
>
> It seems that this representation requires a couple extra primitive
> features from Weak#. I think that's okay: Weak# already has some primitive
> features designed to support ForeignPtr.
>
> 1. An operation to add a Haskell finalizer to a Weak#, similar to the one
> that adds a C finalizer.
>
> 2. A way to deal with mixed finalizers: either make the finalizer-adding
> primops report distinguishable failure on mixing or arrange to run the C
> finalizers after any Haskell finalizers (since C finalizers are much more
> likely to actually invalidate the pointer).
>
> 3. A documented guarantee about the order in which the finalizers attached
> to a particular Weak# run, compatible with the ForeignPtr documentation.
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ForeignPtr representation

2018-09-06 Thread David Feuer
I realized that the current representation is kind of balanced on a knife
edge, efficiency-wise. There's probably no way to make one thing faster
without slowing down another: there are just too many things a ForeignPtr
could be trying to represent.

On Thu, Sep 6, 2018, 3:15 AM Simon Marlow  wrote:

> Wouldn't this mean that unpacking a ForeignPtr is one word longer than it
> is now? That would have a big impact on ByteString.
>
> What do you think is redundant in the current representation?
>
> Cheers
> Simon
>
> On Wed, 5 Sep 2018 at 00:23, David Feuer  wrote:
>
>> I'm trying, and failing, to understand why ForeignPtr is defined the way
>> it is. It all seems rather complicated and redundant. I was thinking we
>> might want to switch to something simpler and more explicit, like this:
>>
>> data ForeignPtr a = ForeignPtr {
>>   fptr :: !(Ptr a) -- What we point to
>>   froot :: MutableByteArray# RealWorld
>>   fwk :: MutVar# RealWorld Any -- The finalizers
>>   }
>>
>> froot represents the object the ForeignPtr points into. When created by
>> one of the malloc variants, this will actually be the allocated byte array.
>> Otherwise, it will be a 0-length array.
>>
>> fwk should be seen as having type
>>
>>   fwk :: MutVar# RealWorld (Weak# (MutableByteArray# RealWorld))
>>
>> but we can't express that directly right now. fwk is keyed on froot, and
>> in the malloc case also points to it, to prevent it from being freed
>> prematurely.
>>
>> It seems that this representation requires a couple extra primitive
>> features from Weak#. I think that's okay: Weak# already has some primitive
>> features designed to support ForeignPtr.
>>
>> 1. An operation to add a Haskell finalizer to a Weak#, similar to the one
>> that adds a C finalizer.
>>
>> 2. A way to deal with mixed finalizers: either make the finalizer-adding
>> primops report distinguishable failure on mixing or arrange to run the C
>> finalizers after any Haskell finalizers (since C finalizers are much more
>> likely to actually invalidate the pointer).
>>
>> 3. A documented guarantee about the order in which the finalizers
>> attached to a particular Weak# run, compatible with the ForeignPtr
>> documentation.
>>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs