Repository navigation
Improve native GC lifetimes and member resolution - #227
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #227 +/- ##
==========================================
+ Coverage 87.78% 87.79% +0.01%
==========================================
Files 311 311
Lines 47092 47155 +63
==========================================
+ Hits 41338 41401 +63
Misses 5754 5754 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🔵 Needs a closer look
It reworks core GC reachability, monitor concurrency, and synchronized-method execution ordering—high-risk areas where subtle lifetime or race regressions warrant final human review despite passing tests.
No open issues 🎉
What changed in this PR
This PR hardens the native JVM's garbage collector against collecting host-visible references and tightens member resolution. On the GC side it adds a consumer-provided ExternalRoots trait plus scoped NativeFrame guards so that host references, synchronized-method arguments/results, and active monitor objects stay rooted across suspension points; reachability is now tracked by object identity (fixing cyclic-reference handling) and collection failures surface through anyhow::Result instead of panicking, with Java System.gc()/Runtime.gc() translating failures to InternalError. On the resolution side, field/method lookup now tries the caller's requested static/instance kind first while preserving JVMS declaring-class order and incompatible-kind errors.
Changes:
- GC roots now include
ExternalRoots, active monitors (Monitor::is_active), andNativeFrame-scoped host references;collect_garbage/determine_garbagereturnanyhow::Resultand key reachability onClassInstance::identity(). - Synchronized-method execution acquires the monitor after pushing the Java frame and uses
pop_frame_with_result, keeping arguments/results rooted while waiting for the monitor;MonitorWaittracksactive_waitsand releases it onDrop. resolve_field/resolve_methodgained anexpected_staticpreference; broad test/fixture additions cover external roots, frame lifetimes, cycles, and GC during monitor operations.
| File | Description |
|---|---|
| jvm/src/external_roots.rs | New ExternalRoots trait for consumer-provided root discovery. |
| jvm/src/jvm.rs | NativeFrame guard, native_frame/pop_frame_with_result, external-root + monitor rooting, expected_static resolution, reordered synchronized-method flow. |
| jvm/src/garbage_collector.rs | Identity-based reachability and anyhow::Result error propagation instead of unwrap. |
| jvm/src/monitor.rs | active_waits counter, is_active, MonitorWait Drop, and &mut listener await. |
| jvm/src/lib.rs | Re-exports ExternalRoots and NativeFrame. |
| rustjava-runtime/src/classes/java/lang/{system,runtime}.rs | Translate GC failure to InternalError. |
| jvm/tests/test_garbage_collection.rs, jvm/tests/test_string.rs | New/updated GC tests (external roots, frames, monitors, cycles). |
| test-data/src/{MonitorSemantics,ThreadInterruption}.java | Add System.gc() to exercise collection during monitor operations. |
| test-utils/src/lib.rs, src/lib.rs, rustjava-runtime/tests/.../test_class.rs | Re-export get_bootstrap_class_loader and pass new Jvm::new argument. |
Review effort: Balanced
Garbage collection
ExternalRootstoJvm::new.push_native_frame(args)return a scopedNativeFrameguard that roots object arguments and releases local references on drop; remove manualJvm::pop_frame.anyhow::Resultwithout sweeping after root discovery or tracing fails; translate Java GC entry-point failures toInternalError.Member resolution
Verification
cargo fmt --allcargo clippy --workspace --all-targets --locked --offline -- -D warningscargo clippy --target wasm32-unknown-unknown --locked --offline -- -D warningscargo test --workspace --locked --offline --quiet: 581 passed, 2 ignored.