Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process GC preserve #156

Merged
merged 10 commits into from
Jun 25, 2024
2 changes: 2 additions & 0 deletions julia/mmtk_julia_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,8 @@ typedef struct mmtk__jl_task_t {
int8_t threadpoolid;
// saved gc stack top for context switches
mmtk_jl_gcframe_t *gcstack;
// stack of objects (not slots) that need to be transitively pinned
mmtk_jl_gcframe_t *tpin_gcstack;
size_t world_age;
// quick lookup for current ptls
void* ptls; // == jl_all_tls_states[tid]
Expand Down
4 changes: 2 additions & 2 deletions mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ edition = "2018"
# Metadata for the Julia repository
[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 = "88fea475d9639820488f6dd50fcb08c60a011899"
julia_repo = "https://github.com/udesou/julia.git"
julia_version = "0558e64792ace533e7dccacb903ed03d2b5a51c3"

[lib]
crate-type = ["cdylib"]
Expand Down
1 change: 1 addition & 0 deletions mmtk/api/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern void mmtk_unreachable(void);
extern unsigned char mmtk_pin_object(void* obj);
extern bool mmtk_is_pinned(void* obj);


extern void mmtk_set_vm_space(void* addr, size_t size);
extern void mmtk_immortal_region_post_alloc(void* addr, size_t size);

Expand Down
58 changes: 40 additions & 18 deletions mmtk/src/julia_scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,20 @@ pub unsafe fn scan_julia_object<EV: EdgeVisitor<JuliaVMEdge>>(obj: Address, clos

pub unsafe fn mmtk_scan_gcstack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
ta: *const mmtk_jl_task_t,
mut closure: &'a mut EV,
mut pclosure: Option<&'a mut EV>,
closure: &'a mut EV,
pclosure: Option<&'a mut EV>,
) {
// process transitively pinning stack first
let pinning_closure = if let Some(c) = pclosure {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest having a separate method mmtk_scan_tpin_gcstack or something, and deal with the new stack there. The current code is too confusing: the tpin_gcstack is scanned with the normal closure when pclosure has a value. Creating a new function to scan tpin_gcstack and only pass the closure that is needed to the new function.

// only do this when scanning stack roots
// will not need the pinning closure, since everything on this stack will have to be transitively pinning
scan_stack((*ta).tpin_gcstack, 0, u64::MAX, 0, closure, None);
Some(c)
} else {
None
};

// process Julia's standard shadow (GC) stack
let stkbuf = (*ta).stkbuf;
let copy_stack = (*ta).copy_stack_custom();

Expand All @@ -370,7 +381,6 @@ pub unsafe fn mmtk_scan_gcstack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
process_edge(closure, stkbuf_edge);
}

let mut s = (*ta).gcstack;
let (mut offset, mut lb, mut ub) = (0 as isize, 0 as u64, u64::MAX);

#[cfg(feature = "julia_copy_stack")]
Expand All @@ -384,8 +394,29 @@ pub unsafe fn mmtk_scan_gcstack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
offset = (*ta).stkbuf as isize - lb as isize;
}

if s != std::ptr::null_mut() {
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
// process Julia's gc shadow stack
scan_stack((*ta).gcstack, lb, ub, offset, closure, pinning_closure);

// just call into C, since the code is cold
if (*ta).excstack != std::ptr::null_mut() {
((*UPCALLS).scan_julia_exc_obj)(
Address::from_ptr(ta),
Address::from_mut_ptr(closure),
process_edge::<EV> as _,
);
}
}

unsafe fn scan_stack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
mut stack: *mut mmtk__jl_gcframe_t,
lb: u64,
ub: u64,
offset: isize,
mut closure: &'a mut EV,
mut pclosure: Option<&'a mut EV>,
) {
if stack != std::ptr::null_mut() {
let s_nroots_addr = ::std::ptr::addr_of!((*stack).nroots);
let mut nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
debug_assert!(nroots.as_usize() as u32 <= UINT32_MAX);
let mut nr = nroots >> 3;
Expand All @@ -403,7 +434,7 @@ pub unsafe fn mmtk_scan_gcstack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
}
};

