[MLton] share bug

Matthew Fluet fluet@cs.cornell.edu
Sun, 23 Apr 2006 23:09:50 -0400 (EDT)


> This time I even tested the patch, on the following example.
>
> --------------------------------------------------------------------------------
> val a = Array.tabulate (2, fn i => [[i], [i + 1]])
> (* Move everything into the old generation. *)
> val () = MLton.GC.collect ()
> (* Allocate a new object in the nursery. *)
> val list = [hd (hd (Array.sub (a, 0)))] :: Array.sub (a, 0)
> (* Share on the whole list, which should create an intergenerational pointer. *)
> val () = MLton.share list
> (* Check invariants. *)
> val () = MLton.GC.collect ()
> val () = print (concat ["size is = ", Int.toString (MLton.size list), "\n"])
> val () = Array.update (a, 0, list)
> val [[i], [j], [k]] = Array.sub (a, 0)
> val _ = i + j + k
> --------------------------------------------------------------------------------
>
> If you compile the above with -debug true, it will fail in an assert
> at the GC.collect.  With the patch below, it runs fine (the correct
> size for the list is 60, not 72, since part of it is shared).

I'm porting the share bug fix to x86_64 branch and was confirming the 
existence of the bug in revised runtime.  I know that raising the 
assertion requires a rebuilt runtime with FORCE_GENERATIONAL=TRUE.  I was 
trying to fake this by fooling with the ratios and max-heap runtime 
options.  I discovered that when running the program with
   @MLton max-heap 10K --
I get no assertion from the runtime, but I get an uncaught Bind exception. 
I observe the same behavior on HEAD before revision 4400, but not after.
I don't see an obvious connection between marking intergenerational 
pointers and the Bind exception, so I'm worried that there is another bug 
lurking around.  But, I'm willing to be convinced that the share fix 
explains the behavior.