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

Method new_ref

crates/vm/src/object/core.rs:2177–2225  ·  view source on GitHub ↗
(payload: T, typ: crate::builtins::PyTypeRef, dict: Option<PyDictRef>)

Source from the content-addressed store, hash-verified

2175impl<T: PyPayload + crate::object::MaybeTraverse + core::fmt::Debug> PyRef<T> {
2176 #[inline(always)]
2177 pub fn new_ref(payload: T, typ: crate::builtins::PyTypeRef, dict: Option<PyDictRef>) -> Self {
2178 let has_dict = dict.is_some();
2179 let is_heaptype = typ.heaptype_ext.is_some();
2180
2181 // Try to reuse from freelist (no dict, no heaptype)
2182 let cached = if !has_dict && !is_heaptype {
2183 unsafe { T::freelist_pop(&payload) }
2184 } else {
2185 None
2186 };
2187
2188 let ptr = if let Some(cached) = cached {
2189 let inner = cached.as_ptr() as *mut PyInner<T>;
2190 unsafe {
2191 core::ptr::write(&mut (*inner).ref_count, RefCount::new());
2192 (*inner).gc_bits.store(0, Ordering::Relaxed);
2193 core::ptr::drop_in_place(&mut (*inner).payload);
2194 core::ptr::write(&mut (*inner).payload, payload);
2195 // Freelist only stores exact base types (push-side filter),
2196 // but subtypes sharing the same Rust payload (e.g. structseq)
2197 // may pop entries. Update typ if it differs.
2198 let cached_typ: *const Py<PyType> = &*(*inner).typ;
2199 if core::ptr::eq(cached_typ, &*typ) {
2200 drop(typ);
2201 } else {
2202 let _old = (*inner).typ.swap(typ);
2203 }
2204 }
2205 unsafe { NonNull::new_unchecked(inner.cast::<Py<T>>()) }
2206 } else {
2207 let inner = PyInner::new(payload, typ, dict);
2208 unsafe { NonNull::new_unchecked(inner.cast::<Py<T>>()) }
2209 };
2210
2211 // Track object if:
2212 // - HAS_TRAVERSE is true (Rust payload implements Traverse), OR
2213 // - has instance dict (user-defined class instances), OR
2214 // - heap type (all heap type instances are GC-tracked, like Py_TPFLAGS_HAVE_GC)
2215 if <T as crate::object::MaybeTraverse>::HAS_TRAVERSE || has_dict || is_heaptype {
2216 let gc = crate::gc_state::gc_state();
2217 unsafe {
2218 gc.track_object(ptr.cast());
2219 }
2220 // Check if automatic GC should run
2221 gc.maybe_collect();
2222 }
2223
2224 Self { ptr }
2225 }
2226}
2227
2228impl<T: crate::class::PySubclass + core::fmt::Debug> PyRef<T>

Callers

nothing calls this directly

Calls 10

newFunction · 0.85
gc_stateFunction · 0.85
track_objectMethod · 0.80
maybe_collectMethod · 0.80
writeFunction · 0.50
eqFunction · 0.50
as_ptrMethod · 0.45
storeMethod · 0.45
swapMethod · 0.45
castMethod · 0.45

Tested by

no test coverage detected