Skip to content

Commit

Permalink
Process pinning roots - port PR #142 (#192)
Browse files Browse the repository at this point in the history
Port #142 to `dev`. Process both
transitively pinning roots, and non transitively pinning roots.
  • Loading branch information
qinsoon authored Nov 7, 2024
1 parent 5918de4 commit eeb9f7f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 13 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.idea/
julia/*.o
julia/*.dbj.obj
.vscode
.vscode
mmtk/src/julia_types.rs

2 changes: 1 addition & 1 deletion mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ edition = "2018"
[package.metadata.julia]
# Our CI matches the following line and extract mmtk/julia. If this line is updated, please check ci yaml files and make sure it works.
julia_repo = "https://github.com/mmtk/julia.git"
julia_version = "0517ff8d7981202989ef055296ad42c52a79b758"
julia_version = "7a953be76af34dee24e17cf2b33ba5fb0a7eac02"

[lib]
crate-type = ["cdylib"]
Expand Down
29 changes: 21 additions & 8 deletions mmtk/src/julia_scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos

let ta = obj.to_ptr::<jl_task_t>();

mmtk_scan_gcstack(ta, closure);
mmtk_scan_gcstack(ta, closure, None);

let layout = (*jl_task_type).layout;
debug_assert!((*layout).fielddesc_type_custom() == 0);
Expand Down Expand Up @@ -375,9 +375,10 @@ unsafe fn mmtk_jl_genericmemory_data_owner_field_address(m: *const jl_genericmem
// mmtk_jl_genericmemory_data_owner_field_address(m).load::<*const mmtk_jl_value_t>()
// }

pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
pub unsafe fn mmtk_scan_gcstack<'a, EV: SlotVisitor<JuliaVMSlot>>(
ta: *const jl_task_t,
closure: &mut EV,
mut closure: &'a mut EV,
mut pclosure: Option<&'a mut EV>,
) {
let stkbuf = (*ta).ctx.stkbuf;
let copy_stack = (*ta).ctx.copy_stack_custom();
Expand Down Expand Up @@ -406,16 +407,28 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
let mut nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
debug_assert!(nroots.as_usize() as u32 <= std::u32::MAX);
let mut nr = nroots >> 2;
let mut nr = nroots >> 3;

loop {
// if the 'pin' bit on the root type is not set, must transitively pin
// and therefore use transitive pinning closure
let closure_to_use: &mut &mut EV = if (nroots.as_usize() & 4) == 0 {
&mut closure
} else {
// otherwise, use the pinning closure (if available)
match &mut pclosure {
Some(c) => c,
None => &mut closure,
}
};

let rts = Address::from_mut_ptr(s).shift::<Address>(2);
let mut i = 0;
while i < nr {
if (nroots.as_usize() & 1) != 0 {
let slot = read_stack(rts.shift::<Address>(i as isize), offset, lb, ub);
let real_addr = get_stack_addr(slot, offset, lb, ub);
process_slot(closure, real_addr);
process_slot(*closure_to_use, real_addr);
} else {
let real_addr =
get_stack_addr(rts.shift::<Address>(i as isize), offset, lb, ub);
Expand All @@ -431,12 +444,12 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(

// pointer is not malloced but function is native, so skip it
if gc_ptr_tag(slot, 1) {
process_offset_slot(closure, real_addr, 1);
process_offset_slot(*closure_to_use, real_addr, 1);
i += 2;
continue;
}

process_slot(closure, real_addr);
process_slot(*closure_to_use, real_addr);
}

i += 1;
Expand All @@ -452,7 +465,7 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
let new_nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
nroots = new_nroots;
nr = nroots >> 2;
nr = nroots >> 3;
continue;
}
}
Expand Down
18 changes: 15 additions & 3 deletions mmtk/src/scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,19 @@ impl Scanning<JuliaVM> for VMScanning {
use mmtk::util::Address;

let ptls: &mut _jl_tls_states_t = unsafe { std::mem::transmute(mutator.mutator_tls) };
let mut slot_buffer = SlotBuffer { buffer: vec![] }; // need to be tpinned as they're all from the shadow stack
let mut tpinning_slot_buffer = SlotBuffer { buffer: vec![] }; // need to be transitively pinned
let mut pinning_slot_buffer = SlotBuffer { buffer: vec![] }; // roots from the shadow stack that we know that do not need to be transitively pinned
let mut node_buffer = vec![];

// Scan thread local from ptls: See gc_queue_thread_local in gc.c
let mut root_scan_task = |task: *const _jl_task_t, task_is_root: bool| {
if !task.is_null() {
unsafe {
crate::julia_scanning::mmtk_scan_gcstack(task, &mut slot_buffer);
crate::julia_scanning::mmtk_scan_gcstack(
task,
&mut tpinning_slot_buffer,
Some(&mut pinning_slot_buffer),
);
}
if task_is_root {
// captures wrong root nodes before creating the work
Expand Down Expand Up @@ -134,13 +139,20 @@ impl Scanning<JuliaVM> for VMScanning {

// Push work
const CAPACITY_PER_PACKET: usize = 4096;
for tpinning_roots in slot_buffer
for tpinning_roots in tpinning_slot_buffer
.buffer
.chunks(CAPACITY_PER_PACKET)
.map(|c| c.to_vec())
{
factory.create_process_tpinning_roots_work(tpinning_roots);
}
for pinning_roots in pinning_slot_buffer
.buffer
.chunks(CAPACITY_PER_PACKET)
.map(|c| c.to_vec())
{
factory.create_process_pinning_roots_work(pinning_roots);
}
for nodes in node_buffer.chunks(CAPACITY_PER_PACKET).map(|c| c.to_vec()) {
factory.create_process_pinning_roots_work(nodes);
}
Expand Down

0 comments on commit eeb9f7f

Please sign in to comment.