@@ -160,6 +160,7 @@ use core::option::Option::{Some, None};
160
160
use core:: ptr:: { self , PtrExt } ;
161
161
use core:: result:: Result ;
162
162
use core:: result:: Result :: { Ok , Err } ;
163
+ use core:: intrinsics:: assume;
163
164
164
165
use heap:: deallocate;
165
166
@@ -905,10 +906,24 @@ trait RcBoxPtr<T> {
905
906
fn strong ( & self ) -> uint { self . inner ( ) . strong . get ( ) }
906
907
907
908
#[ 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
+ // This allows the bulk of the destructor to be omitted in cases where we know that
913
+ // the reference count must be > 0.
914
+ unsafe { assume ( strong > 0 ) ; }
915
+ self . inner ( ) . strong . set ( strong + 1 ) ;
916
+ }
909
917
910
918
#[ inline]
911
- fn dec_strong ( & self ) { self . inner ( ) . strong . set ( self . strong ( ) - 1 ) ; }
919
+ fn dec_strong ( & self ) {
920
+ let strong = self . strong ( ) ;
921
+ // The reference count is always at least one unless we're about to drop the type
922
+ // This allows the bulk of the destructor to be omitted in cases where we know that
923
+ // the reference count must be > 0
924
+ unsafe { assume ( strong > 0 ) ; }
925
+ self . inner ( ) . strong . set ( strong - 1 ) ;
926
+ }
912
927
913
928
#[ inline]
914
929
fn weak ( & self ) -> uint { self . inner ( ) . weak . get ( ) }
@@ -922,12 +937,30 @@ trait RcBoxPtr<T> {
922
937
923
938
impl < T > RcBoxPtr < T > for Rc < T > {
924
939
#[ inline( always) ]
925
- fn inner ( & self ) -> & RcBox < T > { unsafe { & ( * * self . _ptr ) } }
940
+ fn inner ( & self ) -> & RcBox < T > {
941
+ unsafe {
942
+ // Safe to assume this here, as if it weren't true, we'd be breaking
943
+ // the contract anyway.
944
+ // This allows the null check to be elided in the destructor if we
945
+ // manipulated the reference count in the same function.
946
+ assume ( !self . _ptr . is_null ( ) ) ;
947
+ & ( * * self . _ptr )
948
+ }
949
+ }
926
950
}
927
951
928
952
impl < T > RcBoxPtr < T > for Weak < T > {
929
953
#[ inline( always) ]
930
- fn inner ( & self ) -> & RcBox < T > { unsafe { & ( * * self . _ptr ) } }
954
+ fn inner ( & self ) -> & RcBox < T > {
955
+ unsafe {
956
+ // Safe to assume this here, as if it weren't true, we'd be breaking
957
+ // the contract anyway
958
+ // This allows the null check to be elided in the destructor if we
959
+ // manipulated the reference count in the same function.
960
+ assume ( !self . _ptr . is_null ( ) ) ;
961
+ & ( * * self . _ptr )
962
+ }
963
+ }
931
964
}
932
965
933
966
#[ cfg( test) ]
0 commit comments