Skip to content

Commit a729a40

Browse files
committed
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.
1 parent 65b61ff commit a729a40

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

src/liballoc/rc.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ use core::option::Option::{Some, None};
160160
use core::ptr::{self, PtrExt};
161161
use core::result::Result;
162162
use core::result::Result::{Ok, Err};
163+
use core::intrinsics::assume;
163164

164165
use heap::deallocate;
165166

@@ -905,10 +906,20 @@ trait RcBoxPtr<T> {
905906
fn strong(&self) -> uint { self.inner().strong.get() }
906907

907908
#[inline]
908-
fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
909+
fn inc_strong(&self) {
910+
let strong = self.strong();
911+
// The reference count is always at least one unless we're about to drop the type
912+
unsafe { assume(strong > 0); }
913+
self.inner().strong.set(strong + 1);
914+
}
909915

910916
#[inline]
911-
fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
917+
fn dec_strong(&self) {
918+
let strong = self.strong();
919+
// The reference count is always at least one unless we're about to drop the type
920+
unsafe { assume(strong > 0); }
921+
self.inner().strong.set(strong - 1);
922+
}
912923

913924
#[inline]
914925
fn weak(&self) -> uint { self.inner().weak.get() }

0 commit comments

Comments
 (0)