@@ -278,7 +278,9 @@ pub unsafe fn scan_julia_object<EV: EdgeVisitor<JuliaVMEdge>>(obj: Address, clos
278
278
279
279
let ta = obj. to_ptr :: < mmtk_jl_task_t > ( ) ;
280
280
281
- mmtk_scan_gcstack ( ta, closure) ;
281
+ // transitively pinnig of stack roots happens during root
282
+ // processing so it's fine to have only one closure here
283
+ mmtk_scan_gcstack ( ta, closure, None ) ;
282
284
283
285
let layout = ( * jl_task_type) . layout ;
284
286
debug_assert ! ( ( * layout) . fielddesc_type( ) == 0 ) ;
@@ -354,9 +356,10 @@ pub unsafe fn scan_julia_object<EV: EdgeVisitor<JuliaVMEdge>>(obj: Address, clos
354
356
}
355
357
}
356
358
357
- pub unsafe fn mmtk_scan_gcstack < EV : EdgeVisitor < JuliaVMEdge > > (
359
+ pub unsafe fn mmtk_scan_gcstack < ' a , EV : EdgeVisitor < JuliaVMEdge > > (
358
360
ta : * const mmtk_jl_task_t ,
359
- closure : & mut EV ,
361
+ mut closure : & ' a mut EV ,
362
+ mut pclosure : Option < & ' a mut EV > ,
360
363
) {
361
364
let stkbuf = ( * ta) . stkbuf ;
362
365
let copy_stack = ( * ta) . copy_stack_custom ( ) ;
@@ -385,16 +388,28 @@ pub unsafe fn mmtk_scan_gcstack<EV: EdgeVisitor<JuliaVMEdge>>(
385
388
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
386
389
let mut nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
387
390
debug_assert ! ( nroots. as_usize( ) as u32 <= UINT32_MAX ) ;
388
- let mut nr = nroots >> 2 ;
391
+ let mut nr = nroots >> 3 ;
389
392
390
393
loop {
394
+ // if the 'pin' bit on the root type is not set, must transitively pin
395
+ // and therefore use transitive pinning closure
396
+ let closure_to_use: & mut & mut EV = if ( nroots. as_usize ( ) & 4 ) == 0 {
397
+ & mut closure
398
+ } else {
399
+ // otherwise, use the pinning closure (if available)
400
+ match & mut pclosure {
401
+ Some ( c) => c,
402
+ None => & mut closure,
403
+ }
404
+ } ;
405
+
391
406
let rts = Address :: from_mut_ptr ( s) . shift :: < Address > ( 2 ) ;
392
407
let mut i = 0 ;
393
408
while i < nr {
394
409
if ( nroots. as_usize ( ) & 1 ) != 0 {
395
410
let slot = read_stack ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
396
411
let real_addr = get_stack_addr ( slot, offset, lb, ub) ;
397
- process_edge ( closure , real_addr) ;
412
+ process_edge ( * closure_to_use , real_addr) ;
398
413
} else {
399
414
let real_addr =
400
415
get_stack_addr ( rts. shift :: < Address > ( i as isize ) , offset, lb, ub) ;
@@ -410,12 +425,12 @@ pub unsafe fn mmtk_scan_gcstack<EV: EdgeVisitor<JuliaVMEdge>>(
410
425
411
426
// pointer is not malloced but function is native, so skip it
412
427
if gc_ptr_tag ( slot, 1 ) {
413
- process_offset_edge ( closure , real_addr, 1 ) ;
428
+ process_offset_edge ( * closure_to_use , real_addr, 1 ) ;
414
429
i += 2 ;
415
430
continue ;
416
431
}
417
432
418
- process_edge ( closure , real_addr) ;
433
+ process_edge ( * closure_to_use , real_addr) ;
419
434
}
420
435
421
436
i += 1 ;
@@ -431,7 +446,7 @@ pub unsafe fn mmtk_scan_gcstack<EV: EdgeVisitor<JuliaVMEdge>>(
431
446
let s_nroots_addr = :: std:: ptr:: addr_of!( ( * s) . nroots) ;
432
447
let new_nroots = read_stack ( Address :: from_ptr ( s_nroots_addr) , offset, lb, ub) ;
433
448
nroots = new_nroots;
434
- nr = nroots >> 2 ;
449
+ nr = nroots >> 3 ;
435
450
continue ;
436
451
}
437
452
}
@@ -447,14 +462,14 @@ pub unsafe fn mmtk_scan_gcstack<EV: EdgeVisitor<JuliaVMEdge>>(
447
462
}
448
463
449
464
#[ inline( always) ]
450
- unsafe fn read_stack ( addr : Address , offset : isize , lb : u64 , ub : u64 ) -> Address {
465
+ pub unsafe fn read_stack ( addr : Address , offset : isize , lb : u64 , ub : u64 ) -> Address {
451
466
let real_addr = get_stack_addr ( addr, offset, lb, ub) ;
452
467
453
468
real_addr. load :: < Address > ( )
454
469
}
455
470
456
471
#[ inline( always) ]
457
- fn get_stack_addr ( addr : Address , offset : isize , lb : u64 , ub : u64 ) -> Address {
472
+ pub fn get_stack_addr ( addr : Address , offset : isize , lb : u64 , ub : u64 ) -> Address {
458
473
if addr. as_usize ( ) >= lb as usize && addr. as_usize ( ) < ub as usize {
459
474
return addr + offset;
460
475
} else {
0 commit comments