Skip to content

Commit

Permalink
Remove traces of Alloy from library/alloc
Browse files Browse the repository at this point in the history
Having parts of GC code in both library/std and library/alloc is a
hangover from before and overly complicates linking. In order to apply
some of the optimisations that we want on for off-thread finalisation,
we must first fix this.

This commit simply shuffles code around and renames things.
  • Loading branch information
jacob-hughes committed Mar 18, 2024
1 parent 5b00d25 commit 9dbe8c0
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 161 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ dependencies = [
name = "alloc"
version = "0.0.0"
dependencies = [
"bdwgc",
"compiler_builtins",
"core",
"rand",
Expand Down Expand Up @@ -280,8 +279,8 @@ version = "0.1.0"
dependencies = [
"cmake",
"compiler_builtins",
"core",
"libc",
"rustc-std-workspace-core",
]

[[package]]
Expand Down
1 change: 0 additions & 1 deletion library/alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ autobenches = false
edition = "2021"

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

Expand Down
134 changes: 0 additions & 134 deletions library/alloc/src/gc.rs

This file was deleted.

7 changes: 0 additions & 7 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,6 @@ extern crate test;
#[cfg(test)]
mod testing;

#[allow(unused_extern_crates)]
#[allow(missing_docs)]
#[unstable(feature = "gc", issue = "none")]
pub extern crate bdwgc;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;
Expand All @@ -250,8 +245,6 @@ pub mod collections;
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
pub mod ffi;
pub mod fmt;
#[unstable(feature = "gc", issue = "none")]
pub mod gc;
#[cfg(not(no_rc))]
pub mod rc;
pub mod slice;
Expand Down
2 changes: 1 addition & 1 deletion library/bdwgc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
license = "Apache-2.0 OR MIT"

[dependencies]
core = { path = "../core" }
core = { version = "1.0.0", package = 'rustc-std-workspace-core' }
compiler_builtins = { version = "0.1.10", features = ['rustc-dep-of-std'] }
libc = { version = "0.2.148", default-features = false, features = ['rustc-dep-of-std'], public = true }

Expand Down
3 changes: 0 additions & 3 deletions library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ use core::{mem, ptr};
#[doc(inline)]
pub use alloc_crate::alloc::*;

#[unstable(feature = "gc", issue = "none")]
pub use alloc_crate::gc::GcAllocator;

/// The default memory allocator provided by the operating system.
///
/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
Expand Down
124 changes: 120 additions & 4 deletions library/std/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,20 @@
#![allow(missing_docs)]

use core::{
alloc::{AllocError, Allocator, GlobalAlloc, Layout},
any::Any,
cell::RefCell,
cmp::Ordering,
cmp::{self, Ordering},
fmt,
hash::{Hash, Hasher},
marker::{FinalizerSafe, PhantomData, Unsize},
mem::{transmute, MaybeUninit},
ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver},
ptr::{drop_in_place, null_mut, NonNull},
ptr::{self, drop_in_place, null_mut, NonNull},
};

use crate::{sync::mpsc, sync::mpsc::Sender, thread};

pub use alloc::gc::thread_registered;
pub use alloc::gc::GcAllocator;
pub use core::gc::*;

#[cfg(profile_gc)]
Expand All @@ -66,6 +65,123 @@ static FINALIZERS_REGISTERED: AtomicU64 = AtomicU64::new(0);
#[cfg(profile_gc)]
static FINALIZERS_COMPLETED: AtomicU64 = AtomicU64::new(0);

////////////////////////////////////////////////////////////////////////////////
// BDWGC Allocator
////////////////////////////////////////////////////////////////////////////////

// Fast-path for low alignment values
pub const MIN_ALIGN: usize = 8;

#[derive(Debug)]
pub struct GcAllocator;

unsafe impl GlobalAlloc for GcAllocator {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
unsafe { gc_malloc(layout) }
}

#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { gc_free(ptr, layout) }
}

#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
unsafe { gc_realloc(ptr, layout, new_size) }
}
}

#[inline]
unsafe fn gc_malloc(layout: Layout) -> *mut u8 {
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
unsafe { bdwgc::GC_malloc(layout.size()) as *mut u8 }
} else {
let mut out = ptr::null_mut();
// posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
// Since these are all powers of 2, we can just use max.
unsafe {
let align = layout.align().max(core::mem::size_of::<usize>());
let ret = bdwgc::GC_posix_memalign(&mut out, align, layout.size());
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
}
}
}

#[inline]
unsafe fn gc_realloc(ptr: *mut u8, old_layout: Layout, new_size: usize) -> *mut u8 {
if old_layout.align() <= MIN_ALIGN && old_layout.align() <= new_size {
unsafe { bdwgc::GC_realloc(ptr, new_size) as *mut u8 }
} else {
unsafe {
let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align());

let new_ptr = gc_malloc(new_layout);
if !new_ptr.is_null() {
let size = cmp::min(old_layout.size(), new_size);
ptr::copy_nonoverlapping(ptr, new_ptr, size);
gc_free(ptr, old_layout);
}
new_ptr
}
}
}

#[inline]
unsafe fn gc_free(ptr: *mut u8, layout: Layout) {
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
unsafe {
bdwgc::GC_free(ptr);
}
} else {
unsafe {
bdwgc::GC_free(bdwgc::GC_base(ptr));
}
}
}

unsafe impl Allocator for GcAllocator {
#[inline]
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
match layout.size() {
0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)),
size => unsafe {
let ptr = gc_malloc(layout);
let ptr = NonNull::new(ptr).ok_or(AllocError)?;
Ok(NonNull::slice_from_raw_parts(ptr, size))
},
}
}

unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout) {}
}

impl GcAllocator {
pub fn force_gc() {
unsafe { bdwgc::GC_gcollect() }
}
}

////////////////////////////////////////////////////////////////////////////////
// Free functions
////////////////////////////////////////////////////////////////////////////////

pub fn init() {
unsafe { bdwgc::GC_init() }
}

pub fn suppress_warnings() {
unsafe { bdwgc::GC_set_warn_proc(&bdwgc::GC_ignore_warn_proc as *const _ as *mut u8) };
}

pub fn thread_registered() -> bool {
unsafe { bdwgc::GC_thread_is_registered() != 0 }
}

////////////////////////////////////////////////////////////////////////////////
// GC API
////////////////////////////////////////////////////////////////////////////////

struct GcBox<T: ?Sized>(T);

/// A multi-threaded garbage collected pointer.
Expand Down
5 changes: 2 additions & 3 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,16 +559,15 @@ pub use core::u8;
#[allow(deprecated, deprecated_in_future)]
pub use core::usize;

#[unstable(feature = "gc", issue = "none")]
pub use alloc_crate::gc::GcAllocator;

pub mod f32;
pub mod f64;

#[macro_use]
pub mod thread;
pub mod ascii;
pub mod backtrace;
#[unstable(feature = "gc", issue = "none")]
use bdwgc;
pub mod collections;
pub mod env;
pub mod error;
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// Rust's stack overflow handler will unregister and return if there is
// no stack overflow, allowing the fault to "fall-through" to Boehm's
// handler next time. The is not true in the reverse case.
alloc::gc::init();
crate::gc::init();

sys::init(argc, argv, sigpipe);

Expand Down
Loading

0 comments on commit 9dbe8c0

Please sign in to comment.