Struct cranelift_codegen::binemit::StackMap
source · pub struct StackMap { /* private fields */ }Expand description
Stack maps record which words in a stack frame contain live GC references at a given instruction pointer.
Logically, a set of stack maps for a function record a table of the form:
+---------------------+-------------------------------------------+
| Instruction Pointer | SP-Relative Offsets of Live GC References |
+---------------------+-------------------------------------------+
| 0x12345678 | 2, 6, 12 |
| 0x1234abcd | 2, 6 |
| ... | ... |
+---------------------+-------------------------------------------+
Where “instruction pointer” is an instruction pointer within the function, and “offsets of live GC references” contains the offsets (in units of words) from the frame’s stack pointer where live GC references are stored on the stack. Instruction pointers within the function that do not have an entry in this table are not GC safepoints.
Because
- offsets of live GC references are relative from the stack pointer, and
- stack frames grow down from higher addresses to lower addresses,
to get a pointer to a live reference at offset x within a stack frame, you
add x from the frame’s stack pointer.
For example, to calculate the pointer to the live GC reference inside “frame
1” below, you would do frame_1_sp + x:
Stack
+-------------------+
| Frame 0 |
| |
| | |
| +-------------------+ <--- Frame 0's SP
| | Frame 1 |
Grows | |
down | |
| | Live GC reference | --+--
| | | |
| | | |
V | | x = offset of live GC reference
| | |
| | |
+-------------------+ --+-- <--- Frame 1's SP
| Frame 2 |
| ... |
An individual StackMap is associated with just one instruction pointer
within the function, contains the size of the stack frame, and represents
the stack frame as a bitmap. There is one bit per word in the stack frame,
and if the bit is set, then the word contains a live GC reference.
Note that a caller’s OutgoingArg stack slots and callee’s IncomingArg
stack slots overlap, so we must choose which function’s stack maps record
live GC references in these slots. We record the IncomingArgs in the
callee’s stack map.
Implementations§
source§impl StackMap
impl StackMap
sourcepub fn from_slice(vec: &[bool]) -> Self
pub fn from_slice(vec: &[bool]) -> Self
Create a vec of Bitsets from a slice of bools.
Examples found in repository?
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
pub fn spillslots_to_stack_map(
&self,
slots: &[SpillSlot],
state: &<M::I as MachInstEmit>::State,
) -> StackMap {
let virtual_sp_offset = M::get_virtual_sp_offset_from_state(state);
let nominal_sp_to_fp = M::get_nominal_sp_to_fp(state);
assert!(virtual_sp_offset >= 0);
trace!(
"spillslots_to_stackmap: slots = {:?}, state = {:?}",
slots,
state
);
let map_size = (virtual_sp_offset + nominal_sp_to_fp) as u32;
let bytes = M::word_bytes();
let map_words = (map_size + bytes - 1) / bytes;
let mut bits = std::iter::repeat(false)
.take(map_words as usize)
.collect::<Vec<bool>>();
let first_spillslot_word =
((self.stackslots_size + virtual_sp_offset as u32) / bytes) as usize;
for &slot in slots {
let slot = slot.index();
bits[first_spillslot_word + slot] = true;
}
StackMap::from_slice(&bits[..])
}sourcepub fn as_slice(&self) -> &[BitSet<u32>]
pub fn as_slice(&self) -> &[BitSet<u32>]
Returns the raw bitmap that represents this stack map.
sourcepub fn mapped_words(&self) -> u32
pub fn mapped_words(&self) -> u32
Returns the number of words represented by this stack map.
Trait Implementations§
source§impl PartialEq<StackMap> for StackMap
impl PartialEq<StackMap> for StackMap
impl Eq for StackMap
impl StructuralEq for StackMap
impl StructuralPartialEq for StackMap
Auto Trait Implementations§
impl RefUnwindSafe for StackMap
impl Send for StackMap
impl Sync for StackMap
impl Unpin for StackMap
impl UnwindSafe for StackMap
Blanket Implementations§
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.