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

Revert current off-thread finalisation mechanism and disable parallel marking #116

Merged
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
2 changes: 2 additions & 0 deletions library/bdwgc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ extern "C" {

pub fn GC_init();

pub fn GC_set_markers_count(count: usize);

pub fn GC_set_warn_proc(level: *mut u8);

pub fn GC_tls_rootset() -> *mut u8;
Expand Down
99 changes: 37 additions & 62 deletions library/std/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,15 @@
use core::{
alloc::{AllocError, Allocator, GlobalAlloc, Layout},
any::Any,
cell::RefCell,
cmp::{self, Ordering},
fmt,
hash::{Hash, Hasher},
marker::{FinalizerSafe, PhantomData, Unsize},
mem::{transmute, MaybeUninit},
mem::MaybeUninit,
ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver},
ptr::{self, drop_in_place, null_mut, NonNull},
};

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

pub use core::gc::*;

#[cfg(profile_gc)]
Expand Down Expand Up @@ -167,6 +164,7 @@ impl GcAllocator {
////////////////////////////////////////////////////////////////////////////////

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

Expand Down Expand Up @@ -377,15 +375,11 @@ impl<T> Gc<T> {
#[cfg(profile_gc)]
FINALIZERS_REGISTERED.fetch_add(1, atomic::Ordering::Relaxed);

// This function gets called by Boehm when an object becomes unreachable.
unsafe extern "C" fn finalizer<T>(object: *mut u8, _meta: *mut u8) {
unsafe extern "C" fn finalizer<T>(obj: *mut u8, _meta: *mut u8) {
unsafe {
let cb = finalizer_callback::<T>;
let fo = FinalizableObj {
callback: transmute(cb as unsafe extern "C" fn(*mut T)),
object,
};
FINALIZER_QUEUE.with(|q| q.borrow().as_ref().unwrap().send(fo).unwrap());
drop_in_place(obj as *mut T);
#[cfg(profile_gc)]
FINALIZERS_COMPLETED.fetch_add(1, atomic::Ordering::Relaxed);
}
}

Expand All @@ -399,6 +393,37 @@ impl<T> Gc<T> {
)
}
}

#[unstable(feature = "gc", issue = "none")]
pub fn unregister_finalizer(&mut self) {
let ptr = self.ptr.as_ptr() as *mut GcBox<T> as *mut u8;
unsafe {
bdwgc::GC_register_finalizer(
ptr,
None,
::core::ptr::null_mut(),
::core::ptr::null_mut(),
::core::ptr::null_mut(),
);
}
}
}

#[cfg(profile_gc)]
#[derive(Debug)]
pub struct FinalizerInfo {
pub registered: u64,
pub completed: u64,
}

#[cfg(profile_gc)]
impl FinalizerInfo {
pub fn finalizer_info() -> FinalizerInfo {
FinalizerInfo {
registered: FINALIZERS_REGISTERED.load(atomic::Ordering::Relaxed),
completed: FINALIZERS_COMPLETED.load(atomic::Ordering::Relaxed),
}
}
}

impl Gc<dyn Any> {
Expand Down Expand Up @@ -755,53 +780,3 @@ impl<T: ?Sized> AsRef<T> for Gc<T> {
&**self
}
}

thread_local! {
pub static FINALIZER_QUEUE: RefCell<Option<FinalizerQueue>> = RefCell::new(None);
}

type FinalizerQueue = Sender<FinalizableObj>;

#[derive(Debug)]
pub struct FinalizableObj {
callback: FinalizerCallback,
object: *mut u8,
}

unsafe impl Send for FinalizableObj {}

pub(crate) fn init_finalization_thread() {
let (sender, receiver) = mpsc::channel();
FINALIZER_QUEUE.with(|q| *q.borrow_mut() = Some(sender));

thread::spawn(move || {
for finalisable in receiver.iter() {
unsafe { (finalisable.callback)(finalisable.object) };
}
});
}

unsafe extern "C" fn finalizer_callback<T>(obj: *mut T) {
unsafe { drop_in_place(obj as *mut T) };
#[cfg(profile_gc)]
FINALIZERS_COMPLETED.fetch_add(1, atomic::Ordering::Relaxed);
}

type FinalizerCallback = unsafe extern "C" fn(data: *mut u8);

#[cfg(profile_gc)]
#[derive(Debug)]
pub struct FinalizerInfo {
pub registered: u64,
pub completed: u64,
}

#[cfg(profile_gc)]
impl FinalizerInfo {
pub fn finalizer_info() -> FinalizerInfo {
FinalizerInfo {
registered: FINALIZERS_REGISTERED.load(atomic::Ordering::Relaxed),
completed: FINALIZERS_COMPLETED.load(atomic::Ordering::Relaxed),
}
}
}
2 changes: 0 additions & 2 deletions library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,6 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// info about the stack bounds.
let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
thread_info::set(main_guard, thread);

crate::gc::init_finalization_thread();
}
}

Expand Down
6 changes: 0 additions & 6 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ use crate::any::Any;
use crate::cell::UnsafeCell;
use crate::ffi::{CStr, CString};
use crate::fmt;
use crate::gc::FINALIZER_QUEUE;
use crate::io;
use crate::marker::PhantomData;
use crate::mem::{self, forget};
Expand Down Expand Up @@ -513,16 +512,11 @@ impl Builder {
}

let f = MaybeDangling::new(f);

let fin_q_sender = FINALIZER_QUEUE.with(|q| q.borrow().clone());

let main = move || {
if let Some(name) = their_thread.cname() {
imp::Thread::set_name(name);
}

FINALIZER_QUEUE.with(|q| *q.borrow_mut() = fin_q_sender);

crate::io::set_output_capture(output_capture);

// SAFETY: we constructed `f` initialized.
Expand Down
2 changes: 1 addition & 1 deletion src/bdwgc