MCPcopy Index your code
hub / github.com/RustPython/RustPython / promote_survivors

Method promote_survivors

crates/vm/src/gc_state.rs:745–783  ·  view source on GitHub ↗

Promote surviving objects to the next generation. `survivors` must be strong references (`PyObjectRef`) to keep objects alive, since the generation read locks are released before this is called. Holds both source and destination list locks simultaneously to prevent a race where concurrent `untrack_object` reads a stale `gc_generation` and operates on the wrong list.

(&self, from_gen: usize, survivors: &[PyObjectRef])

Source from the content-addressed store, hash-verified

743 /// a race where concurrent `untrack_object` reads a stale `gc_generation`
744 /// and operates on the wrong list.
745 fn promote_survivors(&self, from_gen: usize, survivors: &[PyObjectRef]) {
746 if from_gen >= 2 {
747 return; // Already in oldest generation
748 }
749
750 let next_gen = from_gen + 1;
751
752 for obj_ref in survivors {
753 let obj = obj_ref.as_ref();
754 let ptr = NonNull::from(obj);
755 let obj_gen = obj.gc_generation();
756 if obj_gen as usize <= from_gen && obj_gen <= 2 {
757 let src_gen = obj_gen as usize;
758
759 // Lock both source and destination lists simultaneously.
760 // Always ascending order (src_gen < next_gen) → no deadlock.
761 let mut src = self.generation_lists[src_gen].write();
762 let mut dst = self.generation_lists[next_gen].write();
763
764 // Re-check under locks: object might have been untracked concurrently
765 if obj.gc_generation() != obj_gen || !obj.is_gc_tracked() {
766 continue;
767 }
768
769 if unsafe { src.remove(ptr) }.is_some() {
770 self.generations[src_gen]
771 .count
772 .fetch_sub(1, Ordering::SeqCst);
773
774 dst.push_front(ptr);
775 self.generations[next_gen]
776 .count
777 .fetch_add(1, Ordering::SeqCst);
778
779 obj.set_gc_generation(next_gen as u8);
780 }
781 }
782 }
783 }
784
785 /// Get count of frozen objects
786 pub fn get_freeze_count(&self) -> usize {

Callers 1

collect_innerMethod · 0.80

Calls 7

gc_generationMethod · 0.80
is_gc_trackedMethod · 0.80
push_frontMethod · 0.80
set_gc_generationMethod · 0.80
as_refMethod · 0.45
writeMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected