[MLton-user] Weak pointer regression test 2
Matthew Fluet
matthew.fluet at gmail.com
Fri Apr 15 09:05:33 PDT 2011
On Fri, Apr 15, 2011 at 7:06 AM, Ivan Tomac <ivan.tomac at gmail.com> wrote:
> On Fri, Apr 15, 2011 at 4:12 AM, Matthew Fluet <matthew.fluet at gmail.com>
> wrote:
>>
>> On Thu, Apr 14, 2011 at 10:03 AM, Ivan Tomac <ivan.tomac at gmail.com> wrote:
>> > Why does the following code (taken from regression/weak.2.sml) return
>> > true,
>> > and more importantly why is it supposed to return true (according to the
>> > expected test result in weak.2.ok):
>> >
>> > structure Weak = MLton.Weak
>> >
>> > val x = (13, ref 5)
>> > val wx = Weak.new x
>> > fun isAlive () = isSome (Weak.get wx)
>> > val _ = MLton.GC.collect ()
>> > val _ = print (Bool.toString (isAlive ()) ^ "\n")
>> >
>> > Shouldn't x be garbage collected?
>>
>> In this program, the object bound to x can be made global (with only
>> constant space overhead), and hence it is reachable throughout the
>> lifetime of the whole program. This is a space/time tradeoff ---
>> making such small objects global may waste a little space (because
>> they are not garbage collected), but can be efficiently accessed
>> through their global name (rather than threading their pointers
>> through the program in variables and closures).
>>
>
> Thanks for the clarification. So if I'm understanding that right, in this
> instance x is still allocated on the heap but available throughout the
> lifetime of the program?
Correct. At program startup, all of the global objects are allocated
(in the heap) and all globals are considered roots for all garbage
collections during the run of the program.
>> Two slight variations on the program will prevent x from being
>> globalized and lead to the object being garbage collected.
>>
>> One: make the object bound to x a "large" (technically, not manifestly
>> small) object:
...
>>
>> Two: bind a (mutable) object to x more than once:
...
>>
>> Both of these programs will print "false".
>>
>
> Interesting. Would you know by any chance if there is a document somewhere
> mentioning what structures and cases does MLton optimize so that they're
> either globalized or not allocated on the heap in first place?
I don't think it is documented anywhere. Indeed, I needed to look at
the intermediate representations of the weak.2.sml program to
determine that it was going on.
> I'm a bit confused about just when is it safe to attach a weak pointer to
> something. For the purpose of finalizing things allocated in a foreign
> library, what kind of a data structure would I have to wrap the allocated
> resource in, so that when a weak pointer is attached I have a reliable way
> of telling when the structure is no longer reachable?
Well, the MLton.Finalizable structure is supposed to provide exactly
those guarantees. It uses MLton.Weak under the hood, but in such a
way that the object is not globalized. See
http://www.mlton.org/MLtonFinalizable for an example.
Indeed, one of the most common "mistakes" made with weak pointers is
trying to make a "Word32.word MLton.Weak.t" object and believe that it
can be used to free a C-side allocated resource; this doesn't work
because the Word32.word is not a heap allocated object (in MLton), and
so is considered always nulled.
More information about the MLton-user
mailing list