1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use {
crate::AsMutPtr,
std::{mem::ManuallyDrop, ops::Deref, ptr, sync::Arc},
};
/// Inlining optimization for `Arc`.
#[derive(Debug)]
pub enum MaybeArc<T> {
Inline(T),
Shared(Arc<T>),
}
impl<T> MaybeArc<T> {
/// `Arc::clone` in place.
// TODO(2.3.1) this whole function is dodgy, Miri correction needed
pub fn refclone(&mut self) -> Self {
let arc = match self {
Self::Inline(mx) => {
let x = unsafe {
// SAFETY: generally a no-op from a safety perspective; the ManuallyDrop ensures
// that it stays that way in the event of a panic in Arc::new
ptr::read(mx.as_mut_ptr().cast::<ManuallyDrop<T>>())
};
let arc = Arc::new(x);
// BEGIN no-panic zone
let arc = unsafe {
// SAFETY: ManuallyDrop is layout-transparent
Arc::from_raw(Arc::into_raw(arc).cast::<T>())
};
unsafe {
// SAFETY: self, being a mutable reference, is valid for writes
ptr::write(self, Self::Shared(arc));
}
// END no-panic zone, the danger has passed
let ref_for_clone = match self {
Self::Shared(s) => &*s,
Self::Inline(..) => unreachable!(),
};
Arc::clone(ref_for_clone)
}
Self::Shared(arc) => Arc::clone(arc),
};
Self::Shared(arc)
}
pub fn try_make_owned(&mut self) -> bool {
if let Self::Shared(am) = self {
let a = unsafe { ptr::read(am) };
if let Ok(x) = Arc::try_unwrap(a) {
unsafe {
ptr::write(self, Self::Inline(x));
}
true
} else {
false
}
} else {
true
}
}
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
match this {
Self::Inline(..) => false,
Self::Shared(a) => match other {
Self::Inline(..) => false,
Self::Shared(b) => Arc::ptr_eq(a, b),
},
}
}
}
impl<T> Deref for MaybeArc<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
match self {
Self::Inline(x) => x,
Self::Shared(a) => a,
}
}
}
impl<T> From<T> for MaybeArc<T> {
#[inline]
fn from(x: T) -> Self { Self::Inline(x) }
}
impl<T> From<Arc<T>> for MaybeArc<T> {
#[inline]
fn from(a: Arc<T>) -> Self { Self::Shared(a) }
}