@@ -20,6 +20,7 @@ impl<L: StatsLogger> Stats<DefaultAlloc, L> {
2020 const_if ! {
2121 "extra_const" ,
2222 "Create a new stats‐collecting allocator wrapper." ,
23+ #[ inline]
2324 pub const fn new( logger: L ) -> Stats <DefaultAlloc , L > {
2425 Stats ( DefaultAlloc , logger)
2526 }
@@ -30,40 +31,64 @@ impl<A, L: StatsLogger> Stats<A, L> {
3031 const_if ! {
3132 "extra_const" ,
3233 "Create a new stats‐collecting allocator wrapper." ,
34+ #[ inline]
3335 pub const fn new_in( inner: A , logger: L ) -> Stats <A , L > {
3436 Stats ( inner, logger)
3537 }
3638 }
3739}
3840
3941// no-op logger
42+ #[ allow( clippy:: inline_always) ]
4043impl StatsLogger for ( ) {
44+ // none of these do anything, so we just inline them.
45+ #[ inline( always) ]
4146 fn log ( & self , _: AllocRes ) { }
47+ #[ inline( always) ]
4248 fn inc_total_bytes_allocated ( & self , _: usize ) -> usize {
4349 0
4450 }
51+ #[ inline( always) ]
4552 fn dec_total_bytes_allocated ( & self , _: usize ) -> usize {
4653 0
4754 }
55+ #[ inline( always) ]
4856 fn total ( & self ) -> usize {
4957 0
5058 }
5159}
5260
61+ /// Internal helper of [`atomic_total_ops`] for adding to an atomic value.
62+ #[ doc( hidden) ]
63+ pub fn inc_atomic ( atomic : & AtomicUsize , bytes : usize ) -> usize {
64+ let res = atomic. load ( Acquire ) + bytes;
65+ atomic. store ( res, Release ) ;
66+ res
67+ }
68+
69+ /// Internal helper of [`atomic_total_ops`] for subtracting from an atomic value.
70+ #[ doc( hidden) ]
71+ pub fn dec_atomic ( atomic : & AtomicUsize , bytes : usize ) -> usize {
72+ let res = atomic. load ( Acquire ) - bytes;
73+ atomic. store ( res, Release ) ;
74+ res
75+ }
76+
77+ #[ macro_export]
78+ /// Helper macro to implement the default atomic total operations for a `StatsLogger`.
5379macro_rules! atomic_total_ops {
54- ( $this: expr $( , $field: ident) ?) => {
80+ ( $( $field: ident) ?) => {
81+ #[ inline( always) ]
5582 fn inc_total_bytes_allocated( & self , bytes: usize ) -> usize {
56- let res = self $( . $field) ?. load( Acquire ) + bytes;
57- self $( . $field) ?. store( res, Release ) ;
58- res
83+ $crate:: stats:: inc_atomic( & self $( . $field) ?, bytes)
5984 }
6085
86+ #[ inline( always) ]
6187 fn dec_total_bytes_allocated( & self , bytes: usize ) -> usize {
62- let res = self $( . $field) ?. load( Acquire ) - bytes;
63- self $( . $field) ?. store( res, Release ) ;
64- res
88+ $crate:: stats:: dec_atomic( & self $( . $field) ?, bytes)
6589 }
6690
91+ #[ inline( always) ]
6792 fn total( & self ) -> usize {
6893 self $( . $field) ?. load( Acquire )
6994 }
@@ -72,27 +97,33 @@ macro_rules! atomic_total_ops {
7297
7398// byte counter-only logger (no stat)
7499impl StatsLogger for AtomicUsize {
100+ #[ inline( always) ]
75101 fn log ( & self , _: AllocRes ) { }
76102
77- atomic_total_ops ! ( self ) ;
103+ atomic_total_ops ! ( ) ;
78104}
79105
80106#[ cfg( feature = "std" ) ]
107+ #[ allow( clippy:: inline_always) ]
81108// file stat-only logger (no byte-count)
82109impl StatsLogger for std:: sync:: Mutex < std:: fs:: File > {
83110 fn log ( & self , stat : AllocRes ) {
111+ // TODO: use File::lock
84112 <std:: fs:: File as std:: io:: Write >:: write_all (
85113 & mut self . lock ( ) . expect ( "`Mutex<File>` was poisoned" ) ,
86114 format ! ( "{}" , stat) . as_bytes ( ) ,
87115 )
88116 . expect ( "failed to write to `File`" ) ;
89117 }
118+ #[ inline( always) ]
90119 fn inc_total_bytes_allocated ( & self , _: usize ) -> usize {
91120 0
92121 }
122+ #[ inline( always) ]
93123 fn dec_total_bytes_allocated ( & self , _: usize ) -> usize {
94124 0
95125 }
126+ #[ inline( always) ]
96127 fn total ( & self ) -> usize {
97128 0
98129 }
@@ -102,15 +133,19 @@ impl StatsLogger for std::sync::Mutex<std::fs::File> {
102133macro_rules! delegate_logger {
103134 ( $ty: ty) => {
104135 impl <L : StatsLogger + ?Sized > StatsLogger for $ty {
136+ #[ inline( always) ]
105137 fn log( & self , stat: AllocRes ) {
106138 ( * * self ) . log( stat)
107139 }
140+ #[ inline( always) ]
108141 fn inc_total_bytes_allocated( & self , bytes: usize ) -> usize {
109142 ( * * self ) . inc_total_bytes_allocated( bytes)
110143 }
144+ #[ inline( always) ]
111145 fn dec_total_bytes_allocated( & self , bytes: usize ) -> usize {
112146 ( * * self ) . dec_total_bytes_allocated( bytes)
113147 }
148+ #[ inline( always) ]
114149 fn total( & self ) -> usize {
115150 ( * * self ) . total( )
116151 }
@@ -161,7 +196,7 @@ impl<W: std::io::Write> StatsLogger for IOLog<W> {
161196 . expect ( "failed to write to inner `W` of `WrittenLog`" ) ;
162197 }
163198
164- atomic_total_ops ! ( self , total) ;
199+ atomic_total_ops ! ( total) ;
165200}
166201
167202#[ cfg( feature = "std" ) ]
@@ -174,7 +209,7 @@ impl<W: fmt::Write> StatsLogger for FmtLog<W> {
174209 . expect ( "failed to write to inner `W` of `FmtLog`" ) ;
175210 }
176211
177- atomic_total_ops ! ( self , total) ;
212+ atomic_total_ops ! ( total) ;
178213}
179214
180215#[ cfg( feature = "std" ) ]
@@ -186,7 +221,7 @@ impl StatsLogger for StatCollectingLog {
186221 . push ( stat) ;
187222 }
188223
189- atomic_total_ops ! ( self , total) ;
224+ atomic_total_ops ! ( total) ;
190225}
191226
192227#[ cfg( feature = "std" ) ]
@@ -248,6 +283,7 @@ impl<W: std::io::Write> IOLog<W> {
248283 const_if ! {
249284 "extra_const" ,
250285 "Creates a new [`IOLog`] from a writer." ,
286+ #[ inline]
251287 pub const fn new( buf: W ) -> IOLog <W > {
252288 IOLog {
253289 buf: std:: sync:: Mutex :: new( buf) ,
@@ -262,6 +298,7 @@ impl<W: fmt::Write> FmtLog<W> {
262298 const_if ! {
263299 "extra_const" ,
264300 "Creates a new [`FmtLog`] from a writer." ,
301+ #[ inline]
265302 pub const fn new( buf: W ) -> FmtLog <W > {
266303 FmtLog {
267304 buf: std:: sync:: Mutex :: new( buf) ,
@@ -288,6 +325,7 @@ impl StatCollectingLog {
288325 "extra_const" ,
289326 "Creates a new [`StatCollectingLog`]." ,
290327 #[ must_use]
328+ #[ inline]
291329 pub const fn new( ) -> StatCollectingLog {
292330 StatCollectingLog {
293331 results: std:: sync:: Mutex :: new( Vec :: new( ) ) ,
@@ -298,6 +336,7 @@ impl StatCollectingLog {
298336
299337 /// Creates a new [`StatCollectingLog`] with the given capacity.
300338 #[ must_use]
339+ #[ inline]
301340 pub fn with_capacity ( cap : usize ) -> StatCollectingLog {
302341 StatCollectingLog {
303342 results : std:: sync:: Mutex :: new ( Vec :: with_capacity ( cap) ) ,
@@ -306,10 +345,12 @@ impl StatCollectingLog {
306345 }
307346}
308347
348+ // TODO: dedicated FileLog using File::lock() instead of a mutex
309349#[ cfg( feature = "std" ) ]
310350/// A logger that writes to a file.
311351pub type FileLog = IOLog < std:: fs:: File > ;
312352
353+ // TODO: dedicated StdoutLog
313354#[ cfg( feature = "std" ) ]
314355/// A logger that writes to stdout.
315356pub type StdoutLog = IOLog < std:: io:: Stdout > ;
@@ -627,11 +668,13 @@ fn grow<
627668
628669impl < A : Alloc , L : StatsLogger > Alloc for Stats < A , L > {
629670 #[ track_caller]
671+ #[ inline]
630672 fn alloc ( & self , layout : Layout ) -> Result < NonNull < u8 > , AllocError > {
631673 allocate ( self , A :: alloc, layout, AllocKind :: Uninitialized )
632674 }
633675
634676 #[ track_caller]
677+ #[ inline]
635678 fn alloc_zeroed ( & self , layout : Layout ) -> Result < NonNull < u8 > , AllocError > {
636679 allocate ( self , A :: alloc_zeroed, layout, AllocKind :: Zeroed )
637680 }
0 commit comments