Use shared statics for the ArcInner for Arc<str, CStr>::default, and for Arc<[T]>::default where alignof(T) <= 16.
This commit is contained in:
parent
0b3ebb546f
commit
f27d1e114c
@ -910,19 +910,6 @@ fn from(s: &CStr) -> Rc<CStr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
|
||||||
#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")]
|
|
||||||
impl Default for Arc<CStr> {
|
|
||||||
/// Creates an empty CStr inside an Arc
|
|
||||||
///
|
|
||||||
/// This may or may not share an allocation with other Arcs.
|
|
||||||
#[inline]
|
|
||||||
fn default() -> Self {
|
|
||||||
let c_str: &CStr = Default::default();
|
|
||||||
Arc::from(c_str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")]
|
#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")]
|
||||||
impl Default for Rc<CStr> {
|
impl Default for Rc<CStr> {
|
||||||
|
@ -3308,7 +3308,32 @@ impl Default for Arc<str> {
|
|||||||
/// This may or may not share an allocation with other Arcs.
|
/// This may or may not share an allocation with other Arcs.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Arc::from("")
|
let arc: Arc<[u8]> = Default::default();
|
||||||
|
debug_assert!(core::str::from_utf8(&*arc).is_ok());
|
||||||
|
let (ptr, alloc) = Arc::into_inner_with_allocator(arc);
|
||||||
|
unsafe { Arc::from_ptr_in(ptr.as_ptr() as *mut ArcInner<str>, alloc) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
|
#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl Default for Arc<core::ffi::CStr> {
|
||||||
|
/// Creates an empty CStr inside an Arc
|
||||||
|
///
|
||||||
|
/// This may or may not share an allocation with other Arcs.
|
||||||
|
#[inline]
|
||||||
|
fn default() -> Self {
|
||||||
|
use core::ffi::CStr;
|
||||||
|
static STATIC_INNER_CSTR: ArcInner<[u8; 1]> = ArcInner {
|
||||||
|
strong: atomic::AtomicUsize::new(1),
|
||||||
|
weak: atomic::AtomicUsize::new(1),
|
||||||
|
data: [0],
|
||||||
|
};
|
||||||
|
let inner: NonNull<ArcInner<[u8]>> = NonNull::from(&STATIC_INNER_CSTR);
|
||||||
|
let inner: NonNull<ArcInner<CStr>> = NonNull::new(inner.as_ptr() as *mut ArcInner<CStr>).unwrap();
|
||||||
|
// `this` semantically is the Arc "owned" by the static, so make sure not to drop it.
|
||||||
|
let this: mem::ManuallyDrop<Arc<CStr>> = unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) };
|
||||||
|
(*this).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3320,6 +3345,31 @@ impl<T> Default for Arc<[T]> {
|
|||||||
/// This may or may not share an allocation with other Arcs.
|
/// This may or may not share an allocation with other Arcs.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let alignment_of_t: usize = mem::align_of::<T>();
|
||||||
|
// We only make statics for the lowest five alignments.
|
||||||
|
// Alignments greater than that will use dynamic allocation.
|
||||||
|
macro_rules! use_static_inner_for_alignments {
|
||||||
|
($($alignment:literal),*) => {
|
||||||
|
$(if alignment_of_t == $alignment {
|
||||||
|
// Note: this must be in a new scope because static and type names are unhygenic.
|
||||||
|
#[repr(align($alignment))]
|
||||||
|
struct Aligned;
|
||||||
|
static ALIGNED_STATIC_INNER: ArcInner<Aligned> = ArcInner {
|
||||||
|
strong: atomic::AtomicUsize::new(1),
|
||||||
|
weak: atomic::AtomicUsize::new(1),
|
||||||
|
data: Aligned,
|
||||||
|
};
|
||||||
|
let inner: NonNull<ArcInner<Aligned>> = NonNull::from(&ALIGNED_STATIC_INNER);
|
||||||
|
let inner: NonNull<ArcInner<[T; 0]>> = inner.cast();
|
||||||
|
// `this` semantically is the Arc "owned" by the static, so make sure not to drop it.
|
||||||
|
let this: mem::ManuallyDrop<Arc<[T; 0]>> = unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) };
|
||||||
|
return (*this).clone();
|
||||||
|
})*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
use_static_inner_for_alignments!(1, 2, 4, 8, 16);
|
||||||
|
|
||||||
|
// If T's alignment is not one of the ones we have a static for, make a new unique allocation.
|
||||||
let arr: [T; 0] = [];
|
let arr: [T; 0] = [];
|
||||||
Arc::from(arr)
|
Arc::from(arr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user