From 11fa827233f8de1b7e83fd8a0c3d65c0e38eec0e Mon Sep 17 00:00:00 2001 From: Jake Hughes Date: Wed, 11 Jun 2025 16:03:55 +0100 Subject: [PATCH 1/2] Make libbdwgc a dependency of liballoc instead of libstd Previously, libstd depended on libbdwgc (our bindings layer for libgc.so). Historically this made sense when we tried statically linking libgc.a because the interface was tightly coupled with code in library/std/gc.rs. However, this was always a pain-point: liballoc must also depend on libbdwgc, but libstd depends on liballoc, causing this confusing and error-prone cyclic dependency. This reared its head in two main ways: (1) very slow rustc compile times, because libbdwgc would always cache-bust libstd recompiles; (2) occassionally, the build artefacts would end up in a irreparable state and require a full clean (this mostly happened when sending a SIGINT to `x.py` while it was busy building). This commit fixes both these issues, but it is also a necessary prerequesite for the changes to our stat collection, which require libbdwgc to be isolated from libstd in order to prevent duplicate metric collection. --- library/Cargo.lock | 3 +-- library/alloc/Cargo.toml | 2 ++ library/alloc/src/lib.rs | 4 ++++ library/std/Cargo.toml | 1 - library/std/src/gc.rs | 1 + library/std/src/lib.rs | 4 ++-- library/std/src/sys/pal/unix/thread.rs | 6 +++--- library/sysroot/Cargo.toml | 1 - tests/run-make/alloc-no-oom-handling/rmake.rs | 1 + tests/run-make/alloc-no-rc/rmake.rs | 1 + tests/run-make/alloc-no-sync/rmake.rs | 1 + tests/run-make/linker-warning/rmake.rs | 1 + tests/run-make/linker-warning/short-error.txt | 2 +- 13 files changed, 18 insertions(+), 10 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index a68b8350f1bd6..73a517fb449f9 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -28,6 +28,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ + "bdwgc", "compiler_builtins", "core", "rand", @@ -359,7 +360,6 @@ version = "0.0.0" dependencies = [ "addr2line", "alloc", - "bdwgc", "cfg-if", "compiler_builtins", "core", @@ -409,7 +409,6 @@ dependencies = [ name = "sysroot" version = "0.0.0" dependencies = [ - "bdwgc", "proc_macro", "profiler_builtins", "std", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 869cd39a3a351..524de49bf1df4 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -11,6 +11,7 @@ autobenches = false edition = "2021" [dependencies] +bdwgc = { path = "../bdwgc" } core = { path = "../core", public = true } compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } @@ -54,6 +55,7 @@ check-cfg = [ 'cfg(bootstrap)', 'cfg(no_global_oom_handling)', 'cfg(no_rc)', + 'cfg(no_gc)', 'cfg(no_sync)', 'cfg(randomized_layouts)', ] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 034659101f21f..631bf2208b631 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -254,6 +254,10 @@ pub mod __export { pub use core::hint::must_use; } +#[cfg(not(no_gc))] +#[unstable(feature = "gc", issue = "none")] +pub use bdwgc; + #[cfg(test)] #[allow(dead_code)] // Not used in all configurations pub(crate) mod test_helpers { diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 55665cb2934ce..141a70710d4ce 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -15,7 +15,6 @@ crate-type = ["dylib", "rlib"] [dependencies] alloc = { path = "../alloc", public = true } cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } -bdwgc = { path = "../bdwgc" } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } diff --git a/library/std/src/gc.rs b/library/std/src/gc.rs index 8207372d6e722..b2a39d2b85d79 100644 --- a/library/std/src/gc.rs +++ b/library/std/src/gc.rs @@ -56,6 +56,7 @@ use core::{fmt, iter}; use crate::alloc::GC_COUNTERS; #[cfg(not(no_global_oom_handling))] use crate::alloc::{Global, handle_alloc_error}; +use crate::bdwgc; use crate::sync::{Condvar, Mutex}; #[cfg(feature = "log-stats")] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 47aac368fa039..bf14187c1f554 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -571,6 +571,8 @@ pub use core::unsafe_binder; #[allow(deprecated, deprecated_in_future)] pub use core::usize; +#[unstable(feature = "gc", issue = "none")] +pub use alloc_crate::bdwgc; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc_crate::borrow; #[stable(feature = "rust1", since = "1.0.0")] @@ -604,8 +606,6 @@ pub mod ascii; pub mod backtrace; #[unstable(feature = "bstr", issue = "134915")] pub mod bstr; -#[unstable(feature = "gc", issue = "none")] -use bdwgc; pub mod collections; pub mod env; pub mod error; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index f0cff2885ad3a..7033bf88b09fe 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -87,7 +87,7 @@ impl Thread { let ret = crate::bdwgc::GC_pthread_create( &mut native, - attr.as_ptr() as *const bdwgc::pthread_attr_t, + attr.as_ptr() as *const crate::bdwgc::pthread_attr_t, Some(thread_start), p as *mut _, ); @@ -323,7 +323,7 @@ impl Thread { pub fn join(self) { let id = self.into_id(); - let ret = unsafe { bdwgc::GC_pthread_join(id, ptr::null_mut()) }; + let ret = unsafe { crate::bdwgc::GC_pthread_join(id, ptr::null_mut()) }; assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret)); } @@ -338,7 +338,7 @@ impl Thread { impl Drop for Thread { fn drop(&mut self) { - let ret = unsafe { bdwgc::GC_pthread_detach(self.id) }; + let ret = unsafe { crate::bdwgc::GC_pthread_detach(self.id) }; debug_assert_eq!(ret, 0); } } diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 1cc9cf01a1c35..689c6dde003b4 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -11,7 +11,6 @@ proc_macro = { path = "../proc_macro", public = true } profiler_builtins = { path = "../profiler_builtins", optional = true } std = { path = "../std", public = true } test = { path = "../test", public = true } -bdwgc = { path = "../bdwgc", public = true } # Forward features to the `std` crate as necessary [features] diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs index 89a6636d9a0cc..8019e0f29564f 100644 --- a/tests/run-make/alloc-no-oom-handling/rmake.rs +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -11,5 +11,6 @@ fn main() { .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) .cfg("no_global_oom_handling") + .cfg("no_gc") .run(); } diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs index 12171c2148f1d..f514b5af5e65a 100644 --- a/tests/run-make/alloc-no-rc/rmake.rs +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -11,5 +11,6 @@ fn main() { .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) .cfg("no_rc") + .cfg("no_gc") .run(); } diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs index 29f204f30673e..e5d6e87fce0ca 100644 --- a/tests/run-make/alloc-no-sync/rmake.rs +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -11,5 +11,6 @@ fn main() { .crate_type("rlib") .input(source_root().join("library/alloc/src/lib.rs")) .cfg("no_sync") + .cfg("no_gc") .run(); } diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 73ad248b6f363..8e5c2cd752ef3 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -9,6 +9,7 @@ fn run_rustc() -> Rustc { .arg("-Clink-self-contained=-linker") .arg("-Zunstable-options") .arg("-Wlinker-messages") + .cfg("no_gc") .output("main") .linker("./fake-linker"); if run_make_support::target() == "x86_64-unknown-linux-gnu" { diff --git a/tests/run-make/linker-warning/short-error.txt b/tests/run-make/linker-warning/short-error.txt index 34cdb4519777e..c3cfb5c85b23a 100644 --- a/tests/run-make/linker-warning/short-error.txt +++ b/tests/run-make/linker-warning/short-error.txt @@ -1,6 +1,6 @@ error: linking with `./fake-linker` failed: exit status: 1 | - = note: "./fake-linker" "-m64" "/symbols.o" "-Wl,-rpath,/lib" "-Wl,-Bdynamic" "-Wl,--no-as-needed" "-lgc" "-Wl,--as-needed" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libbdwgc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgc" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/build-root/bdwgc/lib" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" + = note: "./fake-linker" "-m64" "/symbols.o" "-Wl,-rpath,/lib" "-Wl,-Bdynamic" "-Wl,--no-as-needed" "-lgc" "-Wl,--as-needed" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liballoc-*,libbdwgc-*,liblibc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lgc" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/build-root/bdwgc/lib" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: error: baz From 942a788007c4dad86dfa8a46fb3460e4391a2501 Mon Sep 17 00:00:00 2001 From: Jake Hughes Date: Wed, 11 Jun 2025 16:15:59 +0100 Subject: [PATCH 2/2] Remove unused libstd features Building libgc now happens inside the bootstrapper which handles the relevant build args. --- library/bdwgc/Cargo.toml | 5 ----- library/std/Cargo.toml | 2 -- library/sysroot/Cargo.toml | 2 -- src/bootstrap/src/lib.rs | 6 ------ 4 files changed, 15 deletions(-) diff --git a/library/bdwgc/Cargo.toml b/library/bdwgc/Cargo.toml index cd14e93cec851..ac1d1e5c3076a 100644 --- a/library/bdwgc/Cargo.toml +++ b/library/bdwgc/Cargo.toml @@ -14,8 +14,3 @@ libc = { version = "0.2.148", default-features = false, features = ['rustc-dep-o [build-dependencies] cmake = "0.1" - -[features] -link-shared = [] -gc-assertions = [] -gc-debug = [] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 141a70710d4ce..666205f253763 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -107,8 +107,6 @@ log-stats = ["alloc/log-stats"] premature-finalizer-prevention = [] premature-finalizer-prevention-optimize = [] finalizer-elision = [] -bdwgc-assertions = ["bdwgc/gc-assertions"] -bdwgc-debug = ["bdwgc/gc-debug"] bdwgc-disable = [] # Make panics and failed asserts immediately abort without formatting any message diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 689c6dde003b4..10da3c36ca530 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -38,6 +38,4 @@ 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"] -bdwgc-assertions = ["std/bdwgc-assertions"] -bdwgc-debug = ["std/bdwgc-debug"] bdwgc-disable = ["std/bdwgc-disable"] diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 2f287889c60c6..0ff54dbfd2adb 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -692,12 +692,6 @@ impl Build { if self.config.premature_finalizer_prevention_optimize { features.insert("premature-finalizer-prevention-optimize"); } - if self.config.bdwgc_assertions { - features.insert("bdwgc-assertions"); - } - if self.config.bdwgc_debug { - features.insert("bdwgc-debug"); - } if self.config.bdwgc_disable { features.insert("bdwgc-disable"); }