Skip to content

Commit 62fff57

Browse files
committed
Deal with GC preserve stacks (#191)
This PR ports #156 to `dev`.
1 parent 3f242b5 commit 62fff57

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ julia/*.o
33
julia/*.dbj.obj
44
.vscode
55
mmtk/src/julia_types.rs
6-

mmtk/src/julia_scanning.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,68 @@ unsafe fn mmtk_jl_genericmemory_data_owner_field_address(m: *const jl_genericmem
373373
// mmtk_jl_genericmemory_data_owner_field_address(m).load::<*const mmtk_jl_value_t>()
374374
// }
375375

376+
pub unsafe fn mmtk_scan_gcpreserve_stack<'a, EV: SlotVisitor<JuliaVMSlot>>(
377+
ta: *const jl_task_t,
378+
closure: &'a mut EV,
379+
) {
380+
// process transitively pinning stack
381+
let mut s = (*ta).gcpreserve_stack;
382+
let (offset, lb, ub) = (0 as isize, 0 as u64, u64::MAX);
383+
384+
if s != std::ptr::null_mut() {
385+
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
386+
let mut nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
387+
debug_assert!(nroots.as_usize() <= u32::MAX as usize);
388+
let mut nr = nroots >> 3;
389+
390+
loop {
391+
let rts = Address::from_mut_ptr(s).shift::<Address>(2);
392+
let mut i = 0;
393+
394+
while i < nr {
395+
let real_addr = get_stack_addr(rts.shift::<Address>(i as isize), offset, lb, ub);
396+
397+
let slot = read_stack(rts.shift::<Address>(i as isize), offset, lb, ub);
398+
use crate::julia_finalizer::gc_ptr_tag;
399+
// malloced pointer tagged in jl_gc_add_quiescent
400+
// skip both the next element (native function), and the object
401+
if slot & 3usize == 3 {
402+
i += 2;
403+
continue;
404+
}
405+
406+
// pointer is not malloced but function is native, so skip it
407+
if gc_ptr_tag(slot, 1) {
408+
i += 2;
409+
continue;
410+
}
411+
412+
process_slot(closure, real_addr);
413+
i += 1;
414+
}
415+
416+
let s_prev_address = ::std::ptr::addr_of!((*s).prev);
417+
let sprev = read_stack(Address::from_ptr(s_prev_address), offset, lb, ub);
418+
if sprev.is_zero() {
419+
break;
420+
}
421+
422+
s = sprev.to_mut_ptr::<jl_gcframe_t>();
423+
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
424+
let new_nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
425+
nroots = new_nroots;
426+
nr = nroots >> 3;
427+
continue;
428+
}
429+
}
430+
}
431+
376432
pub unsafe fn mmtk_scan_gcstack<'a, EV: SlotVisitor<JuliaVMSlot>>(
377433
ta: *const jl_task_t,
378434
mut closure: &'a mut EV,
379435
mut pclosure: Option<&'a mut EV>,
380436
) {
437+
// process Julia's standard shadow (GC) stack
381438
let stkbuf = (*ta).ctx.stkbuf;
382439
let copy_stack = (*ta).ctx.copy_stack_custom();
383440

mmtk/src/scanning.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ impl Scanning<JuliaVM> for VMScanning {
6161
let mut root_scan_task = |task: *const _jl_task_t, task_is_root: bool| {
6262
if !task.is_null() {
6363
unsafe {
64+
crate::julia_scanning::mmtk_scan_gcpreserve_stack(
65+
task,
66+
&mut tpinning_slot_buffer,
67+
);
6468
crate::julia_scanning::mmtk_scan_gcstack(
6569
task,
6670
&mut tpinning_slot_buffer,

0 commit comments

Comments
 (0)