@@ -64,6 +64,44 @@ pub unsafe fn mmtk_jl_to_typeof(t: Address) -> *const jl_datatype_t {
64
64
65
65
const PRINT_OBJ_TYPE : bool = false ;
66
66
67
+ trait ValidOffset : Copy {
68
+ fn to_isize ( self ) -> isize ;
69
+ }
70
+ impl ValidOffset for u8 {
71
+ #[ inline]
72
+ fn to_isize ( self ) -> isize {
73
+ self as isize
74
+ }
75
+ }
76
+ impl ValidOffset for u16 {
77
+ #[ inline]
78
+ fn to_isize ( self ) -> isize {
79
+ self as isize
80
+ }
81
+ }
82
+ impl ValidOffset for u32 {
83
+ #[ inline]
84
+ fn to_isize ( self ) -> isize {
85
+ self as isize
86
+ }
87
+ }
88
+ unsafe fn scan_julia_obj_n < T > (
89
+ obj : Address ,
90
+ begin : Address ,
91
+ end : Address ,
92
+ closure : & mut impl SlotVisitor < JuliaVMSlot > ,
93
+ ) where
94
+ T : ValidOffset ,
95
+ {
96
+ let mut ptr = begin;
97
+ while ptr < end {
98
+ let offset = ptr. load :: < T > ( ) ;
99
+ let slot = obj. shift :: < Address > ( offset. to_isize ( ) ) ;
100
+ process_slot ( closure, slot) ;
101
+ ptr = ptr. shift :: < T > ( 1 ) ;
102
+ }
103
+ }
104
+
67
105
// This function is a rewrite of `gc_mark_outrefs()` in `gc.c`
68
106
// INFO: *_custom() functions are acessors to bitfields that do not use bindgen generated code.
69
107
#[ inline( always) ]
@@ -182,15 +220,9 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
182
220
debug_assert ! ( ( * layout) . fielddesc_type_custom( ) == 0 ) ;
183
221
debug_assert ! ( ( * layout) . nfields > 0 ) ;
184
222
let npointers = ( * layout) . npointers ;
185
- let mut obj8_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
223
+ let obj8_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
186
224
let obj8_end = obj8_begin. shift :: < u8 > ( npointers as isize ) ;
187
-
188
- while obj8_begin < obj8_end {
189
- let obj8_begin_loaded = obj8_begin. load :: < u8 > ( ) ;
190
- let slot = obj. shift :: < Address > ( obj8_begin_loaded as isize ) ;
191
- process_slot ( closure, slot) ;
192
- obj8_begin = obj8_begin. shift :: < u8 > ( 1 ) ;
193
- }
225
+ scan_julia_obj_n :: < u8 > ( obj, obj8_begin, obj8_end, closure) ;
194
226
} else if vtag_usize == ( ( jl_small_typeof_tags_jl_string_tag as usize ) << 4 )
195
227
&& PRINT_OBJ_TYPE
196
228
{
@@ -378,39 +410,25 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
378
410
( * layout) . nfields > 0 && ( * layout) . fielddesc_type_custom( ) != 3 ,
379
411
"opaque types should have been handled specially"
380
412
) ;
381
- if ( * layout) . fielddesc_type_custom ( ) == 0 {
382
- let mut obj8_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
383
- let obj8_end = obj8_begin. shift :: < u8 > ( npointers as isize ) ;
384
-
385
- while obj8_begin < obj8_end {
386
- let obj8_begin_loaded = obj8_begin. load :: < u8 > ( ) ;
387
- let slot = obj. shift :: < Address > ( obj8_begin_loaded as isize ) ;
388
- process_slot ( closure, slot) ;
389
- obj8_begin = obj8_begin. shift :: < u8 > ( 1 ) ;
413
+ let obj_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
414
+ let obj_end;
415
+ match ( * layout) . fielddesc_type_custom ( ) {
416
+ 0 => {
417
+ obj_end = obj_begin. shift :: < u8 > ( npointers as isize ) ;
418
+ scan_julia_obj_n :: < u8 > ( obj, obj_begin, obj_end, closure) ;
390
419
}
391
- } else if ( * layout) . fielddesc_type_custom ( ) == 1 {
392
- let mut obj16_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
393
- let obj16_end = obj16_begin. shift :: < u16 > ( npointers as isize ) ;
394
-
395
- while obj16_begin < obj16_end {
396
- let obj16_begin_loaded = obj16_begin. load :: < u16 > ( ) ;
397
- let slot = obj. shift :: < Address > ( obj16_begin_loaded as isize ) ;
398
- process_slot ( closure, slot) ;
399
- obj16_begin = obj16_begin. shift :: < u16 > ( 1 ) ;
420
+ 1 => {
421
+ obj_end = obj_begin. shift :: < u16 > ( npointers as isize ) ;
422
+ scan_julia_obj_n :: < u16 > ( obj, obj_begin, obj_end, closure) ;
400
423
}
401
- } else if ( * layout) . fielddesc_type_custom ( ) == 2 {
402
- let mut obj32_begin = mmtk_jl_dt_layout_ptrs ( layout) ;
403
- let obj32_end = obj32_begin. shift :: < u32 > ( npointers as isize ) ;
404
-
405
- while obj32_begin < obj32_end {
406
- let obj32_begin_loaded = obj32_begin. load :: < u32 > ( ) ;
407
- let slot = obj. shift :: < Address > ( obj32_begin_loaded as isize ) ;
408
- process_slot ( closure, slot) ;
409
- obj32_begin = obj32_begin. shift :: < u32 > ( 1 ) ;
424
+ 2 => {
425
+ obj_end = obj_begin. shift :: < u32 > ( npointers as isize ) ;
426
+ scan_julia_obj_n :: < u32 > ( obj, obj_begin, obj_end, closure) ;
427
+ }
428
+ _ => {
429
+ debug_assert ! ( ( * layout) . fielddesc_type_custom( ) == 3 ) ;
430
+ unimplemented ! ( ) ;
410
431
}
411
- } else {
412
- debug_assert ! ( ( * layout) . fielddesc_type_custom( ) == 3 ) ;
413
- unimplemented ! ( ) ;
414
432
}
415
433
}
416
434
}
0 commit comments