@@ -485,39 +485,131 @@ pub extern "C" fn mmtk_get_obj_size(obj: ObjectReference) -> usize {
485
485
}
486
486
}
487
487
488
+ #[ allow( unused_variables) ]
489
+ fn assert_is_object ( object : ObjectReference ) {
490
+ // The checks are quite expensive. Dont run it in normal builds.
491
+ const ASSERT_OBJECT : bool = false ;
492
+ if ASSERT_OBJECT {
493
+ #[ cfg( debug_assertions) ]
494
+ {
495
+ use crate :: object_model:: { is_object_in_immixspace, is_object_in_los} ;
496
+ if !mmtk_object_is_managed_by_mmtk ( object. to_raw_address ( ) . as_usize ( ) ) {
497
+ panic ! ( "{} is not managed by MMTk" , object) ;
498
+ }
499
+ if !is_object_in_immixspace ( & object) && !is_object_in_los ( & object) {
500
+ // We will use VO bit in the following check. But if the object is not in immix space or LOS, we cannot do the check.
501
+ return ;
502
+ }
503
+ if !object
504
+ . to_raw_address ( )
505
+ . is_aligned_to ( ObjectReference :: ALIGNMENT )
506
+ {
507
+ panic ! (
508
+ "{} is not aligned, it cannot be an object reference" ,
509
+ object
510
+ )
511
+ }
512
+ if memory_manager:: is_mmtk_object ( object. to_raw_address ( ) ) . is_none ( ) {
513
+ error ! ( "{} is not an object" , object) ;
514
+ if let Some ( base_ref) = memory_manager:: find_object_from_internal_pointer (
515
+ object. to_raw_address ( ) ,
516
+ usize:: MAX ,
517
+ ) {
518
+ panic ! ( "{} is an internal pointer of {}" , object, base_ref) ;
519
+ } else {
520
+ panic ! (
521
+ "{} is not recognised as an object reference, or an internal reference" ,
522
+ object
523
+ ) ;
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
488
529
#[ no_mangle]
489
530
pub extern "C" fn mmtk_pin_object ( object : ObjectReference ) -> bool {
531
+ assert_is_object ( object) ;
532
+ crate :: early_return_for_non_moving_build!( false ) ;
533
+ memory_manager:: pin_object ( object)
534
+ }
535
+
536
+ #[ no_mangle]
537
+ pub extern "C" fn mmtk_unpin_object ( object : ObjectReference ) -> bool {
538
+ assert_is_object ( object) ;
539
+ crate :: early_return_for_non_moving_build!( false ) ;
540
+ memory_manager:: unpin_object ( object)
541
+ }
542
+
543
+ #[ no_mangle]
544
+ pub extern "C" fn mmtk_is_object_pinned ( object : ObjectReference ) -> bool {
545
+ assert_is_object ( object) ;
490
546
crate :: early_return_for_non_moving_build!( false ) ;
491
547
492
- // We may in the future replace this with a check for the immix space (bound check), which should be much cheaper.
493
- if mmtk_object_is_managed_by_mmtk ( object. to_raw_address ( ) . as_usize ( ) ) {
494
- memory_manager:: pin_object ( object)
548
+ memory_manager:: is_pinned ( object)
549
+ }
550
+
551
+ macro_rules! handle_potential_internal_pointer {
552
+ ( $func: path, $addr: expr) => { {
553
+ if $addr. is_aligned_to( ObjectReference :: ALIGNMENT ) {
554
+ if let Some ( obj) = memory_manager:: is_mmtk_object( $addr) {
555
+ return $func( obj) ;
556
+ }
557
+ }
558
+ let maybe_objref = memory_manager:: find_object_from_internal_pointer( $addr, usize :: MAX ) ;
559
+ if let Some ( obj) = maybe_objref {
560
+ trace!(
561
+ "Attempt to pin {:?}, but it is an internal reference of {:?}" ,
562
+ $addr,
563
+ obj
564
+ ) ;
565
+ $func( obj)
566
+ } else {
567
+ warn!(
568
+ "Attempt to pin {:?}, but it is not recognised as a object" ,
569
+ $addr
570
+ ) ;
571
+ false
572
+ }
573
+ } } ;
574
+ }
575
+
576
+ #[ no_mangle]
577
+ pub extern "C" fn mmtk_pin_pointer ( addr : Address ) -> bool {
578
+ crate :: early_return_for_non_moving_build!( false ) ;
579
+
580
+ if crate :: object_model:: is_addr_in_immixspace ( addr) {
581
+ handle_potential_internal_pointer ! ( memory_manager:: pin_object, addr)
495
582
} else {
496
- debug ! ( "Object is not managed by mmtk - (un)pinning it via this function isn't supported ." ) ;
583
+ debug ! ( "Object is not in Immix space. MMTk will not move the object. No need to pin the object ." ) ;
497
584
false
498
585
}
499
586
}
500
587
501
588
#[ no_mangle]
502
- pub extern "C" fn mmtk_unpin_object ( object : ObjectReference ) -> bool {
589
+ pub extern "C" fn mmtk_unpin_pointer ( addr : Address ) -> bool {
503
590
crate :: early_return_for_non_moving_build!( false ) ;
504
591
505
- if mmtk_object_is_managed_by_mmtk ( object . to_raw_address ( ) . as_usize ( ) ) {
506
- memory_manager:: unpin_object ( object )
592
+ if crate :: object_model :: is_addr_in_immixspace ( addr ) {
593
+ handle_potential_internal_pointer ! ( memory_manager:: unpin_object, addr )
507
594
} else {
508
- debug ! ( "Object is not managed by mmtk - (un)pinning it via this function isn't supported ." ) ;
595
+ debug ! ( "Object is not in Immix space. MMTk will not move the object. No need to unpin the object ." ) ;
509
596
false
510
597
}
511
598
}
512
599
513
600
#[ no_mangle]
514
- pub extern "C" fn mmtk_is_pinned ( object : ObjectReference ) -> bool {
601
+ pub extern "C" fn mmtk_is_pointer_pinned ( addr : Address ) -> bool {
515
602
crate :: early_return_for_non_moving_build!( false ) ;
516
603
517
- if mmtk_object_is_managed_by_mmtk ( object. to_raw_address ( ) . as_usize ( ) ) {
518
- memory_manager:: is_pinned ( object)
604
+ if crate :: object_model:: is_addr_in_immixspace ( addr) {
605
+ handle_potential_internal_pointer ! ( memory_manager:: is_pinned, addr)
606
+ } else if !mmtk_object_is_managed_by_mmtk ( addr. as_usize ( ) ) {
607
+ debug ! (
608
+ "Object is not in Immix space. MMTk will not move the object. We assume it is pinned."
609
+ ) ;
610
+ true
519
611
} else {
520
- debug ! ( "Object is not managed by mmtk - checking via this function isn't supported." ) ;
612
+ debug ! ( "Object is not managed by mmtk - checking pinning state via this function isn't supported." ) ;
521
613
false
522
614
}
523
615
}
0 commit comments