[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.