Skip to content

Commit 016ea0b

Browse files
committed
inline stats.rs
1 parent ed4e570 commit 016ea0b

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ _no versions before 0.13.2 have a changelog as I started the changelog in that v
66

77
- [Version 0.16.0 Predicted](#version-0160-predicted)
88
- [Version 0.15.0](#version-0150)
9+
- [Commit 7](#commit-7-2025-8-06)
10+
- [Commit 6](#commit-6-2025-8-05)
11+
- [Commit 5](#commit-5-2025-8-05)
912
- [Commit 4](#commit-4-2025-8-05)
1013
- [Commit 3](#commit-3-2025-8-05)
1114
- [Commit 2](#commit-2-2025-8-05)
@@ -38,6 +41,11 @@ _no versions before 0.13.2 have a changelog as I started the changelog in that v
3841

3942
## Version 0.15.0
4043

44+
### Commit 8 (2025-8-07)
45+
46+
- Inline stats.rs
47+
- Slightly improve inlining in lib.rs and helpers.rs
48+
4149
### Commit 7 (2025-8-06)
4250

4351
- Inline lib.rs

src/features/stats.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
4043
impl 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`.
5379
macro_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)
7499
impl 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)
82109
impl 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> {
102133
macro_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.
311351
pub type FileLog = IOLog<std::fs::File>;
312352

353+
// TODO: dedicated StdoutLog
313354
#[cfg(feature = "std")]
314355
/// A logger that writes to stdout.
315356
pub type StdoutLog = IOLog<std::io::Stdout>;
@@ -627,11 +668,13 @@ fn grow<
627668

628669
impl<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
}

src/helpers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub const fn align_up(n: usize, align: NonZeroUsize) -> usize {
104104
///
105105
/// `align` must be non-zero.
106106
#[must_use]
107+
#[inline]
107108
pub const unsafe fn align_up_unchecked(n: usize, align: usize) -> usize {
108109
let m1 = align - 1;
109110
(n + m1) & !m1

src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ macro_rules! const_if {
139139
};
140140
}
141141

142-
// TODO: inlining for stats.rs, and alloc_slice.rs.
142+
// TODO: inlining for alloc_slice.rs.
143143

144144
extern crate alloc;
145145
extern crate core;
@@ -499,21 +499,23 @@ pub(crate) mod nightly {
499499
default_alloc_impl!(Global);
500500
}
501501

502+
#[allow(clippy::inline_always)]
502503
impl<A: Alloc + ?Sized> Alloc for &A {
504+
// TODO: decide whether to keep these as inline always
503505
#[cfg_attr(miri, track_caller)]
504-
#[inline]
506+
#[inline(always)]
505507
fn alloc(&self, layout: Layout) -> Result<NonNull<u8>, AllocError> {
506508
(**self).alloc(layout)
507509
}
508510

509511
#[cfg_attr(miri, track_caller)]
510-
#[inline]
512+
#[inline(always)]
511513
fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<u8>, AllocError> {
512514
(**self).alloc_zeroed(layout)
513515
}
514516

515517
#[cfg_attr(miri, track_caller)]
516-
#[inline]
518+
#[inline(always)]
517519
unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout) {
518520
(**self).dealloc(ptr, layout);
519521
}

0 commit comments

Comments
 (0)