@@ -488,17 +488,36 @@ pub mod specs {
488
488
// This macro is invoked in define_vm_metadata_global_spec or define_vm_metadata_local_spec.
489
489
// Use those two to define a new VM metadata spec.
490
490
macro_rules! define_vm_metadata_spec {
491
- ( $spec_name: ident, $is_global: expr, $log_num_bits: expr, $side_min_obj_size: expr) => {
491
+ ( $( #[ $outer: meta] ) * $spec_name: ident, $is_global: expr, $log_num_bits: expr, $side_min_obj_size: expr) => {
492
+ $( #[ $outer] ) *
492
493
pub struct $spec_name( MetadataSpec ) ;
493
494
impl $spec_name {
495
+ /// The number of bits (in log2) that are needed for the spec.
494
496
pub const LOG_NUM_BITS : usize = $log_num_bits;
497
+
498
+ /// Whether this spec is global or local. For side metadata, the binding needs to make sure
499
+ /// global specs are laid out after another global spec, and local specs are laid
500
+ /// out after another local spec. Otherwise, there will be an assertion failure.
495
501
pub const IS_GLOBAL : bool = $is_global;
502
+
503
+ /// Declare that the VM uses in-header metadata for this metadata type.
504
+ /// For the specification of the `bit_offset` argument, please refer to
505
+ /// the document of `[crate::util::metadata::header_metadata::HeaderMetadataSpec.bit_offset]`.
506
+ /// The binding needs to make sure that the bits used for a spec in the header do not conflict with
507
+ /// the bits of another spec (unless it is specified that some bits may be reused).
496
508
pub const fn in_header( bit_offset: isize ) -> Self {
497
509
Self ( MetadataSpec :: InHeader ( HeaderMetadataSpec {
498
510
bit_offset,
499
511
num_of_bits: 1 << Self :: LOG_NUM_BITS ,
500
512
} ) )
501
513
}
514
+
515
+ /// Declare that the VM uses side metadata for this metadata type,
516
+ /// and the side metadata is the first of its kind (global or local).
517
+ /// The first global or local side metadata should be declared with `side_first()`,
518
+ /// and the rest side metadata should be declared with `side_after()` after a defined
519
+ /// side metadata of the same kind (global or local). Logically, all the declarations
520
+ /// create two list of side metadata, one for global, and one for local.
502
521
pub const fn side_first( ) -> Self {
503
522
if Self :: IS_GLOBAL {
504
523
Self ( MetadataSpec :: OnSide ( SideMetadataSpec {
@@ -518,6 +537,13 @@ pub mod specs {
518
537
} ) )
519
538
}
520
539
}
540
+
541
+ /// Declare that the VM uses side metadata for this metadata type,
542
+ /// and the side metadata should be laid out after the given side metadata spec.
543
+ /// The first global or local side metadata should be declared with `side_first()`,
544
+ /// and the rest side metadata should be declared with `side_after()` after a defined
545
+ /// side metadata of the same kind (global or local). Logically, all the declarations
546
+ /// create two list of side metadata, one for global, and one for local.
521
547
pub const fn side_after( spec: & MetadataSpec ) -> Self {
522
548
assert!( spec. is_on_side( ) ) ;
523
549
let side_spec = spec. extract_side_spec( ) ;
@@ -530,9 +556,13 @@ pub mod specs {
530
556
log_bytes_in_region: $side_min_obj_size as usize ,
531
557
} ) )
532
558
}
559
+
560
+ /// Return the inner `[crate::util::metadata::MetadataSpec]` for the metadata type.
533
561
pub const fn as_spec( & self ) -> & MetadataSpec {
534
562
& self . 0
535
563
}
564
+
565
+ /// Return the number of bits for the metadata type.
536
566
pub const fn num_bits( & self ) -> usize {
537
567
1 << $log_num_bits
538
568
}
@@ -547,20 +577,57 @@ pub mod specs {
547
577
}
548
578
549
579
// Log bit: 1 bit per object, global
550
- define_vm_metadata_spec ! ( VMGlobalLogBitSpec , true , 0 , LOG_MIN_OBJECT_SIZE ) ;
580
+ define_vm_metadata_spec ! (
581
+ #[ doc = "1-bit global metadata to log an object." ]
582
+ VMGlobalLogBitSpec ,
583
+ true ,
584
+ 0 ,
585
+ LOG_MIN_OBJECT_SIZE
586
+ ) ;
551
587
// Forwarding pointer: word size per object, local
552
588
define_vm_metadata_spec ! (
589
+ #[ doc = "1-word local metadata for spaces that may copy objects." ]
590
+ #[ doc = "This metadata has to be stored in the header." ]
591
+ #[ doc = "This metadata can be defined at a position within the object payload." ]
592
+ #[ doc = "As a forwarding pointer is only stored in dead objects which is not" ]
593
+ #[ doc = "accessible by the language, it is okay that store a forwarding pointer overwrites object payload" ]
553
594
VMLocalForwardingPointerSpec ,
554
595
false ,
555
596
LOG_BITS_IN_WORD ,
556
597
LOG_MIN_OBJECT_SIZE
557
598
) ;
558
599
// Forwarding bits: 2 bits per object, local
559
- define_vm_metadata_spec ! ( VMLocalForwardingBitsSpec , false , 1 , LOG_MIN_OBJECT_SIZE ) ;
600
+ define_vm_metadata_spec ! (
601
+ #[ doc = "2-bit local metadata for spaces that store a forwarding state for objects." ]
602
+ #[ doc = "If this spec is defined in the header, it can be defined with a position of the lowest 2 bits in the forwarding pointer." ]
603
+ VMLocalForwardingBitsSpec ,
604
+ false ,
605
+ 1 ,
606
+ LOG_MIN_OBJECT_SIZE
607
+ ) ;
560
608
// Mark bit: 1 bit per object, local
561
- define_vm_metadata_spec ! ( VMLocalMarkBitSpec , false , 0 , LOG_MIN_OBJECT_SIZE ) ;
609
+ define_vm_metadata_spec ! (
610
+ #[ doc = "1-bit local metadata for spaces that need to mark an object." ]
611
+ VMLocalMarkBitSpec ,
612
+ false ,
613
+ 0 ,
614
+ LOG_MIN_OBJECT_SIZE
615
+ ) ;
562
616
// Pinning bit: 1 bit per object, local
563
- define_vm_metadata_spec ! ( VMLocalPinningBitSpec , false , 0 , LOG_MIN_OBJECT_SIZE ) ;
617
+ define_vm_metadata_spec ! (
618
+ #[ doc = "1-bit local metadata for spaces that support pinning." ]
619
+ VMLocalPinningBitSpec ,
620
+ false ,
621
+ 0 ,
622
+ LOG_MIN_OBJECT_SIZE
623
+ ) ;
564
624
// Mark&nursery bits for LOS: 2 bit per page, local
565
- define_vm_metadata_spec ! ( VMLocalLOSMarkNurserySpec , false , 1 , LOG_BYTES_IN_PAGE ) ;
625
+ define_vm_metadata_spec ! (
626
+ #[ doc = "2-bits local metadata for the large object space. The two bits serve as" ]
627
+ #[ doc = "the mark bit and the nursery bit." ]
628
+ VMLocalLOSMarkNurserySpec ,
629
+ false ,
630
+ 1 ,
631
+ LOG_BYTES_IN_PAGE
632
+ ) ;
566
633
}
0 commit comments