Skip to content
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
20 changes: 0 additions & 20 deletions library/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ dependencies = [
name = "alloc"
version = "0.0.0"
dependencies = [
"bdwgc",
"compiler_builtins",
"core",
"rand",
Expand All @@ -41,16 +40,6 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"

[[package]]
name = "bdwgc"
version = "0.1.0"
dependencies = [
"cmake",
"compiler_builtins",
"libc",
"rustc-std-workspace-core",
]

[[package]]
name = "cc"
version = "1.2.0"
Expand All @@ -70,15 +59,6 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "cmake"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
dependencies = [
"cc",
]

[[package]]
name = "compiler_builtins"
version = "0.1.150"
Expand Down
3 changes: 1 addition & 2 deletions library/alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ autobenches = false
edition = "2021"

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

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

[lints.rust.unexpected_cfgs]
level = "warn"
Expand Down
2 changes: 1 addition & 1 deletion library/bdwgc/build.rs → library/alloc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn main() {
let status = Command::new(bindgen)
.args(&[
"--ctypes-prefix",
"libc",
"core::ffi",
"--use-core",
"-o",
out.to_str().unwrap(),
Expand Down
31 changes: 0 additions & 31 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,6 @@ pub use core::alloc::*;
use core::hint;
#[cfg(not(test))]
use core::ptr::{self, NonNull};
#[cfg(feature = "log-stats")]
use core::sync::atomic::AtomicU64;

#[cfg(feature = "log-stats")]
#[unstable(feature = "gc", issue = "none")]
/// Global counters for various GC stats.
pub static GC_COUNTERS: GcCounters = GcCounters {
finalizers_registered: AtomicU64::new(0),
finalizers_elidable: AtomicU64::new(0),
finalizers_completed: AtomicU64::new(0),
barriers_visited: AtomicU64::new(0),
allocated_gc: AtomicU64::new(0),
allocated_boxed: AtomicU64::new(0),
allocated_rc: AtomicU64::new(0),
allocated_arc: AtomicU64::new(0),
};

#[cfg(feature = "log-stats")]
#[unstable(feature = "gc", issue = "none")]
#[allow(missing_docs)]
#[derive(Debug, Default)]
pub struct GcCounters {
pub finalizers_registered: AtomicU64,
pub finalizers_elidable: AtomicU64,
pub finalizers_completed: AtomicU64,
pub barriers_visited: AtomicU64,
pub allocated_gc: AtomicU64,
pub allocated_boxed: AtomicU64,
pub allocated_rc: AtomicU64,
pub allocated_arc: AtomicU64,
}

unsafe extern "Rust" {
// These are the magic symbols to call the global allocator. rustc generates
Expand Down
157 changes: 157 additions & 0 deletions library/alloc/src/bdwgc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#![allow(missing_docs)]

#[cfg(not(no_gc))]
#[allow(nonstandard_style)]
#[allow(missing_debug_implementations)]
pub mod api {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}

#[cfg(not(no_gc))]
pub use api::*;

pub mod metrics {
#[derive(Copy, Clone, Debug)]
pub enum Metric {
AllocationsArc,
AllocationsGc,
AllocationsRc,
AllocationsBox,
FinalizersRun,
FinalizersElided,
FinalizersRegistered,
}

trait MetricsImpl {
fn init(&self) {}
fn increment(&self, _amount: u64, _metric: Metric) {}
fn capture(&self, _is_last: bool) {}
}

#[cfg(feature = "gc-metrics")]
mod active {
use core::sync::atomic::{AtomicU64, Ordering};

use super::{Metric, MetricsImpl};

pub(super) struct Metrics {
finalizers_registered: AtomicU64,
finalizers_elidable: AtomicU64,
finalizers_completed: AtomicU64,
barriers_visited: AtomicU64,
allocated_gc: AtomicU64,
allocated_arc: AtomicU64,
allocated_rc: AtomicU64,
allocated_boxed: AtomicU64,
}

impl Metrics {
pub const fn new() -> Self {
Self {
finalizers_registered: AtomicU64::new(0),
finalizers_elidable: AtomicU64::new(0),
finalizers_completed: AtomicU64::new(0),
barriers_visited: AtomicU64::new(0),
allocated_gc: AtomicU64::new(0),
allocated_arc: AtomicU64::new(0),
allocated_rc: AtomicU64::new(0),
allocated_boxed: AtomicU64::new(0),
}
}
}

pub extern "C" fn record_post_collection(event: crate::GC_EventType) {
if event == crate::GC_EventType_GC_EVENT_END {
super::METRICS.capture(false);
}
}

impl MetricsImpl for Metrics {
fn init(&self) {
unsafe {
crate::GC_enable_benchmark_stats();
crate::GC_set_on_collection_event(Some(record_post_collection));
}
}

fn increment(&self, amount: u64, metric: Metric) {
match metric {
Metric::AllocationsArc => {
self.allocated_boxed.fetch_sub(amount, Ordering::Relaxed);
self.allocated_arc.fetch_add(amount, Ordering::Relaxed);
}
Metric::AllocationsRc => {
self.allocated_boxed.fetch_sub(amount, Ordering::Relaxed);
self.allocated_rc.fetch_add(amount, Ordering::Relaxed);
}
Metric::AllocationsBox => {
self.allocated_boxed.fetch_add(amount, Ordering::Relaxed);
}
Metric::AllocationsGc => {
self.allocated_gc.fetch_add(amount, Ordering::Relaxed);
}
Metric::FinalizersRun => {
self.finalizers_completed.fetch_add(amount, Ordering::Relaxed);
}
Metric::FinalizersElided => {
self.finalizers_completed.fetch_add(amount, Ordering::Relaxed);
}
Metric::FinalizersRegistered => {
self.finalizers_registered.fetch_add(amount, Ordering::Relaxed);
}
}
}

fn capture(&self, is_last: bool) {
// Must preserve this ordering as it's hardcoded inside BDWGC.
// See src/bdwgc/misc.c:2812
unsafe {
crate::GC_log_metrics(
self.finalizers_completed.load(Ordering::Relaxed),
self.finalizers_registered.load(Ordering::Relaxed),
self.allocated_gc.load(Ordering::Relaxed),
self.allocated_arc.load(Ordering::Relaxed),
self.allocated_rc.load(Ordering::Relaxed),
self.allocated_boxed.load(Ordering::Relaxed),
is_last as i32,
);
}
}
}
}

#[cfg(not(feature = "gc-metrics"))]
pub mod noop {
use super::MetricsImpl;

#[derive(Debug, Default)]
pub struct Metrics;

impl Metrics {
pub const fn new() -> Self {
Self
}
}

impl MetricsImpl for Metrics {}
}

#[cfg(feature = "gc-metrics")]
use active::Metrics;
#[cfg(not(feature = "gc-metrics"))]
use noop::Metrics;

static METRICS: Metrics = Metrics::new();

pub fn init() {
METRICS.init();
}

pub fn record_final() {
METRICS.capture(true);
}

pub fn increment(amount: u64, metric: Metric) {
METRICS.increment(amount, metric);
}
}
3 changes: 1 addition & 2 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,8 @@ pub mod __export {
pub use core::hint::must_use;
}

#[cfg(not(no_gc))]
#[unstable(feature = "gc", issue = "none")]
pub use bdwgc;
pub mod bdwgc;

#[cfg(test)]
#[allow(dead_code)] // Not used in all configurations
Expand Down
Loading