Skip to content

Commit e27e488

Browse files
committed
Reset in-defrag state in end-of-gc
1 parent a4401ce commit e27e488

File tree

6 files changed

+30
-18
lines changed

6 files changed

+30
-18
lines changed

src/plan/generational/immix/global.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,7 @@ impl<VM: VMBinding> Plan for GenImmix<VM> {
137137
let full_heap = !self.gen.is_current_gc_nursery();
138138
self.gen.release(tls);
139139
if full_heap {
140-
let did_defrag = self.immix_space.release(full_heap);
141-
self.last_gc_was_defrag.store(did_defrag, Ordering::Relaxed);
142-
} else {
143-
self.last_gc_was_defrag.store(false, Ordering::Relaxed);
140+
self.immix_space.release(full_heap);
144141
}
145142
self.last_gc_was_full_heap
146143
.store(full_heap, Ordering::Relaxed);
@@ -149,6 +146,9 @@ impl<VM: VMBinding> Plan for GenImmix<VM> {
149146
fn end_of_gc(&mut self, _tls: VMWorkerThread) {
150147
self.gen
151148
.set_next_gc_full_heap(CommonGenPlan::should_next_gc_be_full_heap(self));
149+
150+
let did_defrag = self.immix_space.end_of_gc();
151+
self.last_gc_was_defrag.store(did_defrag, Ordering::Relaxed);
152152
}
153153

154154
fn current_gc_may_move_object(&self) -> bool {

src/plan/global.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ pub trait Plan: 'static + HasSpaces + Sync + Downcast {
302302
/// Return whether the current GC may move any object. The VM binding can make use of this
303303
/// information and choose to or not to update some data structures that record the addresses
304304
/// of objects.
305+
///
306+
/// This function is callable during a GC. From the VM binding's point of view, the information
307+
/// of whether the current GC is a defrag GC is available since `Collection::stop_mutators` is
308+
/// called, and remains available until `resume_mutators`.
305309
fn current_gc_may_move_object(&self) -> bool;
306310

307311
/// An object is firstly reached by a sanity GC. So the object is reachable

src/plan/immix/global.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ impl<VM: VMBinding> Plan for Immix<VM> {
9393
fn release(&mut self, tls: VMWorkerThread) {
9494
self.common.release(tls, true);
9595
// release the collected region
96+
self.immix_space.release(true);
97+
}
98+
99+
fn end_of_gc(&mut self, _tls: VMWorkerThread) {
96100
self.last_gc_was_defrag
97-
.store(self.immix_space.release(true), Ordering::Relaxed);
101+
.store(self.immix_space.end_of_gc(), Ordering::Relaxed);
98102
}
99103

100104
fn current_gc_may_move_object(&self) -> bool {

src/plan/sticky/immix/global.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ impl<VM: VMBinding> Plan for StickyImmix<VM> {
126126

127127
fn release(&mut self, tls: crate::util::VMWorkerThread) {
128128
if self.is_current_gc_nursery() {
129-
let was_defrag = self.immix.immix_space.release(false);
130-
self.immix
131-
.set_last_gc_was_defrag(was_defrag, Ordering::Relaxed);
132129
self.immix.common.los.release(false);
133130
} else {
134131
self.immix.release(tls);
@@ -140,6 +137,10 @@ impl<VM: VMBinding> Plan for StickyImmix<VM> {
140137
crate::plan::generational::global::CommonGenPlan::should_next_gc_be_full_heap(self);
141138
self.next_gc_full_heap
142139
.store(next_gc_full_heap, Ordering::Relaxed);
140+
141+
let was_defrag = self.immix.immix_space.end_of_gc();
142+
self.immix
143+
.set_last_gc_was_defrag(was_defrag, Ordering::Relaxed);
143144
}
144145

145146
fn collection_required(&self, space_full: bool, space: Option<SpaceStats<Self::VM>>) -> bool {

src/policy/immix/defrag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,9 @@ impl Defrag {
205205
.store(threshold, Ordering::Release);
206206
}
207207

208-
/// Release work. Should be called in ImmixSpace::release.
208+
/// Reset the in-defrag state.
209209
#[allow(clippy::assertions_on_constants)]
210-
pub fn release<VM: VMBinding>(&self, _space: &ImmixSpace<VM>) {
210+
pub fn reset_in_defrag(&self) {
211211
debug_assert!(super::DEFRAG);
212212
self.in_defrag_collection.store(false, Ordering::Release);
213213
}

src/policy/immix/immixspace.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -440,12 +440,10 @@ impl<VM: VMBinding> ImmixSpace<VM> {
440440
}
441441
}
442442

443-
/// Release for the immix space. This is called when a GC finished.
444-
/// Return whether this GC was a defrag GC, as a plan may want to know this.
445-
pub fn release(&mut self, major_gc: bool) -> bool {
446-
let did_defrag = self.defrag.in_defrag();
443+
/// Release for the immix space.
444+
pub fn release(&mut self, major_gc: bool) {
447445
if major_gc {
448-
// Update line_unavail_state for hole searching afte this GC.
446+
// Update line_unavail_state for hole searching after this GC.
449447
if !super::BLOCK_ONLY {
450448
self.line_unavail_state.store(
451449
self.line_mark_state.load(Ordering::Acquire),
@@ -460,12 +458,17 @@ impl<VM: VMBinding> ImmixSpace<VM> {
460458
// Sweep chunks and blocks
461459
let work_packets = self.generate_sweep_tasks();
462460
self.scheduler().work_buckets[WorkBucketStage::Release].bulk_add(work_packets);
463-
if super::DEFRAG {
464-
self.defrag.release(self);
465-
}
466461

467462
self.lines_consumed.store(0, Ordering::Relaxed);
463+
}
468464

465+
/// This is called when a GC finished.
466+
/// Return whether this GC was a defrag GC, as a plan may want to know this.
467+
pub fn end_of_gc(&mut self) -> bool {
468+
let did_defrag = self.defrag.in_defrag();
469+
if super::DEFRAG {
470+
self.defrag.reset_in_defrag();
471+
}
469472
did_defrag
470473
}
471474

0 commit comments

Comments
 (0)