forked from mmtk/mmtk-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinding.rs
111 lines (97 loc) · 3.06 KB
/
binding.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::collections::HashMap;
use std::ffi::CString;
use std::sync::atomic::AtomicBool;
use std::sync::Mutex;
use std::thread::JoinHandle;
use libc::c_void;
use mmtk::util::ObjectReference;
use mmtk::MMTK;
use crate::abi;
use crate::abi::RubyBindingOptions;
use crate::ppp::PPPRegistry;
use crate::weak_proc::WeakProcessor;
use crate::Ruby;
pub struct RubyBindingFast {
pub gc_enabled: AtomicBool,
}
impl RubyBindingFast {
pub const fn new() -> Self {
Self {
// Mimic the old behavior when the gc_enabled flag was in mmtk-core.
// We may refactor it so that it is false by default.
gc_enabled: AtomicBool::new(true),
}
}
}
pub struct RubyBindingFastMut {
pub suffix_size: usize,
}
impl RubyBindingFastMut {
pub const fn new() -> Self {
Self { suffix_size: 0 }
}
}
pub(crate) struct MovedGIVTblEntry {
pub old_objref: ObjectReference,
pub gen_ivtbl: *mut c_void,
}
pub struct RubyBinding {
pub mmtk: &'static MMTK<Ruby>,
pub options: RubyBindingOptions,
pub upcalls: *const abi::RubyUpcalls,
pub plan_name: Mutex<Option<CString>>,
pub weak_proc: WeakProcessor,
pub ppp_registry: PPPRegistry,
pub(crate) moved_givtbl: Mutex<HashMap<ObjectReference, MovedGIVTblEntry>>,
pub gc_thread_join_handles: Mutex<Vec<JoinHandle<()>>>,
}
unsafe impl Sync for RubyBinding {}
unsafe impl Send for RubyBinding {}
impl RubyBinding {
pub fn new(
mmtk: &'static MMTK<Ruby>,
binding_options: &RubyBindingOptions,
upcalls: *const abi::RubyUpcalls,
) -> Self {
unsafe {
crate::BINDING_FAST_MUT.suffix_size = binding_options.suffix_size;
}
Self {
mmtk,
options: binding_options.clone(),
upcalls,
plan_name: Mutex::new(None),
weak_proc: WeakProcessor::new(),
ppp_registry: PPPRegistry::new(),
moved_givtbl: Default::default(),
gc_thread_join_handles: Default::default(),
}
}
pub fn upcalls(&self) -> &'static abi::RubyUpcalls {
unsafe { &*self.upcalls as &'static abi::RubyUpcalls }
}
pub fn get_plan_name_c(&self) -> *const libc::c_char {
let mut plan_name = self.plan_name.lock().unwrap();
if plan_name.is_none() {
let name_string = format!("{:?}", *self.mmtk.get_options().plan);
let c_string = CString::new(name_string)
.unwrap_or_else(|e| panic!("Failed converting plan name to CString: {e}"));
*plan_name = Some(c_string);
}
plan_name.as_deref().unwrap().as_ptr()
}
pub fn join_all_gc_threads(&self) {
let handles = {
let mut guard = self.gc_thread_join_handles.lock().unwrap();
std::mem::take(&mut *guard)
};
debug!("Joining GC threads...");
let total = handles.len();
let mut joined = 0;
for handle in handles {
handle.join().unwrap();
joined += 1;
debug!("{joined}/{total} GC threads joined.");
}
}
}