Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alloy metric recording fixes and additions #158

Merged
merged 2 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use core::sync::atomic::AtomicU64;
/// Global counters for various GC stats.
pub static GC_COUNTERS: GcCounters = GcCounters {
finalizers_registered: AtomicU64::new(0),
finalizers_elidable: AtomicU64::new(0),
barriers_visited: AtomicU64::new(0),
allocated_gc: AtomicU64::new(0),
allocated_boxed: AtomicU64::new(0),
allocated_rc: AtomicU64::new(0),
Expand All @@ -35,6 +37,8 @@ pub static GC_COUNTERS: GcCounters = GcCounters {
#[derive(Debug, Default)]
pub struct GcCounters {
pub finalizers_registered: AtomicU64,
pub finalizers_elidable: AtomicU64,
pub barriers_visited: AtomicU64,
pub allocated_gc: AtomicU64,
pub allocated_boxed: AtomicU64,
pub allocated_rc: AtomicU64,
Expand Down
2 changes: 2 additions & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ system-llvm-libunwind = ["unwind/system-llvm-libunwind"]
# Alloy debug flags
log-stats = ["alloc/log-stats"]
premature-finalizer-prevention = []
premature-finalizer-prevention-optimize = []
finalizer-elision = []

# Make panics and failed asserts immediately abort without formatting any message
panic_immediate_abort = ["core/panic_immediate_abort", "alloc/panic_immediate_abort"]
Expand Down
77 changes: 61 additions & 16 deletions library/std/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,28 +161,53 @@ impl GcAllocator {
#[cfg(feature = "log-stats")]
#[derive(Debug, Copy, Clone)]
pub struct GcStats {
pub finalizers_registered: u64,
pub finalizers_completed: u64,
pub allocated_gc: u64,
pub allocated_boxed: u64,
pub allocated_arc: u64,
pub allocated_rc: u64,
pub num_gcs: u64,
pub elision_enabled: u8,
pub prem_enabled: u8,
pub premopt_enabled: u8,
pub num_finalizers_registered: u64,
pub num_finalizers_completed: u64,
pub num_finalizers_elidable: u64,
pub num_barriers_visited: u64,
pub num_allocated_gc: u64,
pub num_allocated_boxed: u64,
pub num_allocated_arc: u64,
pub num_allocated_rc: u64,
pub num_cycles: u64,
}

////////////////////////////////////////////////////////////////////////////////
// Free functions
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "log-stats")]
pub fn stats() -> GcStats {
#[cfg(feature = "finalizer-elision")]
let elision_enabled = 1;
#[cfg(not(feature = "finalizer-elision"))]
let elision_enabled = 0;
#[cfg(feature = "premature-finalizer-prevention")]
let prem_enabled = 1;
#[cfg(not(feature = "premature-finalizer-prevention"))]
let prem_enabled = 0;
#[cfg(feature = "premature-finalizer-prevention-optimize")]
let premopt_enabled = 1;
#[cfg(not(feature = "premature-finalizer-prevention-optimize"))]
let premopt_enabled = 0;

GcStats {
finalizers_registered: GC_COUNTERS.finalizers_registered.load(atomic::Ordering::Relaxed),
finalizers_completed: unsafe { bdwgc::GC_finalized_total() },
allocated_gc: GC_COUNTERS.allocated_gc.load(atomic::Ordering::Relaxed),
allocated_boxed: GC_COUNTERS.allocated_boxed.load(atomic::Ordering::Relaxed),
allocated_rc: GC_COUNTERS.allocated_rc.load(atomic::Ordering::Relaxed),
allocated_arc: GC_COUNTERS.allocated_arc.load(atomic::Ordering::Relaxed),
num_gcs: unsafe { bdwgc::GC_get_gc_no() },
elision_enabled,
prem_enabled,
premopt_enabled,
num_finalizers_registered: GC_COUNTERS
.finalizers_registered
.load(atomic::Ordering::Relaxed),
num_finalizers_completed: unsafe { bdwgc::GC_finalized_total() },
num_finalizers_elidable: GC_COUNTERS.finalizers_elidable.load(atomic::Ordering::Relaxed),
num_barriers_visited: GC_COUNTERS.barriers_visited.load(atomic::Ordering::Relaxed),
num_allocated_gc: GC_COUNTERS.allocated_gc.load(atomic::Ordering::Relaxed),
num_allocated_boxed: GC_COUNTERS.allocated_boxed.load(atomic::Ordering::Relaxed),
num_allocated_rc: GC_COUNTERS.allocated_rc.load(atomic::Ordering::Relaxed),
num_allocated_arc: GC_COUNTERS.allocated_arc.load(atomic::Ordering::Relaxed),
num_cycles: unsafe { bdwgc::GC_get_gc_no() },
}
}

Expand Down Expand Up @@ -267,6 +292,8 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Gc<U>> for Gc<T> {}
#[cfg(all(not(bootstrap), not(test), feature = "premature-finalizer-prevention"))]
impl<T: ?Sized> Drop for Gc<T> {
fn drop(&mut self) {
#[cfg(feature = "log-stats")]
GC_COUNTERS.barriers_visited.fetch_add(1, atomic::Ordering::Relaxed);
keep_alive(self);
}
}
Expand Down Expand Up @@ -489,8 +516,26 @@ impl<T> Gc<T> {
#[cfg(not(no_global_oom_handling))]
unsafe fn new_internal(value: T) -> Self {
#[cfg(not(bootstrap))]
if !crate::mem::needs_finalizer::<T>() {
return Self::from_inner(Box::leak(Box::new_in(GcBox { value }, GcAllocator)).into());
{
#[cfg(feature = "finalizer-elision")]
let needs_finalizer = crate::mem::needs_finalizer::<T>();
#[cfg(not(feature = "finalizer-elision"))]
let needs_finalizer = crate::mem::needs_drop::<T>();

if !needs_finalizer {
return Self::from_inner(
Box::leak(Box::new_in(GcBox { value }, GcAllocator)).into(),
);
}

#[cfg(feature = "log-stats")]
{
GC_COUNTERS.finalizers_elidable.fetch_add(
crate::mem::needs_finalizer::<T>() as u64,
atomic::Ordering::Relaxed,
);
GC_COUNTERS.finalizers_registered.fetch_add(1, atomic::Ordering::Relaxed);
}
}

unsafe extern "C" fn finalizer_shim<T>(obj: *mut u8, _: *mut u8) {
Expand Down
32 changes: 24 additions & 8 deletions library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,32 @@ pub(crate) fn log_stats() {
.open(crate::env::var("ALLOY_LOG").unwrap())
.unwrap();

let headers =
"finalizers registered,finalizers completed,GC allocated,boxed allocated,GC cycles";
let headers = "elision enabled,\
premature finalizer prevention enabled,\
premopt enabled,\
finalizers registered,\
finalizers completed,\
barriers visited,\
Gc allocated,\
Box allocated,\
Rc allocated,\
Arc allocated,\
STW pauses";
let stats = crate::gc::stats();
let stats = format!(
"{},{},{},{},{}\n",
stats.finalizers_registered,
stats.finalizers_completed,
stats.allocated_gc,
stats.allocated_boxed,
stats.num_gcs
"{},{},{},{},{},{},{},{},{},{},{},{}\n",
stats.elision_enabled,
stats.prem_enabled,
stats.premopt_enabled,
stats.num_finalizers_registered,
stats.num_finalizers_completed,
stats.num_finalizers_elidable,
stats.num_barriers_visited,
stats.num_allocated_gc,
stats.num_allocated_boxed,
stats.num_allocated_rc,
stats.num_allocated_arc,
stats.num_cycles
);
write!(filename, "{}", format!("{headers}\n{stats}")).unwrap();
}
Expand Down
2 changes: 2 additions & 0 deletions library/sysroot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ std_detect_env_override = ["std/std_detect_env_override"]

# Alloy debug flags
log-stats = ["std/log-stats"]
finalizer-elision = ["std/finalizer-elision"]
premature-finalizer-prevention = ["std/premature-finalizer-prevention"]
premature-finalizer-prevention-optimize = ["std/premature-finalizer-prevention-optimize"]
3 changes: 3 additions & 0 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,9 @@ impl Build {
if self.config.premature_finalizer_prevention {
features.push_str(" premature-finalizer-prevention");
}
if self.config.finalizer_elision {
features.push_str(" finalizer-elision");
}
features
}

Expand Down