Bug 1549596 - ThinArc should use NonNull. r=bholley
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 07 May 2019 03:16:21 +0000
changeset 534900 48edd877bde3ebbf5efc525eddad22099c0673ad
parent 534899 831798cef995ab1dfc196e4adf68aba337a2950a
child 534901 63d77dbcfda80e420a7e35c2b4244a7a67a5bef2
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1549596
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1549596 - ThinArc should use NonNull. r=bholley If only for parallelism with Arc<>. Differential Revision: https://phabricator.services.mozilla.com/D30131
servo/components/servo_arc/lib.rs
--- a/servo/components/servo_arc/lib.rs
+++ b/servo/components/servo_arc/lib.rs
@@ -16,17 +16,17 @@
 //! * We can add methods to support our custom use cases [1].
 //! * We have support for dynamically-sized types (see from_header_and_iter).
 //! * We have support for thin arcs to unsized types (see ThinArc).
 //! * We have support for references to static data, which don't do any
 //!   refcounting.
 //!
 //! [1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1360883
 
-// The semantics of `Arc` are alread documented in the Rust docs, so we don't
+// The semantics of `Arc` are already documented in the Rust docs, so we don't
 // duplicate those here.
 #![allow(missing_docs)]
 
 extern crate nodrop;
 #[cfg(feature = "servo")]
 extern crate serde;
 extern crate stable_deref_trait;
 
@@ -762,17 +762,17 @@ type HeaderSliceWithLength<H, T> = Heade
 /// alongside the `Arc`'s pointer. In some situations you may wish to
 /// have a thin pointer instead, perhaps for FFI compatibility
 /// or space efficiency.
 ///
 /// `ThinArc` solves this by storing the length in the allocation itself,
 /// via `HeaderSliceWithLength`.
 #[repr(C)]
 pub struct ThinArc<H, T> {
-    ptr: *mut ArcInner<HeaderSliceWithLength<H, [T; 1]>>,
+    ptr: ptr::NonNull<ArcInner<HeaderSliceWithLength<H, [T; 1]>>>,
 }
 
 unsafe impl<H: Sync + Send, T: Sync + Send> Send for ThinArc<H, T> {}
 unsafe impl<H: Sync + Send, T: Sync + Send> Sync for ThinArc<H, T> {}
 
 // Synthesize a fat pointer from a thin pointer.
 //
 // See the comment around the analogous operation in from_header_and_iter.
@@ -791,17 +791,17 @@ impl<H, T> ThinArc<H, T> {
     #[inline]
     pub fn with_arc<F, U>(&self, f: F) -> U
     where
         F: FnOnce(&Arc<HeaderSliceWithLength<H, [T]>>) -> U,
     {
         // Synthesize transient Arc, which never touches the refcount of the ArcInner.
         let transient = unsafe {
             NoDrop::new(Arc {
-                p: ptr::NonNull::new_unchecked(thin_to_thick(self.ptr)),
+                p: ptr::NonNull::new_unchecked(thin_to_thick(self.ptr.as_ptr())),
             })
         };
 
         // Expose the transient Arc to the callback, which may clone it if it wants.
         let result = f(&transient);
 
         // Forget the transient Arc to leave the refcount untouched.
         // XXXManishearth this can be removed when unions stabilize,
@@ -846,27 +846,27 @@ impl<H, T> ThinArc<H, T> {
     /// If this is a static ThinArc, this returns null.
     #[inline]
     pub fn heap_ptr(&self) -> *const c_void {
         let is_static =
             ThinArc::with_arc(self, |a| a.inner().count.load(Relaxed) == STATIC_REFCOUNT);
         if is_static {
             ptr::null()
         } else {
-            self.ptr as *const ArcInner<T> as *const c_void
+            self.ptr.as_ptr() as *const ArcInner<T> as *const c_void
         }
     }
 }
 
 impl<H, T> Deref for ThinArc<H, T> {
     type Target = HeaderSliceWithLength<H, [T]>;
 
     #[inline]
     fn deref(&self) -> &Self::Target {
-        unsafe { &(*thin_to_thick(self.ptr)).data }
+        unsafe { &(*thin_to_thick(self.ptr.as_ptr())).data }
     }
 }
 
 impl<H, T> Clone for ThinArc<H, T> {
     #[inline]
     fn clone(&self) -> Self {
         ThinArc::with_arc(self, |a| Arc::into_thin(a.clone()))
     }
@@ -888,25 +888,27 @@ impl<H, T> Arc<HeaderSliceWithLength<H, 
             a.header.length,
             a.slice.len(),
             "Length needs to be correct for ThinArc to work"
         );
         let fat_ptr: *mut ArcInner<HeaderSliceWithLength<H, [T]>> = a.ptr();
         mem::forget(a);
         let thin_ptr = fat_ptr as *mut [usize] as *mut usize;
         ThinArc {
-            ptr: thin_ptr as *mut ArcInner<HeaderSliceWithLength<H, [T; 1]>>,
+            ptr: unsafe {
+                ptr::NonNull::new_unchecked(thin_ptr as *mut ArcInner<HeaderSliceWithLength<H, [T; 1]>>)
+            },
         }
     }
 
     /// Converts a `ThinArc` into an `Arc`. This consumes the `ThinArc`, so the refcount
     /// is not modified.
     #[inline]
     pub fn from_thin(a: ThinArc<H, T>) -> Self {
-        let ptr = thin_to_thick(a.ptr);
+        let ptr = thin_to_thick(a.ptr.as_ptr());
         mem::forget(a);
         unsafe {
             Arc {
                 p: ptr::NonNull::new_unchecked(ptr),
             }
         }
     }
 }