1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use crate::util::heap::layout::vm_layout::VMLayout;
#[cfg(target_pointer_width = "32")]
use crate::util::heap::layout::vm_layout::BYTES_IN_CHUNK;
use crate::util::metadata::side_metadata::SideMetadataOffset;
use crate::util::Address;
// XXX: We updated the base address to start from the second 4Mb chunk for 32-bit architectures,
// as otherwise for side metadatas with a large `min_obj_size`, we were overlapping with system
// reserved addresses such as 0x0.
// XXXX: I updated the base address for 32 bit to 0x1000_0000. For what I tested on, the library
// and the malloc heap often starts at 0x800_0000. If we start the metadata from the second 4Mb chunk (i.e. the chunk `[0x40_0000, 0x80_0000)`),
// we won't be guaranteed enough space before 0x800_0000. For example, the VO bit is 1 bit per 4 bytes
// (1 word in 32bits), and it will take the address range of [0x40_000, 0x840_0000) which clashes with
// the library/heap. So I move this to 0x1000_0000.
// This is made public, as VM bingdings may need to use this.
#[cfg(target_pointer_width = "32")]
/// Global side metadata start address
pub const GLOBAL_SIDE_METADATA_BASE_ADDRESS: Address = unsafe { Address::from_usize(0x1000_0000) };
// FIXME: The 64-bit base address is changed from 0x0600_0000_0000 to 0x0c00_0000_0000 so that it
// is less likely to overlap with any space. But it does not solve the problem completely.
// If there are more spaces, it will still overlap with some spaces.
// See: https://github.com/mmtk/mmtk-core/issues/458
#[cfg(target_pointer_width = "64")]
/// Global side metadata start address
pub const GLOBAL_SIDE_METADATA_BASE_ADDRESS: Address =
unsafe { Address::from_usize(0x0000_0c00_0000_0000usize) };
pub(crate) const GLOBAL_SIDE_METADATA_BASE_OFFSET: SideMetadataOffset =
SideMetadataOffset::addr(GLOBAL_SIDE_METADATA_BASE_ADDRESS);
/// Base address of VO bit, public to VM bindings which may need to use this.
#[cfg(target_pointer_width = "64")]
pub const VO_BIT_SIDE_METADATA_ADDR: Address =
crate::util::metadata::vo_bit::VO_BIT_SIDE_METADATA_ADDR;
/// This constant represents the worst-case ratio of source data size to global side metadata.
/// A value of 2 means the space required for global side metadata must be less than 1/4th of the source data.
/// So, a value of `n` means this ratio must be less than $2^-n$.
#[cfg(target_pointer_width = "32")]
pub(super) const LOG_GLOBAL_SIDE_METADATA_WORST_CASE_RATIO: usize = 3;
#[cfg(target_pointer_width = "64")]
pub(super) const LOG_GLOBAL_SIDE_METADATA_WORST_CASE_RATIO: usize = 1;
/// This constant represents the worst-case ratio of source data size to global+local side metadata.
/// A value of 1 means the space required for global+local side metadata must be less than 1/2nd of the source data.
/// So, a value of `n` means this ratio must be less than $2^-n$.
#[cfg(target_pointer_width = "32")]
pub(super) const LOG_LOCAL_SIDE_METADATA_WORST_CASE_RATIO: usize = 3;
#[cfg(target_pointer_width = "64")]
pub(super) const LOG_LOCAL_SIDE_METADATA_WORST_CASE_RATIO: usize = 1;
/// The max bytes (in log2) that may be used for global side metadata.
pub(crate) const LOG_MAX_GLOBAL_SIDE_METADATA_SIZE: usize =
VMLayout::LOG_ARCH_ADDRESS_SPACE - LOG_GLOBAL_SIDE_METADATA_WORST_CASE_RATIO;
// TODO - we should check this limit somewhere
// pub(crate) const LOG_MAX_LOCAL_SIDE_METADATA_SIZE: usize =
// 1 << (LOG_ADDRESS_SPACE - LOG_LOCAL_SIDE_METADATA_WORST_CASE_RATIO);
// Local side metadata start address
pub(crate) const LOCAL_SIDE_METADATA_BASE_ADDRESS: Address =
GLOBAL_SIDE_METADATA_BASE_ADDRESS.add(1usize << LOG_MAX_GLOBAL_SIDE_METADATA_SIZE);
// Local side metadata start offset
#[cfg(target_pointer_width = "32")]
pub(crate) const LOCAL_SIDE_METADATA_BASE_OFFSET: SideMetadataOffset = SideMetadataOffset::rel(0);
#[cfg(target_pointer_width = "64")]
pub(crate) const LOCAL_SIDE_METADATA_BASE_OFFSET: SideMetadataOffset =
SideMetadataOffset::addr(LOCAL_SIDE_METADATA_BASE_ADDRESS);
#[cfg(target_pointer_width = "32")]
pub(super) const LOCAL_SIDE_METADATA_PER_CHUNK: usize =
BYTES_IN_CHUNK >> LOG_LOCAL_SIDE_METADATA_WORST_CASE_RATIO;
/// The base address for the global side metadata space available to VM bindings, to be used for the per-object metadata.
/// VM bindings must use this to avoid overlap with core internal global side metadata.
pub const GLOBAL_SIDE_METADATA_VM_BASE_ADDRESS: Address =
super::spec_defs::LAST_GLOBAL_SIDE_METADATA_SPEC.upper_bound_address_for_contiguous();
/// The base offset for the global side metadata available to VM bindings.
pub const GLOBAL_SIDE_METADATA_VM_BASE_OFFSET: SideMetadataOffset =
super::spec_defs::LAST_GLOBAL_SIDE_METADATA_SPEC.upper_bound_offset();
/// The base address for the local side metadata space available to VM bindings, to be used for the per-object metadata.
/// VM bindings must use this to avoid overlap with core internal local side metadata.
pub const LOCAL_SIDE_METADATA_VM_BASE_OFFSET: SideMetadataOffset =
super::spec_defs::LAST_LOCAL_SIDE_METADATA_SPEC.upper_bound_offset();