Skip to content

Commit 4340bc9

Browse files
committed
Trace ptr_or_offset for jl_genericmemoryref_t
1 parent 4ada9ec commit 4340bc9

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

mmtk/src/julia_scanning.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ pub unsafe fn mmtk_jl_to_typeof(t: Address) -> *const jl_datatype_t {
6262
t.to_ptr::<jl_datatype_t>()
6363
}
6464

65+
// The type jl_genericmemoryref_t potentially has two pointers (ptr_or_offset, and mem).
66+
// But Julia only identifies it with one single pointer (mem). We need to make sure ptr_or_offset is also traced.
67+
// This function only traces ptr_or_offset, and still leaves mem to the generic trace for data types.
68+
fn trace_ptr_or_offset_in_genericmemoryref<SV: SlotVisitor<JuliaVMSlot>>(closure: &mut SV, r: *mut jl_genericmemoryref_t) {
69+
unsafe {
70+
if mmtk_object_is_managed_by_mmtk((*r).ptr_or_offset as usize) {
71+
let ptr_or_ref_slot = Address::from_ptr(::std::ptr::addr_of!((*r).ptr_or_offset));
72+
let mem_addr_as_usize = (*r).mem as usize;
73+
let ptr_or_offset_as_usize = (*r).ptr_or_offset as usize;
74+
if ptr_or_offset_as_usize > mem_addr_as_usize {
75+
let offset = ptr_or_offset_as_usize - mem_addr_as_usize;
76+
77+
// Only update the offset pointer if the offset is valid (> 0)
78+
if offset > 0 {
79+
process_offset_slot(closure, ptr_or_ref_slot, offset);
80+
}
81+
}
82+
}
83+
}
84+
}
85+
6586
const PRINT_OBJ_TYPE: bool = false;
6687

6788
// This function is a rewrite of `gc_mark_outrefs()` in `gc.c`
@@ -217,21 +238,7 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
217238
let a = obj.to_ptr::<jl_array_t>();
218239
let memref = (*a).ref_;
219240

220-
let ptr_or_offset = memref.ptr_or_offset;
221-
// if the object moves its pointer inside the array object (void* ptr_or_offset) needs to be updated as well
222-
if mmtk_object_is_managed_by_mmtk(ptr_or_offset as usize) {
223-
let ptr_or_ref_slot = Address::from_ptr(::std::ptr::addr_of!((*a).ref_.ptr_or_offset));
224-
let mem_addr_as_usize = memref.mem as usize;
225-
let ptr_or_offset_as_usize = ptr_or_offset as usize;
226-
if ptr_or_offset_as_usize > mem_addr_as_usize {
227-
let offset = ptr_or_offset_as_usize - mem_addr_as_usize;
228-
229-
// Only update the offset pointer if the offset is valid (> 0)
230-
if offset > 0 {
231-
process_offset_slot(closure, ptr_or_ref_slot, offset);
232-
}
233-
}
234-
}
241+
trace_ptr_or_offset_in_genericmemoryref(closure, &mut (*a).ref_);
235242
}
236243
if (*vt).name == jl_genericmemory_typename {
237244
if PRINT_OBJ_TYPE {
@@ -363,6 +370,11 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
363370
return;
364371
}
365372

373+
if (*vt).name == jl_genericmemoryref_typename {
374+
let gmr = obj.to_mut_ptr::<jl_genericmemoryref_t>();
375+
trace_ptr_or_offset_in_genericmemoryref(closure, gmr);
376+
}
377+
366378
if PRINT_OBJ_TYPE {
367379
println!("scan_julia_obj {}: datatype\n", obj);
368380
}

0 commit comments

Comments
 (0)