From b4f45195e09e38c6deae8605c0f61eb0b534ff20 Mon Sep 17 00:00:00 2001
From: Kunshan Wang <wks1986@gmail.com>
Date: Tue, 24 Oct 2023 19:45:00 +0800
Subject: [PATCH] Expose `is_emergency_collection` to VM bindings (#997)

`is_emergency_collection` is useful during weak reference processing.
JVMs can choose not to retain referents of `SoftReference` during
emergency GC.

The `is_emergency_collection` function was moved from `Plan` to
`GlobalState` in
https://github.com/mmtk/mmtk-core/commit/57af17fbfd94ff0df2cd3b1e504abe299ce4f0ab.
After that, the `MMTK:state` field is private and inaccessible to VM
bindings. VM bindings that depend on the to-be-deprecated built-in
`ReferenceProcessor` still work because it is part of the `mmtk` crate,
and can `mmtk.state.is_emergency_collection`. However, VM bindings that
do weak reference processing on the VM side using the
`Scanning::process_weak_refs` API can no longer call that function. This
makes [this PR](https://github.com/mmtk/mmtk-jikesrvm/pull/150) unable
to merge. In the future, the OpenJDK binding will also need it when it
off-loads weak reference processing to the binding side.

This PR adds a public API function `MMTK::is_emergency_collection` which
can be called by the VM bindings.
---
 src/mmtk.rs | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/mmtk.rs b/src/mmtk.rs
index b5487addc0..12f3e77cba 100644
--- a/src/mmtk.rs
+++ b/src/mmtk.rs
@@ -272,6 +272,24 @@ impl<VM: VMBinding> MMTK<VM> {
         *self.state.gc_status.lock().unwrap() == GcStatus::GcProper
     }
 
+    /// Return true if the current GC is an emergency GC.
+    ///
+    /// An emergency GC happens when a normal GC cannot reclaim enough memory to satisfy allocation
+    /// requests.  Plans may do full-heap GC, defragmentation, etc. during emergency in order to
+    /// free up more memory.
+    ///
+    /// VM bindings can call this function during GC to check if the current GC is an emergency GC.
+    /// If it is, the VM binding is recommended to retain fewer objects than normal GCs, to the
+    /// extent allowed by the specification of the VM or langauge.  For example, the VM binding may
+    /// choose not to retain objects used for caching.  Specifically, for Java virtual machines,
+    /// that means not retaining referents of [`SoftReference`][java-soft-ref] which is primarily
+    /// designed for implementing memory-sensitive caches.
+    ///
+    /// [java-soft-ref]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ref/SoftReference.html
+    pub fn is_emergency_collection(&self) -> bool {
+        self.state.is_emergency_collection()
+    }
+
     /// The application code has requested a collection. This is just a GC hint, and
     /// we may ignore it.
     ///