(payload: T, typ: crate::builtins::PyTypeRef, dict: Option<PyDictRef>)
| 2175 | impl<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 | |
| 2228 | impl<T: crate::class::PySubclass + core::fmt::Debug> PyRef<T> |
nothing calls this directly
no test coverage detected