wenyuzhao / mmtk-core

Memory Management ToolKit

Home Page:https://www.mmtk.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Eclipse crash on small heap during mature evacuation

wenyuzhao opened this issue · comments

RUST_BACKTRACE=1 MMTK_PLAN=LXR  /usr/local/google/home/wenyuzhao/mmtk-dev/openjdk/build/linux-x86_64-normal-server-fastdebug/jdk/bin/java  -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-InlineObjectCopy -XX:-UseBiasedLocking -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UseThirdPartyHeap -Xms534M -Xmx534M  --add-exports java.base/jdk.internal.ref=ALL-UNNAMED -cp ~/dacapo/dacapo-evaluation-git-b00bfa9.jar Harness -n 5  eclipse 
MMTk Compressed Pointers: disabled
Enable 47-bit address space
VMLayoutConstants: 64bit
Workers: 24
-------------------- Immix Args --------------------
 * barrier: "FieldBarrier"
 * barrier_measurement: false
 * instrumentation: false
 * ix_block_only: false
 * ix_no_defrag: false
 * ix_ref_count: false
 * lxr_evacuate_nursery_in_recycled_lines: false
 * lxr_delayed_nursery_evacuation: false
 * lxr_enable_initial_alloc_limit: false
 * ignore_reusing_blocks: true
 * log_block_size: 15
 * log_line_size: 8
 * log_bytes_per_rc_lock_bit: 9
 * lxr_rc_only: false
 * buffer_size: 1024
 * nontemporal: false
 * cm_large_array_optimization: false
 * inc_max_copy_depth: false
 * no_finalizer: false
 * no_reference_types: false

RuntimeArgs {
    incs_limit: None,
    blocks_limit: None,
    no_mutator_line_recycling: false,
    lock_free_blocks: 24,
    nursery_blocks: None,
    nursery_ratio: None,
    lower_concurrent_worker_priority: false,
    concurrent_worker_ratio: 50,
    max_mature_defrag_percent: 15,
    max_pause_millis: None,
    max_copy_size: 512,
    concurrent_marking_stop_blocks: 128,
    max_survival_mb: Some(
        128,
    ),
    survival_predictor_harmonic_mean: false,
    survival_predictor_weighted: true,
    trace_threshold: 20,
    min_reuse_lines: 1,
    no_recursive_dec: false,
}
----------------------------------------------------
start: 0x20000000000, end: 0x200000000000
FieldBarrier
ClassUnloading Enabled
--------------------------------------------------------------------------------
...
thread '<unnamed>' panicked at 'assertion failed: object.is_in_any_space()', /usr/local/google/home/wenyuzhao/mmtk-dev/./mmtk-core/src/plan/lxr/cm.rs:322:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:143:14
   2: core::panicking::panic
             at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:48:5
   3: <mmtk::plan::lxr::cm::LXRStopTheWorldProcessEdges<VM,_> as mmtk::scheduler::gc_work::ProcessEdgesWork>::trace_object
             at ./mmtk-core/src/plan/lxr/cm.rs:322:9
   4: <mmtk::plan::lxr::cm::LXRStopTheWorldProcessEdges<VM,_> as mmtk::scheduler::gc_work::ProcessEdgesWork>::process_edge
             at ./mmtk-core/src/plan/lxr/cm.rs:372:26
   5: <mmtk::plan::lxr::cm::LXRStopTheWorldProcessEdges<VM,_> as mmtk::scheduler::gc_work::ProcessEdgesWork>::process_edges
             at ./mmtk-core/src/plan/lxr/cm.rs:357:17
   6: mmtk::scheduler::gc_work::<impl mmtk::scheduler::work::GCWork<<E as mmtk::scheduler::gc_work::ProcessEdgesWork>::VM> for E>::do_work
             at ./mmtk-core/src/scheduler/gc_work.rs:583:13
   7: mmtk::scheduler::work::GCWork::do_work_with_stat
             at ./mmtk-core/src/scheduler/work.rs:55:9
   8: mmtk::scheduler::worker::GCWorker<VM>::run
             at ./mmtk-core/src/scheduler/worker.rs:242:13
   9: mmtk::memory_manager::start_worker
             at ./mmtk-core/src/memory_manager.rs:484:5
  10: start_worker
             at ./mmtk-openjdk/mmtk/src/api.rs:189:5
  11: _ZN6Thread8call_runEv
             at ./openjdk/src/hotspot/share/runtime/thread.cpp:402:12
  12: thread_native_entry
             at ./openjdk/src/hotspot/os/linux/os_linux.cpp:799:19
  13: start_thread
             at ./nptl/./nptl/pthread_create.c:442:8
  14: __GI___clone3
             at ./misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Traceback (most recent call last):
  File "/usr/local/google/home/wenyuzhao/mmtk-dev/run-jdk.py", line 267, in <module>
    main()
  File "/usr/local/google/home/wenyuzhao/mmtk-dev/run-jdk.py", line 261, in main
    run(build_args, run_args)
  File "/usr/local/google/home/wenyuzhao/mmtk-dev/run-jdk.py", line 221, in run

Looks like this happens at the second iteration, in final mark pause when LXR is doing mature evacuation.

LXR mature evacuation remset is a list of remembered field slots (or field locations / addresses). This remset is constructed during concurrent marking.

Multiple RC pauses can happen during CM. RC pauses can kill dead mature objects and reuse the memory during CM -- which makes the remset entry invalidated. Some remset entry can point to arbitrary data instead of a valid heap object.

LXR already has a pass to filter out invalid entries before mature evacuation.

However, during mature evacuation, the copy allocator can also reuse lines, and thus invalidate more entries.

The current solution is to filter out invalid remset entries again before forwarding.

Potential data race issue: One GC thread can invalidate an entry when another thread is updating the pointer after forwarding. The pointer update part should be atomic compare and swap, so that the store operation can be cancelled if the entry is already overwritten.

Note: The current solution relies on conservative reference validity check and is not sound