aboutsummaryrefslogtreecommitdiffstats
path: root/components/servo_arc/lib.rs
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-07-06 18:16:30 +0200
committerSimon Sapin <simon.sapin@exyr.org>2019-07-16 08:03:54 +0200
commit17ec774a49e37f39bd50334e88a1d5937f3d24b1 (patch)
treec61423544c447e415f0c3249fe7e394a658917e3 /components/servo_arc/lib.rs
parent00b3fb49c42127aa93b3aa29501d2f4a26451e67 (diff)
downloadservo-17ec774a49e37f39bd50334e88a1d5937f3d24b1.tar.gz
servo-17ec774a49e37f39bd50334e88a1d5937f3d24b1.zip
Stylo: replace uses of mem::uninitialized with MaybeUninit
MozReview-Commit-ID: KGhYL6DJRaR
Diffstat (limited to 'components/servo_arc/lib.rs')
-rw-r--r--components/servo_arc/lib.rs29
1 files changed, 9 insertions, 20 deletions
diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs
index 089aa60f031..6e86ea7b5f3 100644
--- a/components/servo_arc/lib.rs
+++ b/components/servo_arc/lib.rs
@@ -52,25 +52,6 @@ use std::sync::atomic;
use std::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use std::{isize, usize};
-// Private macro to get the offset of a struct field in bytes from the address of the struct.
-macro_rules! offset_of {
- ($container:path, $field:ident) => {{
- // Make sure the field actually exists. This line ensures that a compile-time error is
- // generated if $field is accessed through a Deref impl.
- let $container { $field: _, .. };
-
- // Create an (invalid) instance of the container and calculate the offset to its
- // field. Using a null pointer might be UB if `&(*(0 as *const T)).field` is interpreted to
- // be nullptr deref.
- let invalid: $container = ::std::mem::uninitialized();
- let offset = &invalid.$field as *const _ as usize - &invalid as *const _ as usize;
-
- // Do not run destructors on the made up invalid instance.
- ::std::mem::forget(invalid);
- offset as isize
- }};
-}
-
/// A soft limit on the amount of references that may be made to an `Arc`.
///
/// Going above this limit will abort your program (although not
@@ -196,6 +177,14 @@ struct ArcInner<T: ?Sized> {
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
+/// Computes the offset of the data field within ArcInner.
+fn data_offset<T>() -> usize {
+ let size = size_of::<ArcInner<()>>();
+ let align = align_of::<T>();
+ // https://github.com/rust-lang/rust/blob/1.36.0/src/libcore/alloc.rs#L187-L207
+ size.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1)
+}
+
impl<T> Arc<T> {
/// Construct an `Arc<T>`
#[inline]
@@ -251,7 +240,7 @@ impl<T> Arc<T> {
unsafe fn from_raw(ptr: *const T) -> Self {
// To find the corresponding pointer to the `ArcInner` we need
// to subtract the offset of the `data` field from the pointer.
- let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner<T>, data));
+ let ptr = (ptr as *const u8).sub(data_offset::<T>());
Arc {
p: ptr::NonNull::new_unchecked(ptr as *mut ArcInner<T>),
phantom: PhantomData,