let rts = Address::from_mut_ptr(s).shift::<Address>(2);
let rts = Address::from_mut_ptr(stack).shift::<Address>(2);
let mut i = 0;
while i < nr {
if (nroots.as_usize() & 1) != 0 {
Expand Down Expand Up @@ -436,29 +467,20 @@ pub unsafe fn mmtk_scan_gcstack<'a, EV: EdgeVisitor<JuliaVMEdge>>(
i += 1;
}

let s_prev_address = ::std::ptr::addr_of!((*s).prev);
let s_prev_address = ::std::ptr::addr_of!((*stack).prev);
let sprev = read_stack(Address::from_ptr(s_prev_address), offset, lb, ub);
if sprev.is_zero() {
break;
}

s = sprev.to_mut_ptr::<mmtk_jl_gcframe_t>();
let s_nroots_addr = ::std::ptr::addr_of!((*s).nroots);
stack = sprev.to_mut_ptr::<mmtk_jl_gcframe_t>();
let s_nroots_addr = ::std::ptr::addr_of!((*stack).nroots);
let new_nroots = read_stack(Address::from_ptr(s_nroots_addr), offset, lb, ub);
nroots = new_nroots;
nr = nroots >> 3;
continue;
}
}

// just call into C, since the code is cold
if (*ta).excstack != std::ptr::null_mut() {
((*UPCALLS).scan_julia_exc_obj)(
Address::from_ptr(ta),
Address::from_mut_ptr(closure),
process_edge::<EV> as _,
);
}
}

#[inline(always)]
Expand Down
38 changes: 24 additions & 14 deletions mmtk/src/julia_types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* automatically generated by rust-bindgen 0.63.0 */
/* automatically generated by rust-bindgen 0.69.4 */

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -3663,7 +3663,6 @@ fn bindgen_test_layout_mmtk__jl_taggedvalue_t() {
);
}
#[repr(C)]
#[repr(align(2))]
#[derive(Debug, Copy, Clone)]
pub struct mmtk_jl_array_flags_t {
pub _bitfield_align_1: [u16; 0],
Expand Down Expand Up @@ -6478,6 +6477,7 @@ pub struct mmtk__jl_task_t {
pub tid: u16,
pub threadpoolid: i8,
pub gcstack: *mut mmtk_jl_gcframe_t,
pub tpin_gcstack: *mut mmtk_jl_gcframe_t,
pub world_age: usize,
pub ptls: *mut ::std::os::raw::c_void,
pub excstack: *mut mmtk_jl_excstack_t,
Expand All @@ -6497,7 +6497,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<mmtk__jl_task_t>(),
376usize,
384usize,
concat!("Size of: ", stringify!(mmtk__jl_task_t))
);
assert_eq!(
Expand Down Expand Up @@ -6656,8 +6656,18 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).world_age) as usize - ptr as usize },
unsafe { ::std::ptr::addr_of!((*ptr).tpin_gcstack) as usize - ptr as usize },
112usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
"::",
stringify!(tpin_gcstack)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).world_age) as usize - ptr as usize },
120usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6667,7 +6677,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).ptls) as usize - ptr as usize },
120usize,
128usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6677,7 +6687,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).excstack) as usize - ptr as usize },
128usize,
136usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6687,7 +6697,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).eh) as usize - ptr as usize },
136usize,
144usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6697,7 +6707,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).ctx) as usize - ptr as usize },
144usize,
152usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6707,7 +6717,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).stkbuf) as usize - ptr as usize },
344usize,
352usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6717,7 +6727,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).bufsz) as usize - ptr as usize },
352usize,
360usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6727,7 +6737,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).inference_start_time) as usize - ptr as usize },
360usize,
368usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6737,7 +6747,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).reentrant_inference) as usize - ptr as usize },
368usize,
376usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand All @@ -6747,7 +6757,7 @@ fn bindgen_test_layout_mmtk__jl_task_t() {
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).reentrant_timing) as usize - ptr as usize },
370usize,
378usize,
concat!(
"Offset of field: ",
stringify!(mmtk__jl_task_t),
Expand Down Expand Up @@ -6833,7 +6843,7 @@ pub union mmtk___jl_purity_overrides_t {
pub overrides: mmtk___jl_purity_overrides_t__bindgen_ty_1,
pub bits: u8,
}
#[repr(C, packed)]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct mmtk___jl_purity_overrides_t__bindgen_ty_1 {
pub _bitfield_align_1: [u8; 0],
Expand Down
Loading