Skip to content

Commit d7cd1a4

Browse files
authored
Merge pull request #188 from jacob-hughes/collection-stats
Add more detailed collection stats
2 parents 3d1d918 + 222287e commit d7cd1a4

File tree

20 files changed

+202
-339
lines changed

20 files changed

+202
-339
lines changed

library/Cargo.lock

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ dependencies = [
2828
name = "alloc"
2929
version = "0.0.0"
3030
dependencies = [
31-
"bdwgc",
3231
"compiler_builtins",
3332
"core",
3433
"rand",
@@ -41,16 +40,6 @@ version = "0.2.21"
4140
source = "registry+https://github.com/rust-lang/crates.io-index"
4241
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
4342

44-
[[package]]
45-
name = "bdwgc"
46-
version = "0.1.0"
47-
dependencies = [
48-
"cmake",
49-
"compiler_builtins",
50-
"libc",
51-
"rustc-std-workspace-core",
52-
]
53-
5443
[[package]]
5544
name = "cc"
5645
version = "1.2.0"
@@ -70,15 +59,6 @@ dependencies = [
7059
"rustc-std-workspace-core",
7160
]
7261

73-
[[package]]
74-
name = "cmake"
75-
version = "0.1.54"
76-
source = "registry+https://github.com/rust-lang/crates.io-index"
77-
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
78-
dependencies = [
79-
"cc",
80-
]
81-
8262
[[package]]
8363
name = "compiler_builtins"
8464
version = "0.1.150"

library/alloc/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ autobenches = false
1111
edition = "2021"
1212

1313
[dependencies]
14-
bdwgc = { path = "../bdwgc" }
1514
core = { path = "../core", public = true }
1615
compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] }
1716

@@ -43,11 +42,11 @@ compiler-builtins-c = ["compiler_builtins/c"]
4342
compiler-builtins-no-asm = ["compiler_builtins/no-asm"]
4443
compiler-builtins-no-f16-f128 = ["compiler_builtins/no-f16-f128"]
4544
compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"]
46-
log-stats = []
4745
# Make panics and failed asserts immediately abort without formatting any message
4846
panic_immediate_abort = ["core/panic_immediate_abort"]
4947
# Choose algorithms that are optimized for binary size instead of runtime performance
5048
optimize_for_size = ["core/optimize_for_size"]
49+
gc-metrics = []
5150

