diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 8befb0579c3..8528be2860c 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -210,6 +210,21 @@ impl Arc { // contents. unsafe { &**self._ptr } } + + // Non-inlined part of `drop`. + #[inline(never)] + unsafe fn drop_slow(&mut self) { + let ptr = *self._ptr; + + // Destroy the data at this time, even though we may not free the box allocation itself + // (there may still be weak pointers lying around). + drop(ptr::read(&self.inner().data)); + + if self.inner().weak.fetch_sub(1, Release) == 1 { + atomic::fence(Acquire); + deallocate(ptr as *mut u8, size_of::>(), min_align_of::>()) + } + } } /// Get the number of weak references to this value. @@ -325,6 +340,7 @@ impl Drop for Arc { /// /// } // implicit drop /// ``` + #[inline] fn drop(&mut self) { // This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but // it is guaranteed to be zeroed after the first if it's run more than once) @@ -353,14 +369,8 @@ impl Drop for Arc { // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) atomic::fence(Acquire); - // Destroy the data at this time, even though we may not free the box allocation itself - // (there may still be weak pointers lying around). - unsafe { drop(ptr::read(&self.inner().data)); } - - if self.inner().weak.fetch_sub(1, Release) == 1 { - atomic::fence(Acquire); - unsafe { deallocate(ptr as *mut u8, size_of::>(), - min_align_of::>()) } + unsafe { + self.drop_slow() } } }