Weak reference semantics - why does a dead weak ref keep its value alive?

Simon Marlow marlowsd at gmail.com
Tue May 27 08:29:08 UTC 2014


On 24/05/2014 01:11, Luite Stegeman wrote:
>
>     In particular, the variant of weak reference you suggest is the
>     /ephemeron/ semantics in Hayes.  Their reachability rule is:
>
>          The value field of an ephemeron is reachable if both (a) the
>          ephemeron (weak pointer object) is reachable, and (b) the key is
>          reachable.
>
>
> Actually it's not the same, since I think the finalizer should still be
> run if the weak pointer object is unreachable (and it should run when
> the key becomes unreachable).
>
> The implementation would indeed need to keep some reference to the key
> and finalizer around after the weak pointer becomes unreachable, perhaps
> on some weak pointers list, but the same goes for GHC's semantics. The
> only difference is that the value (which might in turn make a whole
> bunch of other data reachable) would not have to be retained.
>
> I haven't been able to think of any issues with considering the value
> unreachable here, so I'm still puzzled as to why GHC's semantics would
> be preferable. It doesn't look like it would complicate implementation
> too much either.

So the semantics is currently:

   w <- mkWeak k v f

  1. v is reachable if k is reachable
  2. f is reachable if k is reachable
  3. when k is unreachable, the finalizer f is run
  4. deRefWeak w returns
     - Nothing, if k is not reachable
     - Just v, otherwise

In your proposal I think you would change the first one to

  1. v is reachable if both k and w are reachable

Arguably this makes sense, because as you say, v is accessed via w, and 
what's the point of making v reachable if you can't access it? It's just 
a space leak.

My only worry is how hard this is to implement.  Rather than considering 
w as unconditionally reachable (which is what we do now), you would have 
to track its reachability, and only consider v reachable when both k and 
w are reachable.  A weak pointer object where only k was reachable would 
probably need to be put in a semi-dead (zombie?) state, so that we would 
still run the finalizer when k becomes unreachable.  I suspect all this 
might be more complicated to implement, but maybe there's a simpler way 
that I'm missing.

Cheers,
Simon


More information about the ghc-devs mailing list