5251
[lints.rust.unexpected_cfgs]
5352
level = "warn"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() {
2121
let status = Command::new(bindgen)
2222
.args(&[
2323
"--ctypes-prefix",
24-
"libc",
24+
"core::ffi",
2525
"--use-core",
2626
"-o",
2727
out.to_str().unwrap(),

library/alloc/src/alloc.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,6 @@ pub use core::alloc::*;
99
use core::hint;
1010
#[cfg(not(test))]
1111
use core::ptr::{self, NonNull};
12-
#[cfg(feature = "log-stats")]
13-
use core::sync::atomic::AtomicU64;
14-
15-
#[cfg(feature = "log-stats")]
16-
#[unstable(feature = "gc", issue = "none")]
17-
/// Global counters for various GC stats.
18-
pub static GC_COUNTERS: GcCounters = GcCounters {
19-
finalizers_registered: AtomicU64::new(0),
20-
finalizers_elidable: AtomicU64::new(0),
21-
finalizers_completed: AtomicU64::new(0),
22-
barriers_visited: AtomicU64::new(0),
23-
allocated_gc: AtomicU64::new(0),
24-
allocated_boxed: AtomicU64::new(0),
25-
allocated_rc: AtomicU64::new(0),
26-
allocated_arc: AtomicU64::new(0),
27-
};
28-
29-
#[cfg(feature = "log-stats")]
30-
#[unstable(feature = "gc", issue = "none")]
31-
#[allow(missing_docs)]
32-
#[derive(Debug, Default)]
33-
pub struct GcCounters {
34-
pub finalizers_registered: AtomicU64,
35-
pub finalizers_elidable: AtomicU64,
36-
pub finalizers_completed: AtomicU64,
37-
pub barriers_visited: AtomicU64,
38-
pub allocated_gc: AtomicU64,
39-
pub allocated_boxed: AtomicU64,
40-
pub allocated_rc: AtomicU64,
41-
pub allocated_arc: AtomicU64,
42-
}
4312

4413
unsafe extern "Rust" {
4514
// These are the magic symbols to call the global allocator. rustc generates

library/alloc/src/bdwgc.rs

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#![allow(missing_docs)]
2+
3+
#[cfg(not(no_gc))]
4+
#[allow(nonstandard_style)]
5+
#[allow(missing_debug_implementations)]
6+
pub mod api {
7+
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
8+
}
9+
10+
#[cfg(not(no_gc))]
11+
pub use api::*;
12+
13+
pub mod metrics {
14+
#[derive(Copy, Clone, Debug)]
15+
pub enum Metric {
16+
AllocationsArc,
17+
AllocationsGc,
18+
AllocationsRc,
19+
AllocationsBox,
20+
FinalizersRun,
21+
FinalizersElided,
22+
FinalizersRegistered,
23+
}
24+
25+
trait MetricsImpl {
26+
fn init(&self) {}
27+
fn increment(&self, _amount: u64, _metric: Metric) {}
28+
fn capture(&self, _is_last: bool) {}
29+
}
30+
31+
#[cfg(feature = "gc-metrics")]
32+
mod active {
33+
use core::sync::atomic::{AtomicU64, Ordering};
34+
35+
use super::{Metric, MetricsImpl};
36+
37+
pub(super) struct Metrics {
38+
finalizers_registered: AtomicU64,
39+
finalizers_elidable: AtomicU64,
40+
finalizers_completed: AtomicU64,
41+
barriers_visited: AtomicU64,
42+
allocated_gc: AtomicU64,
43+
allocated_arc: AtomicU64,
44+
allocated_rc: AtomicU64,
45+
allocated_boxed: AtomicU64,
46+
}
47+
48+
impl Metrics {
49+
pub const fn new() -> Self {
50+
Self {
51+
finalizers_registered: AtomicU64::new(0),
52+
finalizers_elidable: AtomicU64::new(0),
53+
finalizers_completed: AtomicU64::new(0),
54+
barriers_visited: AtomicU64::new(0),
55+
allocated_gc: AtomicU64::new(0),
56+
allocated_arc: AtomicU64::new(0),
57+
allocated_rc: AtomicU64::new(0),
58+
allocated_boxed: AtomicU64::new(0),
59+
}
60+
}
61+
}
62+
63+
pub extern "C" fn record_post_collection(event: crate::GC_EventType) {
64+
if event == crate::GC_EventType_GC_EVENT_END {
65+
super::METRICS.capture(false);
66+
}
67+
}
68+
69+
impl MetricsImpl for Metrics {
70+
fn init(&self) {
71+
unsafe {
72+
crate::GC_enable_benchmark_stats();
73+
crate::GC_set_on_collection_event(Some(record_post_collection));
74+
}
75+
}
76+
77+
fn increment(&self, amount: u64, metric: Metric) {
78+
match metric {
79+
Metric::AllocationsArc => {
80+
self.allocated_boxed.fetch_sub(amount, Ordering::Relaxed);
81+
self.allocated_arc.fetch_add(amount, Ordering::Relaxed);
82+
}
83+
Metric::AllocationsRc => {
84+
self.allocated_boxed.fetch_sub(amount, Ordering::Relaxed);
85+
self.allocated_rc.fetch_add(amount, Ordering::Relaxed);
86+
}
87+
Metric::AllocationsBox => {
88+
self.allocated_boxed.fetch_add(amount, Ordering::Relaxed);
89+
}
90+
Metric::AllocationsGc => {
91+
self.allocated_gc.fetch_add(amount, Ordering::Relaxed);
92+
}
93+
Metric::FinalizersRun => {
94+
self.finalizers_completed.fetch_add(amount, Ordering::Relaxed);
95+
}
96+
Metric::FinalizersElided => {
97+
self.finalizers_completed.fetch_add(amount, Ordering::Relaxed);
98+
}
99+
Metric::FinalizersRegistered => {
100+
self.finalizers_registered.fetch_add(amount, Ordering::Relaxed);
101+
}
102+
}
103+
}
104+
105+
fn capture(&self, is_last: bool) {
106+
// Must preserve this ordering as it's hardcoded inside BDWGC.
107+
// See src/bdwgc/misc.c:2812
108+
unsafe {
109+
crate::GC_log_metrics(
110+
self.finalizers_completed.load(Ordering::Relaxed),
111+
self.finalizers_registered.load(Ordering::Relaxed),
112+
self.allocated_gc.load(Ordering::Relaxed),
113+
self.allocated_arc.load(Ordering::Relaxed),
114+
self.allocated_rc.load(Ordering::Relaxed),
115+
self.allocated_boxed.load(Ordering::Relaxed),
116+
is_last as i32,
117+
);
118+
}
119+
}
120+
}
121+
}
122+
123+
#[cfg(not(feature = "gc-metrics"))]
124+
pub mod noop {
125+
use super::MetricsImpl;
126+
127+
#[derive(Debug, Default)]
128+
pub struct Metrics;
129+
130+
impl Metrics {
131+
pub const fn new() -> Self {
132+
Self
133+
}
134+
}
135+
136+
impl MetricsImpl for Metrics {}
137+
}
138+
139+
#[cfg(feature = "gc-metrics")]
140+
use active::Metrics;
141+
#[cfg(not(feature = "gc-metrics"))]
142+
use noop::Metrics;
143+
144+
static METRICS: Metrics = Metrics::new();
145+
146+
pub fn init() {
147+
METRICS.init();
148+
}
149+
150+
pub fn record_final() {
151+
METRICS.capture(true);
152+
}
153+
154+
pub fn increment(amount: u64, metric: Metric) {
155+
METRICS.increment(amount, metric);
156+
}
157+
}

library/alloc/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,8 @@ pub mod __export {
254254
pub use core::hint::must_use;
255255
}
256256

257-
#[cfg(not(no_gc))]
258257
#[unstable(feature = "gc", issue = "none")]
259-
pub use bdwgc;
258+
pub mod bdwgc;
260259

261260
#[cfg(test)]
262261
#[allow(dead_code)] // Not used in all configurations

0 commit comments

Comments
 (0)