@@ -488,17 +488,36 @@ pub mod specs {
488488 // This macro is invoked in define_vm_metadata_global_spec or define_vm_metadata_local_spec.
489489 // Use those two to define a new VM metadata spec.
490490 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] ) *
492493 pub struct $spec_name( MetadataSpec ) ;
493494 impl $spec_name {
495+ /// The number of bits (in log2) that are needed for the spec.
494496 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.
495501 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).
496508 pub const fn in_header( bit_offset: isize ) -> Self {
497509 Self ( MetadataSpec :: InHeader ( HeaderMetadataSpec {
498510 bit_offset,
499511 num_of_bits: 1 << Self :: LOG_NUM_BITS ,
500512 } ) )
501513 }
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.
502521 pub const fn side_first( ) -> Self {
503522 if Self :: IS_GLOBAL {
504523 Self ( MetadataSpec :: OnSide ( SideMetadataSpec {
@@ -518,6 +537,13 @@ pub mod specs {
518537 } ) )
519538 }
520539 }
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.
521547 pub const fn side_after( spec: & MetadataSpec ) -> Self {
522548 assert!( spec. is_on_side( ) ) ;
523549 let side_spec = spec. extract_side_spec( ) ;
@@ -530,9 +556,13 @@ pub mod specs {
530556 log_bytes_in_region: $side_min_obj_size as usize ,
531557 } ) )
532558 }
559+
560+ /// Return the inner `[crate::util::metadata::MetadataSpec]` for the metadata type.
533561 pub const fn as_spec( & self ) -> & MetadataSpec {
534562 & self . 0
535563 }
564+
565+ /// Return the number of bits for the metadata type.
536566 pub const fn num_bits( & self ) -> usize {
537567 1 << $log_num_bits
538568 }
@@ -547,20 +577,57 @@ pub mod specs {
547577 }
548578
549579 // 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+ ) ;
551587 // Forwarding pointer: word size per object, local
552588 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" ]
553594 VMLocalForwardingPointerSpec ,
554595 false ,
555596 LOG_BITS_IN_WORD ,
556597 LOG_MIN_OBJECT_SIZE
557598 ) ;
558599 // 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+ ) ;
560608 // 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+ ) ;
562616 // 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+ ) ;
564624 // 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+ ) ;
566633}
0 commit comments