1 //! User-defined stack maps.
2 //!
3 //! This module provides types allowing users to define stack maps and associate
4 //! them with safepoints.
5 //!
6 //! A **safepoint** is a program point (i.e. CLIF instruction) where it must be
7 //! safe to run GC. Currently all non-tail call instructions are considered
8 //! safepoints. (This does *not* allow, for example, skipping safepoints for
9 //! calls that are statically known not to trigger collections, or to have a
10 //! safepoint on a volatile load to a page that gets protected when it is time
11 //! to GC, triggering a fault that pauses the mutator and lets the collector do
12 //! its work before resuming the mutator. We can lift this restriction in the
13 //! future, if necessary.)
14 //!
15 //! A **stack map** is a description of where to find all the GC-managed values
16 //! that are live at a particular safepoint. Stack maps let the collector find
17 //! on-stack roots. Each stack map is logically a set of offsets into the stack
18 //! frame and the type of value at that associated offset. However, because the
19 //! stack layout isn't defined until much later in the compiler's pipeline, each
20 //! stack map entry instead includes both an `ir::StackSlot` and an offset
21 //! within that slot.
22 //!
23 //! These stack maps are **user-defined** in that it is the CLIF producer's
24 //! responsibility to identify and spill the live GC-managed values and attach
25 //! the associated stack map entries to each safepoint themselves (see
26 //! `cranelift_frontend::Function::declare_needs_stack_map` and
27 //! `cranelift_codegen::ir::DataFlowGraph::append_user_stack_map_entry`). Cranelift
28 //! will not insert spills and record these stack map entries automatically (in
29 //! contrast to the old system and its `r64` values).
30 
31 use crate::ir;
32 use smallvec::SmallVec;
33 
34 pub(crate) type UserStackMapEntryVec = SmallVec<[UserStackMapEntry; 4]>;
35 
36 /// A stack map entry describes a GC-managed value and its location at a
37 /// particular instruction.
38 #[derive(Clone, PartialEq, Hash)]
39 #[cfg_attr(
40     feature = "enable-serde",
41     derive(serde_derive::Serialize, serde_derive::Deserialize)
42 )]
43 pub struct UserStackMapEntry {
44     /// The type of the value stored in this stack map entry.
45     pub ty: ir::Type,
46 
47     /// The stack slot that this stack map entry is within.
48     pub slot: ir::StackSlot,
49 
50     /// The offset within the stack slot where this entry's value can be found.
51     pub offset: u32,
52 }
53