diff --git a/.gitignore b/.gitignore index 02fc026..6707474 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ julia/*.o julia/*.dbj.obj .vscode mmtk/src/julia_types.rs - diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index 5acf7bd..12e24c2 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -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 = "97828e0a7febe174fb6f0e569bd07509d977e446" +julia_version = "b4c8f5d443730d91c34785186c373ed3118cc7aa" [lib] crate-type = ["cdylib"] diff --git a/mmtk/src/julia_scanning.rs b/mmtk/src/julia_scanning.rs index 7c76895..903a098 100644 --- a/mmtk/src/julia_scanning.rs +++ b/mmtk/src/julia_scanning.rs @@ -375,11 +375,68 @@ 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_gcpreserve_stack<'a, EV: SlotVisitor>( + ta: *const jl_task_t, + closure: &'a mut EV, +) { + // process transitively pinning stack + let mut s = (*ta).gcpreserve_stack; + let (offset, lb, ub) = (0 as isize, 0 as u64, u64::MAX); + + if s != std::ptr::null_mut() { + 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() <= u32::MAX as usize); + let mut nr = nroots >> 3; + + loop { + let rts = Address::from_mut_ptr(s).shift::
(2); + let mut i = 0; + + while i < nr { + let real_addr = get_stack_addr(rts.shift::
(i as isize), offset, lb, ub); + + let slot = read_stack(rts.shift::
(i as isize), offset, lb, ub); + use crate::julia_finalizer::gc_ptr_tag; + // malloced pointer tagged in jl_gc_add_quiescent + // skip both the next element (native function), and the object + if slot & 3usize == 3 { + i += 2; + continue; + } + + // pointer is not malloced but function is native, so skip it + if gc_ptr_tag(slot, 1) { + i += 2; + continue; + } + + process_slot(closure, real_addr); + i += 1; + } + + let s_prev_address = ::std::ptr::addr_of!((*s).prev); + let sprev = read_stack(Address::from_ptr(s_prev_address), offset, lb, ub); + if sprev.is_zero() { + break; + } + + s = sprev.to_mut_ptr::(); + 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 >> 3; + continue; + } + } +} + pub unsafe fn mmtk_scan_gcstack<'a, EV: SlotVisitor>( ta: *const jl_task_t, mut closure: &'a mut EV, mut pclosure: Option<&'a mut EV>, ) { + // process Julia's standard shadow (GC) stack let stkbuf = (*ta).ctx.stkbuf; let copy_stack = (*ta).ctx.copy_stack_custom(); diff --git a/mmtk/src/scanning.rs b/mmtk/src/scanning.rs index 472c0d4..da2f348 100644 --- a/mmtk/src/scanning.rs +++ b/mmtk/src/scanning.rs @@ -61,6 +61,10 @@ impl Scanning for VMScanning { let mut root_scan_task = |task: *const _jl_task_t, task_is_root: bool| { if !task.is_null() { unsafe { + crate::julia_scanning::mmtk_scan_gcpreserve_stack( + task, + &mut tpinning_slot_buffer, + ); crate::julia_scanning::mmtk_scan_gcstack( task, &mut tpinning_slot_buffer,