Skip to content

Commit 83aef6e

Browse files
committed
Scanning all tasks; enabling threads and rounding tests
1 parent bbbd583 commit 83aef6e

File tree

4 files changed

+275
-92
lines changed

4 files changed

+275
-92
lines changed

.github/scripts/ci-test-other.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ declare -a tests_to_skip=(
2323
"cmdlineargs"
2424
"Downloads"
2525
"read"
26-
"threads"
26+
# "threads"
2727
"LibCURL"
28-
"rounding"
28+
# "rounding"
2929
"loading"
3030
"misc"
3131
)

mmtk/src/collection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ impl Collection<JuliaVM> for VMCollection {
9292
// unpin conservative roots
9393
crate::conservative::unpin_conservative_roots();
9494

95+
// empty root tasks
96+
let mut root_tasks = crate::scanning::TASK_ROOTS.lock().unwrap();
97+
root_tasks.clear();
98+
9599
// Get the end time of the GC
96100
let end = unsafe { jl_hrtime() };
97101
trace!("gc_end = {}", end);

mmtk/src/julia_scanning.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,24 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
246246

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

249+
#[cfg(debug_assertions)]
250+
{
251+
if !cfg!(feature = "non_moving") {
252+
// Panic if task has not been processed as root
253+
use crate::scanning::TASK_ROOTS;
254+
let task_roots = TASK_ROOTS.lock().unwrap();
255+
256+
let task_objref =
257+
ObjectReference::from_raw_address_unchecked(Address::from_ptr(ta));
258+
if !task_roots.contains(&task_objref) {
259+
panic!(
260+
"Task {} being scanned was not processed as root!",
261+
task_objref
262+
);
263+
}
264+
}
265+
}
266+
249267
mmtk_scan_gcstack(ta, closure, None);
250268

251269
let layout = (*jl_task_type).layout;
@@ -519,6 +537,123 @@ pub unsafe fn mmtk_scan_gcpreserve_stack<EV: SlotVisitor<JuliaVMSlot>>(
519537
}
520538
}
521539

540+
// Scan the shadow stack for root tasks possibly capturing
541+
// more tasks that will also need to be scanned
542+
pub unsafe fn mmtk_scan_gcstack_roots<'a, EV: SlotVisitor<JuliaVMSlot>>(
543+
ta: *const jl_task_t,
544+
mut closure: &'a mut EV,
545+
mut pclosure: Option<&'a mut EV>,
546+
extra_root_tasks: &mut Vec<ObjectReference>,
547+
) {
548+
// process Julia's standard shadow (GC) stack
549+
let stkbuf = (*ta).ctx.stkbuf;
550+
let copy_stack = (*ta).ctx.copy_stack_custom();
551+
552+
#[cfg(feature = "julia_copy_stack")]
553+
if !stkbuf.is_null() && copy_stack != 0 {
554+
let stkbuf_slot = Address::from_ptr(::std::ptr::addr_of!((*ta).ctx.stkbuf));
555+
process_slot(closure, stkbuf_slot);
556+
}
557+
558+
let mut s = (*ta).gcstack;
559+
let (mut offset, mut lb, mut ub) = (0_isize, 0_u64, u64::MAX);
560+
561+
#[cfg(feature = "julia_copy_stack")]
562+
if !stkbuf.is_null() && copy_stack != 0 && (*ta).ptls.is_null() {
563+
if ((*ta).tid._M_i) < 0 {
564+
panic!("tid must be positive.")
565+
}
566+
let stackbase = jl_gc_get_stackbase((*ta).tid._M_i);
567+
ub = stackbase as u64;
568+
lb = ub - ((*ta).ctx.copy_stack() as u64);
569+
offset = (*ta).ctx.stkbuf as isize - lb as isize;
570+
}
571+
572+
if !s.is_null() {
573+
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
574+
let mut nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
575+
debug_assert!(nroots.as_usize() as u32 <= u32::MAX);
576+
let mut nr = nroots >> 3;
577+
578+
loop {
579+
// if the 'pin' bit on the root type is not set, must transitively pin
580+
// and therefore use transitive pinning closure
581+
let closure_to_use: &mut &mut EV = if (nroots.as_usize() & 4) == 0 {
582+
&mut closure
583+
} else {
584+
// otherwise, use the pinning closure (if available)
585+
match &mut pclosure {
586+
Some(c) => c,
587+
None => &mut closure,
588+
}
589+
};
590+
591+
let rts = Address::from_mut_ptr(s).shift::<Address>(2);
592+
let mut i = 0;
593+
while i < nr {
594+
if (nroots.as_usize() & 1) != 0 {
595+
let slot = read_stack(rts.shift::<Address>(i as isize), offset, lb, ub);
596+
let real_addr = get_stack_addr(slot, offset, lb, ub);
597+
process_slot(*closure_to_use, real_addr);
598+
capture_potential_task(real_addr, extra_root_tasks);
599+
} else {
600+
let real_addr =
601+
get_stack_addr(rts.shift::<Address>(i as isize), offset, lb, ub);
602+
603+
let slot = read_stack(rts.shift::<Address>(i as isize), offset, lb, ub);
604+
use crate::julia_finalizer::gc_ptr_tag;
605+
// malloced pointer tagged in jl_gc_add_quiescent
606+
// skip both the next element (native function), and the object
607+
if slot & 3usize == 3 {
608+
i += 2;
609+
continue;
610+
}
611+
612+
// pointer is not malloced but function is native, so skip it
613+
if gc_ptr_tag(slot, 1) {
614+
process_offset_slot(*closure_to_use, real_addr, 1);
615+
i += 2;
616+
continue;
617+
}
618+
619+
process_slot(*closure_to_use, real_addr);
620+
capture_potential_task(real_addr, extra_root_tasks);
621+
}
622+
623+
i += 1;
624+
}
625+
626+
let s_prev_address = ::std::ptr::addr_of!((*s).prev);
627+
let sprev = read_stack(Address::from_ptr(s_prev_address), offset, lb, ub);
628+
if sprev.is_zero() {
629+
break;
630+
}
631+
632+
s = sprev.to_mut_ptr::<jl_gcframe_t>();
633+
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
634+
let new_nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
635+
nroots = new_nroots;
636+
nr = nroots >> 3;
637+
continue;
638+
}
639+
}
640+
}
641+
642+
pub unsafe fn capture_potential_task(addr: Address, extra_root_tasks: &mut Vec<ObjectReference>) {
643+
use mmtk::vm::slot::Slot;
644+
let simple_slot = SimpleSlot::from_address(addr);
645+
646+
if let Some(objref) = simple_slot.load() {
647+
let obj = objref.to_raw_address();
648+
let vtag_usize = mmtk_jl_typetagof(obj).as_usize();
649+
650+
if vtag_usize == ((jl_small_typeof_tags_jl_task_tag as usize) << 4) {
651+
log::info!("Task {} occurs in shadow stack!", objref);
652+
extra_root_tasks.push(objref);
653+
}
654+
}
655+
}
656+
522657
pub unsafe fn mmtk_scan_gcstack<'a, EV: SlotVisitor<JuliaVMSlot>>(
523658
ta: *const jl_task_t,
524659
mut closure: &'a mut EV,

0 commit comments

Comments
 (0)