-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow querying if the current GC may move objects. #1128
Conversation
This feature already exists as Lines 568 to 571 in 1b9cfe4
If you want it to be specific to current GC, you could edit the |
The key is that the VM does not want to iterate through the list of PPP children or entries in weak tables and inspect if each of them may move. If it knows the current GC will not move any object (actually it is more likely for a GC to be non-moving than moving for Immix because only defrag GC moves object, and also true for StickyImmix with non-moving nursery GC), it can skip all PPPs and skip all existing entries in the weak table except the newly added ones. |
I think the PR is generally okay. But there are a few things we need to get it clear.
The 3rd issue is not introduced by this PR, so it does not need to be addressed in this PR. But I hope we can have some ideas about how to improve this before merging the PR. 1. In theory, we just need to define a constant |
I mean technically |
Only |
Yes. I meant that a binding can't even rely on |
This method should be callable from /// Check if the current GC is a defrag GC.
pub fn in_defrag(&self) -> bool { So its scope should be "the current GC", not "if the GC is currently in the phase of defragmenting the heap". Other per-GC information should be cleared at the end of GC. I am actually considering introducing a data structure about "the current GC", and it should include fields like "is the current GC nursery", "is the current GC moving", "is the current GC xxxxxx", etc. That may be part of Strangely,
Actually And the newly introduced
Those serve different purposes.
And the newly introduced mechanism:
I think they serve distinct purposes, and cannot replace each other. For example, the VM must determine the object layout before doing GC, so But it is worth thinking whether it is cheaper to blindly set the pinning bit or checking if an object never moves (because it is in the LOS or the GC is non-moving), or add the object to a set of pinning roots using some kind of scope pinning mechanism like C#'s
This assumes each GC has one trace. I think that's reasonable for all the GCs we currently know. MarkCompact computes two transitive closures in one GC, and we may consider it as a special case. Then the return value of But what about reference-counting-based plans that are not based on tracing? Maybe we just call it
I think
|
946d1fe
to
e27e488
Compare
src/plan/global.rs
Outdated
/// of objects. | ||
/// | ||
/// This function is callable during a GC. From the VM binding's point of view, the information | ||
/// of whether the current GC is a defrag GC is available since `Collection::stop_mutators` is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioning defrag could be confusing here.
/// of whether the current GC is a defrag GC is available since `Collection::stop_mutators` is | |
/// of whether the current GC moves object or not is available since `Collection::stop_mutators` is |
@@ -126,9 +126,6 @@ impl<VM: VMBinding> Plan for StickyImmix<VM> { | |||
|
|||
fn release(&mut self, tls: crate::util::VMWorkerThread) { | |||
if self.is_current_gc_nursery() { | |||
let was_defrag = self.immix.immix_space.release(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to call immix_space.release()
here, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. New objects can be allocated into the immix_space
and the LOS, and we still need to release them. I'll fix it.
src/plan/sticky/immix/global.rs
Outdated
@@ -158,6 +159,14 @@ impl<VM: VMBinding> Plan for StickyImmix<VM> { | |||
self.gc_full_heap.load(Ordering::Relaxed) && self.immix.last_collection_was_exhaustive() | |||
} | |||
|
|||
fn current_gc_may_move_object(&self) -> bool { | |||
if self.is_current_gc_nursery() { | |||
!cfg!(feature = "sticky_immix_non_moving_nursery") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be easier to understand and less error prone than directly checking the feature.
!cfg!(feature = "sticky_immix_non_moving_nursery") | |
crate::policy::immix_space::PREFER_COPY_ON_NURSERY_GC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The major changes include:
Plan::current_gc_may_move_object
.The main change of this PR is allowing querying if the current GC may move any object.
Whether a plan moves objects or not is not a simple "yes or no" question. It may vary in each GC.
The information of whether the current GC is useful inside mmtk-core. For example, we can skip clearing on-the-side forwarding bits in non-moving GCs because no objects will be forwarded. Because this should happen during the Release stage, we postponed the time for Immix-based plans to reset the in-defrag state to the end of GC so that
Plan::current_gc_may_move_object
remains callable during the Release stage. (Note that this PR does not fix #1118, but this mechanism introduced in this PR can be used to implement the clearing of side forwarding bits efficiently.)The information is also useful for VM bindings. Therefore,
Plan::current_gc_may_move_object
is part of the public API.This new method complements existing mechanisms for checking if objects can be moved. They are useful for different purposes and cannot replace each other.
Plan::current_gc_may_move_object
is one GC. It is useful for the VM to decide whether to pin PPPs objects before a GC and how to process weak references or weak tables.PlanConstraints::moves_objects
is a per-plan constant. It is useful for the VM to determine the object layout w.r.t. address-based hashing.ObjectReference::is_movable
is a single object. It is useful for the VM to skip pinning certain objects when interacting with native code.PlanTraceObject::may_move_object
is a trace. It is an internal mechanism for MMTk core to specialize work packets for different kinds of traces.