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