@@ -162,7 +162,7 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
162
162
163
163
let ta = obj. to_ptr :: < jl_task_t > ( ) ;
164
164
165
- mmtk_scan_gcstack ( ta, closure) ;
165
+ mmtk_scan_gcstack ( ta, closure, None ) ;
166
166
167
167
let layout = ( * jl_task_type) . layout ;
168
168
debug_assert ! ( ( * layout) . fielddesc_type_custom( ) == 0 ) ;
@@ -373,9 +373,10 @@ unsafe fn mmtk_jl_genericmemory_data_owner_field_address(m: *const jl_genericmem
373
373
// mmtk_jl_genericmemory_data_owner_field_address(m).load::<*const mmtk_jl_value_t>()
374
374
// }
375
375
376
- pub unsafe fn mmtk_scan_gcstack < EV : SlotVisitor < JuliaVMSlot > > (
376
+ pub unsafe fn mmtk_scan_gcstack < ' a , EV : SlotVisitor < JuliaVMSlot > > (
377
377
ta : * const jl_task_t ,
378
- closure : & mut EV ,
378
+ mut closure : & ' a mut EV ,
379
+ mut pclosure : Option < & ' a mut EV > ,
379
380
) {
380
381
let stkbuf = ( * ta) . ctx . stkbuf ;
381
382
let copy_stack = ( * ta) . ctx . copy_stack_custom ( ) ;
@@ -404,16 +405,28 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
404
405
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
405
406
let mut nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
406
407
debug_assert ! ( nroots. as_usize( ) as u32 <= u32 :: MAX ) ;
407
- let mut nr = nroots >> 2 ;
408
+ let mut nr = nroots >> 3 ;
408
409
409
410
loop {
411
+ // if the 'pin' bit on the root type is not set, must transitively pin
412
+ // and therefore use transitive pinning closure
413
+ let closure_to_use: & mut & mut EV = if ( nroots. as_usize ( ) & 4 ) == 0 {
414
+ & mut closure
415
+ } else {
416
+ // otherwise, use the pinning closure (if available)
417
+ match & mut pclosure {
418
+ Some ( c) => c,
419
+ None => & mut closure,
420
+ }
421
+ } ;
422
+
410
423
let rts = Address :: from_mut_ptr ( s) . shift :: < Address > ( 2 ) ;
411
424
let mut i = 0 ;
412
425
while i < nr {
413
426
if ( nroots. as_usize ( ) & 1 ) != 0 {
414
427
let slot = read_stack ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
415
428
let real_addr = get_stack_addr ( slot, offset, lb, ub) ;
416
- process_slot ( closure , real_addr) ;
429
+ process_slot ( * closure_to_use , real_addr) ;
417
430
} else {
418
431
let real_addr =
419
432
get_stack_addr ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
@@ -429,12 +442,12 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
429
442
430
443
// pointer is not malloced but function is native, so skip it
431
444
if gc_ptr_tag ( slot, 1 ) {
432
- process_offset_slot ( closure , real_addr, 1 ) ;
445
+ process_offset_slot ( * closure_to_use , real_addr, 1 ) ;
433
446
i += 2 ;
434
447
continue ;
435
448
}
436
449
437
- process_slot ( closure , real_addr) ;
450
+ process_slot ( * closure_to_use , real_addr) ;
438
451
}
439
452
440
453
i += 1 ;
@@ -450,7 +463,7 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
450
463
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
451
464
let new_nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
452
465
nroots = new_nroots;
453
- nr = nroots >> 2 ;
466
+ nr = nroots >> 3 ;
454
467
continue ;
455
468
}
456
469
}
0 commit comments