@@ -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 ) ;
@@ -375,9 +375,10 @@ unsafe fn mmtk_jl_genericmemory_data_owner_field_address(m: *const jl_genericmem
375
375
// mmtk_jl_genericmemory_data_owner_field_address(m).load::<*const mmtk_jl_value_t>()
376
376
// }
377
377
378
- pub unsafe fn mmtk_scan_gcstack < EV : SlotVisitor < JuliaVMSlot > > (
378
+ pub unsafe fn mmtk_scan_gcstack < ' a , EV : SlotVisitor < JuliaVMSlot > > (
379
379
ta : * const jl_task_t ,
380
- closure : & mut EV ,
380
+ mut closure : & ' a mut EV ,
381
+ mut pclosure : Option < & ' a mut EV > ,
381
382
) {
382
383
let stkbuf = ( * ta) . ctx . stkbuf ;
383
384
let copy_stack = ( * ta) . ctx . copy_stack_custom ( ) ;
@@ -406,16 +407,28 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
406
407
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
407
408
let mut nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
408
409
debug_assert ! ( nroots. as_usize( ) as u32 <= std:: u32 :: MAX ) ;
409
- let mut nr = nroots >> 2 ;
410
+ let mut nr = nroots >> 3 ;
410
411
411
412
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
+
412
425
let rts = Address :: from_mut_ptr ( s) . shift :: < Address > ( 2 ) ;
413
426
let mut i = 0 ;
414
427
while i < nr {
415
428
if ( nroots. as_usize ( ) & 1 ) != 0 {
416
429
let slot = read_stack ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
417
430
let real_addr = get_stack_addr ( slot, offset, lb, ub) ;
418
- process_slot ( closure , real_addr) ;
431
+ process_slot ( * closure_to_use , real_addr) ;
419
432
} else {
420
433
let real_addr =
421
434
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>>(
431
444
432
445
// pointer is not malloced but function is native, so skip it
433
446
if gc_ptr_tag ( slot, 1 ) {
434
- process_offset_slot ( closure , real_addr, 1 ) ;
447
+ process_offset_slot ( * closure_to_use , real_addr, 1 ) ;
435
448
i += 2 ;
436
449
continue ;
437
450
}
438
451
439
- process_slot ( closure , real_addr) ;
452
+ process_slot ( * closure_to_use , real_addr) ;
440
453
}
441
454
442
455
i += 1 ;
@@ -452,7 +465,7 @@ pub unsafe fn mmtk_scan_gcstack<EV: SlotVisitor<JuliaVMSlot>>(
452
465
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
453
466
let new_nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
454
467
nroots = new_nroots;
455
- nr = nroots >> 2 ;
468
+ nr = nroots >> 3 ;
456
469
continue ;
457
470
}
458
471
}
0 commit comments