Skip to content

Commit 4af5054

Browse files
committed
liballoc: Use NonZero in Arc.
1 parent 0d48f76 commit 4af5054

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/liballoc/arc.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ use core::mem;
7979
use core::ops::{Drop, Deref};
8080
use core::option::Option;
8181
use core::option::Option::{Some, None};
82-
use core::ptr::RawPtr;
83-
use core::ptr;
82+
use core::ptr::{mod, NonZero, RawPtr};
8483
use heap::deallocate;
8584

8685
/// An atomically reference counted wrapper for shared state.
@@ -114,7 +113,7 @@ use heap::deallocate;
114113
pub struct Arc<T> {
115114
// FIXME #12808: strange name to try to avoid interfering with
116115
// field accesses of the contained type via Deref
117-
_ptr: *mut ArcInner<T>,
116+
_ptr: NonZero<*mut ArcInner<T>>,
118117
}
119118

120119
unsafe impl<T: Sync + Send> Send for Arc<T> { }
@@ -130,7 +129,7 @@ unsafe impl<T: Sync + Send> Sync for Arc<T> { }
130129
pub struct Weak<T> {
131130
// FIXME #12808: strange name to try to avoid interfering with
132131
// field accesses of the contained type via Deref
133-
_ptr: *mut ArcInner<T>,
132+
_ptr: NonZero<*mut ArcInner<T>>,
134133
}
135134

136135
unsafe impl<T: Sync + Send> Send for Weak<T> { }
@@ -165,7 +164,7 @@ impl<T> Arc<T> {
165164
weak: atomic::AtomicUint::new(1),
166165
data: data,
167166
};
168-
Arc { _ptr: unsafe { mem::transmute(x) } }
167+
Arc { _ptr: NonZero(unsafe { mem::transmute(x) }) }
169168
}
170169

171170
/// Downgrades the `Arc<T>` to a `Weak<T>` reference.
@@ -194,7 +193,8 @@ impl<T> Arc<T> {
194193
// pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
195194
// because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
196195
// to these contents.
197-
unsafe { &*self._ptr }
196+
let NonZero(ptr) = self._ptr;
197+
unsafe { &*ptr }
198198
}
199199
}
200200

@@ -281,7 +281,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
281281
// pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
282282
// this point, and we required the Arc itself to be `mut`, so we're returning the only
283283
// possible reference to the inner data.
284-
let inner = unsafe { &mut *self._ptr };
284+
let NonZero(ptr) = self._ptr;
285+
let inner = unsafe { &mut *ptr };
285286
&mut inner.data
286287
}
287288
}
@@ -316,7 +317,8 @@ impl<T: Sync + Send> Drop for Arc<T> {
316317
fn drop(&mut self) {
317318
// This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
318319
// it is guaranteed to be zeroed after the first if it's run more than once)
319-
if self._ptr.is_null() { return }
320+
let NonZero(ptr) = self._ptr;
321+
if ptr.is_null() { return }
320322

321323
// Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
322324
// unless we are going to delete the object. This same logic applies to the below
@@ -346,7 +348,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
346348

347349
if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
348350
atomic::fence(atomic::Acquire);
349-
unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
351+
unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
350352
min_align_of::<ArcInner<T>>()) }
351353
}
352354
}
@@ -386,7 +388,8 @@ impl<T: Sync + Send> Weak<T> {
386388
#[inline]
387389
fn inner(&self) -> &ArcInner<T> {
388390
// See comments above for why this is "safe"
389-
unsafe { &*self._ptr }
391+
let NonZero(ptr) = self._ptr;
392+
unsafe { &*ptr }
390393
}
391394
}
392395

@@ -442,14 +445,16 @@ impl<T: Sync + Send> Drop for Weak<T> {
442445
/// } // implicit drop
443446
/// ```
444447
fn drop(&mut self) {
448+
let NonZero(ptr) = self._ptr;
449+
445450
// see comments above for why this check is here
446-
if self._ptr.is_null() { return }
451+
if ptr.is_null() { return }
447452

448453
// If we find out that we were the last weak pointer, then its time to deallocate the data
449454
// entirely. See the discussion in Arc::drop() about the memory orderings
450455
if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
451456
atomic::fence(atomic::Acquire);
452-
unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
457+
unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
453458
min_align_of::<ArcInner<T>>()) }
454459
}
455460
}

0 commit comments

Comments
 (0)