Skip to content

Commit 6ef356a

Browse files
committed
Enable copying GC
1 parent 8fd50fd commit 6ef356a

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

mmtk/src/abi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ pub struct RubyBindingOptions {
273273
pub struct RubyUpcalls {
274274
pub init_gc_worker_thread: extern "C" fn(gc_worker_tls: *mut GCThreadTLS),
275275
pub get_gc_thread_tls: extern "C" fn() -> *mut GCThreadTLS,
276+
pub is_mutator: extern "C" fn() -> bool,
276277
pub stop_the_world: extern "C" fn(tls: VMWorkerThread),
277278
pub resume_mutators: extern "C" fn(tls: VMWorkerThread),
278279
pub block_for_gc: extern "C" fn(tls: VMMutatorThread),

mmtk/src/active_plan.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ impl ActivePlan<Ruby> for VMActivePlan {
1818
}
1919

2020
fn is_mutator(_tls: VMThread) -> bool {
21-
// FIXME
22-
true
21+
(upcalls().is_mutator)()
2322
}
2423

2524
fn mutator(_tls: VMMutatorThread) -> &'static mut Mutator<Ruby> {

mmtk/src/binding.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::ffi::CString;
22
use std::sync::Mutex;
33

4-
use mmtk::MMTK;
4+
use mmtk::util::ObjectReference;
5+
use mmtk::{memory_manager, MMTK};
56

67
use crate::abi;
78
use crate::abi::RubyBindingOptions;
@@ -27,6 +28,7 @@ pub struct RubyBinding {
2728
pub plan_name: Mutex<Option<CString>>,
2829
pub weak_proc: WeakProcessor,
2930
pub ppp_registry: PPPRegistry,
31+
pub(crate) pinned_roots: Mutex<Vec<ObjectReference>>,
3032
}
3133

3234
unsafe impl Sync for RubyBinding {}
@@ -48,6 +50,7 @@ impl RubyBinding {
4850
plan_name: Mutex::new(None),
4951
weak_proc: WeakProcessor::new(),
5052
ppp_registry: PPPRegistry::new(),
53+
pinned_roots: Default::default(),
5154
}
5255
}
5356

@@ -65,4 +68,16 @@ impl RubyBinding {
6568
}
6669
plan_name.as_deref().unwrap().as_ptr()
6770
}
71+
72+
pub(crate) fn unpin_pinned_roots(&self) {
73+
let mut pinned_roots = self
74+
.pinned_roots
75+
.try_lock()
76+
.expect("It is accessed during weak ref processing. Should have no race.");
77+
78+
for object in pinned_roots.drain(..) {
79+
let result = memory_manager::unpin_object::<Ruby>(object);
80+
debug_assert!(result);
81+
}
82+
}
6883
}

mmtk/src/scanning.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{upcalls, Ruby, RubyEdge};
44
use mmtk::scheduler::GCWorker;
55
use mmtk::util::{ObjectReference, VMWorkerThread};
66
use mmtk::vm::{EdgeVisitor, ObjectTracer, RootsWorkFactory, Scanning};
7-
use mmtk::{Mutator, MutatorContext};
7+
use mmtk::{memory_manager, Mutator, MutatorContext};
88

99
pub struct VMScanning {}
1010

@@ -33,8 +33,13 @@ impl Scanning<Ruby> for VMScanning {
3333
"Not an MMTk object: {object}",
3434
);
3535
let gc_tls = unsafe { GCThreadTLS::from_vwt_check(tls) };
36-
let visit_object = |_worker, target_object: ObjectReference, _pin| {
37-
trace!("Tracing object: {} -> {}", object, target_object);
36+
let visit_object = |_worker, target_object: ObjectReference, pin| {
37+
trace!(
38+
"Tracing object: {} -> {}{}",
39+
object,
40+
target_object,
41+
if pin { " pin" } else { "" }
42+
);
3843
debug_assert!(
3944
mmtk::memory_manager::is_mmtk_object(target_object.to_raw_address()),
4045
"Destination is not an MMTk object. Src: {object} dst: {target_object}"
@@ -90,6 +95,7 @@ impl Scanning<Ruby> for VMScanning {
9095
.weak_proc
9196
.process_weak_stuff(worker, tracer_context);
9297
crate::binding().ppp_registry.cleanup_ppps();
98+
crate::binding().unpin_pinned_roots();
9399
false
94100
}
95101

@@ -111,8 +117,21 @@ impl VMScanning {
111117
callback: F,
112118
) {
113119
let mut buffer: Vec<ObjectReference> = Vec::new();
114-
let visit_object = |_, object: ObjectReference, _pin| {
115-
debug!("[{}] Scanning object: {}", root_scan_kind, object);
120+
let mut my_pinned_roots = vec![];
121+
let visit_object = |_, object: ObjectReference, pin| {
122+
debug!(
123+
"[{}] Visiting object: {}{}",
124+
root_scan_kind,
125+
object,
126+
if pin {
127+
"(unmovable root)"
128+
} else {
129+
"(movable, but we pin it anyway)"
130+
}
131+
);
132+
if memory_manager::pin_object::<Ruby>(object) {
133+
my_pinned_roots.push(object);
134+
}
116135
buffer.push(object);
117136
if buffer.len() >= Self::OBJECT_BUFFER_SIZE {
118137
factory.create_process_node_roots_work(std::mem::take(&mut buffer));
@@ -122,8 +141,20 @@ impl VMScanning {
122141
gc_tls
123142
.object_closure
124143
.set_temporarily_and_run_code(visit_object, callback);
144+
125145
if !buffer.is_empty() {
126146
factory.create_process_node_roots_work(buffer);
127147
}
148+
149+
info!(
150+
"Pinned {} node roots during {}",
151+
my_pinned_roots.len(),
152+
root_scan_kind
153+
);
154+
155+
{
156+
let mut pinned_roots = crate::binding().pinned_roots.lock().unwrap();
157+
pinned_roots.append(&mut my_pinned_roots);
158+
}
128159
}
129160
}

0 commit comments

Comments
 (0)