mmtk / mmtk-julia

Julia binding for MMTk
13 stars 9 forks source link

'Called is_live() on 0, which maps to an empty space' in weak ref processing #176

Open qinsoon opened 2 months ago

qinsoon commented 2 months ago

Saw the following error in https://github.com/mmtk/mmtk-julia/pull/175.

thread 'MMTk Worker' panicked at 'Called is_live() on 0, which maps to an empty space', /home/runner/.cargo/git/checkouts/mmtk-core-3306bdeb8eb4322b/73be50d/src/policy/sft.rs:127:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/panicking.rs:67:14
   2: <mmtk::policy::sft::EmptySpaceSFT as mmtk::policy::sft::SFT>::is_live
   3: clear_weak_refs
             at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/src/mmtk-gc.c:145:22
   4: <mmtk_julia::scanning::ScanFinalizersSingleThreaded<C> as mmtk::scheduler::work::GCWork<mmtk_julia::JuliaVM>>::do_work
   5: mmtk::scheduler::worker::GCWorker<VM>::run
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
qinsoon commented 1 month ago

There are two issues here:

  1. Julia weak refs are stored in a thread-local array list. The weak refs may get copied, and the array list is not updated and they still include the old references.
  2. The values that weak refs refer to may get removed. We are not dealing with object forwarding in our weak ref processing. See clear_weak_refs in mmtk-gc.c.

The simple solution is to pin both: the weak ref, and the value they refer to. See https://github.com/mmtk/julia/pull/64/commits/51ba2a602e798e82f48c5d9004520c3fe68645b3.

k-sareen commented 1 month ago

There are many such instances in ART and the solution they have/I have co-opted is to visit these locations at the end of the transitive closure but before the "release" and fixup all pointers since we have complete information at that time. I use the mmtk_get_forwarded_object API to get the new address. The problem in Julia, of course, might be that it's unclear which locations are actually storing pointers.