@@ -162,7 +162,7 @@ pub unsafe fn scan_julia_object<SV: SlotVisitor<JuliaVMSlot>>(obj: Address, clos
162162
163163 let ta = obj. to_ptr :: < jl_task_t > ( ) ;
164164
165- mmtk_scan_gcstack ( ta, closure) ;
165+ mmtk_scan_gcstack ( ta, closure, None ) ;
166166
167167 let layout = ( * jl_task_type) . layout ;
168168 debug_assert ! ( ( * layout) . fielddesc_type_custom( ) == 0 ) ;
@@ -375,9 +375,10 @@ unsafe fn mmtk_jl_genericmemory_data_owner_field_address(m: *const jl_genericmem
375375// mmtk_jl_genericmemory_data_owner_field_address(m).load::<*const mmtk_jl_value_t>()
376376// }
377377
378- pub unsafe fn mmtk_scan_gcstack < EV : SlotVisitor < JuliaVMSlot > > (
378+ pub unsafe fn mmtk_scan_gcstack < ' a , EV : SlotVisitor < JuliaVMSlot > > (
379379 ta : * const jl_task_t ,
380- closure : & mut EV ,
380+ mut closure : & ' a mut EV ,
381+ mut pclosure : Option < & ' a mut EV > ,
381382) {
382383 let stkbuf = ( * ta) . ctx . stkbuf ;
383384 let copy_stack = ( * ta) . ctx . copy_stack_custom ( ) ;
@@ -406,16 +407,28 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
406407 let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
407408 let mut nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
408409 debug_assert ! ( nroots. as_usize( ) as u32 <= std:: u32 :: MAX ) ;
409- let mut nr = nroots >> 2 ;
410+ let mut nr = nroots >> 3 ;
410411
411412 loop {
413+ // if the 'pin' bit on the root type is not set, must transitively pin
414+ // and therefore use transitive pinning closure
415+ let closure_to_use: & mut & mut EV = if ( nroots. as_usize ( ) & 4 ) == 0 {
416+ & mut closure
417+ } else {
418+ // otherwise, use the pinning closure (if available)
419+ match & mut pclosure {
420+ Some ( c) => c,
421+ None => & mut closure,
422+ }
423+ } ;
424+
412425 let rts = Address :: from_mut_ptr ( s) . shift :: < Address > ( 2 ) ;
413426 let mut i = 0 ;
414427 while i < nr {
415428 if ( nroots. as_usize ( ) & 1 ) != 0 {
416429 let slot = read_stack ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
417430 let real_addr = get_stack_addr ( slot, offset, lb, ub) ;
418- process_slot ( closure , real_addr) ;
431+ process_slot ( * closure_to_use , real_addr) ;
419432 } else {
420433 let real_addr =
421434 get_stack_addr ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
@@ -431,12 +444,12 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
431444
432445 // pointer is not malloced but function is native, so skip it
433446 if gc_ptr_tag ( slot, 1 ) {
434- process_offset_slot ( closure , real_addr, 1 ) ;
447+ process_offset_slot ( * closure_to_use , real_addr, 1 ) ;
435448 i += 2 ;
436449 continue ;
437450 }
438451
439- process_slot ( closure , real_addr) ;
452+ process_slot ( * closure_to_use , real_addr) ;
440453 }
441454
442455 i += 1 ;
@@ -452,7 +465,7 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
452465 let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
453466 let new_nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
454467 nroots = new_nroots;
455- nr = nroots >> 2 ;
468+ nr = nroots >> 3 ;
456469 continue ;
457470 }
458471 }
0 commit comments