diff options
| author | James Miller <james@aatch.net> | 2015-01-21 00:46:02 +1300 |
|---|---|---|
| committer | James Miller <james@aatch.net> | 2015-01-21 00:46:02 +1300 |
| commit | a729a404945de10f99e2530a5c28952996532b29 (patch) | |
| tree | a4bd2a7171deb6edf5bab96ecc4c3896c5ed2a7f | |
| parent | 65b61ffb3f55c996eceded6c91281911b671d978 (diff) | |
| download | rust-a729a404945de10f99e2530a5c28952996532b29.tar.gz rust-a729a404945de10f99e2530a5c28952996532b29.zip | |
Use assume to inform the optimiser about refcount invariants
The reference count can never be 0, unless we're about to drop the data completely. Using the `assume` intrinsic allows us to inform LLVM about that invariant, meaning it can avoid unnecessary drops.
| -rw-r--r-- | src/liballoc/rc.rs | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 7191a7af346..0f2a11cc1db 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -160,6 +160,7 @@ use core::option::Option::{Some, None}; use core::ptr::{self, PtrExt}; use core::result::Result; use core::result::Result::{Ok, Err}; +use core::intrinsics::assume; use heap::deallocate; @@ -905,10 +906,20 @@ trait RcBoxPtr<T> { fn strong(&self) -> uint { self.inner().strong.get() } #[inline] - fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); } + fn inc_strong(&self) { + let strong = self.strong(); + // The reference count is always at least one unless we're about to drop the type + unsafe { assume(strong > 0); } + self.inner().strong.set(strong + 1); + } #[inline] - fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); } + fn dec_strong(&self) { + let strong = self.strong(); + // The reference count is always at least one unless we're about to drop the type + unsafe { assume(strong > 0); } + self.inner().strong.set(strong - 1); + } #[inline] fn weak(&self) -> uint { self.inner().weak.get() } |
