@@ -62,6 +62,27 @@ pub unsafe fn mmtk_jl_to_typeof(t: Address) -> *const jl_datatype_t {
62
62
t. to_ptr :: < jl_datatype_t > ( )
63
63
}
64
64
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
+
65
86
const PRINT_OBJ_TYPE : bool = false ;
66
87
67
88
// This function is a rewrite of `gc_mark_outrefs()` in `gc.c`
@@ -214,24 +235,8 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
214
235
}
215
236
let vt = vtag. to_ptr :: < jl_datatype_t > ( ) ;
216
237
if ( * vt) . name == jl_array_typename {
217
- let a = obj. to_ptr :: < jl_array_t > ( ) ;
218
- let memref = ( * a) . ref_ ;
219
-
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
- }
238
+ let a = obj. to_mut_ptr :: < jl_array_t > ( ) ;
239
+ trace_ptr_or_offset_in_genericmemoryref ( closure, & mut ( * a) . ref_ ) ;
235
240
}
236
241
if ( * vt) . name == jl_genericmemory_typename {
237
242
if PRINT_OBJ_TYPE {
@@ -363,6 +368,11 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
363
368
return ;
364
369
}
365
370
371
+ if ( * vt) . name == jl_genericmemoryref_typename {
372
+ let gmr = obj. to_mut_ptr :: < jl_genericmemoryref_t > ( ) ;
373
+ trace_ptr_or_offset_in_genericmemoryref ( closure, gmr) ;
374
+ }
375
+
366
376
if PRINT_OBJ_TYPE {
367
377
println ! ( "scan_julia_obj {}: datatype\n " , obj) ;
368
378
}
0 commit comments