Skip to content

Commit ba73217

Browse files
authored
Update doc comment for Slot (#1409)
We make it clear that a `Slot` points to a slot instead of being the slot itself. We also emphasize that `Slot` can be copied, and the copied `Slot` points to the same slot. We also reorganize the doc comment and explain the relation between slots in general and the `Slot` trait in MMTk. We also use `SimpleSlot` and `OffsetSlot` as examples of what an implementation of `Slot` can contain.
1 parent 38b1391 commit ba73217

File tree

1 file changed

+82
-26
lines changed

1 file changed

+82
-26
lines changed

src/vm/slot.rs

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,100 @@ use atomic::Atomic;
1111
use crate::util::constants::{BYTES_IN_ADDRESS, LOG_BYTES_IN_ADDRESS};
1212
use crate::util::{Address, ObjectReference};
1313

14-
/// A `Slot` represents a slot in an object (a.k.a. a field), on the stack (i.e. a local variable)
15-
/// or any other places (such as global variables). A slot may hold an object reference. We can
16-
/// load the object reference from it, and we can update the object reference in it after the GC
17-
/// moves the object.
14+
/// `Slot` is an abstraction for MMTk to load and update object references in memory.
1815
///
19-
/// For some VMs, a slot may sometimes not hold an object reference. For example, it can hold a
20-
/// special `NULL` pointer which does not point to any object, or it can hold a tagged
21-
/// non-reference value, such as small integers and special values such as `true`, `false`, `null`
22-
/// (a.k.a. "none", "nil", etc. for other VMs), `undefined`, etc.
16+
/// # Slots and the `Slot` trait
2317
///
24-
/// This intends to abstract out the differences of reference field representation among different
25-
/// VMs. If the VM represent a reference field as a word that holds the pointer to the object, it
26-
/// can use the default `SimpleSlot` we provide. In some cases, the VM need to implement its own
27-
/// `Slot` instances.
18+
/// In a VM, a slot can contain an object reference or a non-reference value. It can be in an
19+
/// object (a.k.a. a field), on the stack (i.e. a local variable) or in any other places (such as
20+
/// global variables). It may have different representations in different VMs. Some VMs put a
21+
/// direct pointer to an object into a slot, while others may use compressed pointers, tagged
22+
/// pointers, offsetted pointers, etc. Some VMs (such as JVM) have null references, and others
23+
/// (such as CRuby and JavaScript engines) can also use tagged bits to represent non-reference
24+
/// values such as small integers, `true`, `false`, `null` (a.k.a. "none", "nil", etc.),
25+
/// `undefined`, etc.
26+
///
27+
/// In MMTk, the `Slot` trait is intended to abstract out such different representations of
28+
/// reference fields (compressed, tagged, offsetted, etc.) among different VMs. From MMTk's point
29+
/// of view, **MMTk only cares about the object reference held inside the slot, but not
30+
/// non-reference values**, such as `null`, `true`, etc. When the slot is holding an object
31+
/// reference, we can load the object reference from it, and we can update the object reference in
32+
/// it after the GC moves the object.
33+
///
34+
/// # The `Slot` trait has pointer semantics
35+
///
36+
/// A `Slot` value *points to* a slot, and is not the slot itself. In fact, the simplest
37+
/// implementation of the `Slot` trait ([`SimpleSlot`], see below) can simply contain the address of
38+
/// the slot.
39+
///
40+
/// A `Slot` can be [copied](std::marker::Copy), and the copied `Slot` instance points to the same
41+
/// slot.
42+
///
43+
/// # How to implement `Slot`?
44+
///
45+
/// If a reference field of a VM is word-sized and holds the raw pointer to an object, and uses the
46+
/// 0 word as the null pointer, it can use the default [`SimpleSlot`] we provide. It simply
47+
/// contains a pointer to a memory location that holds an address.
48+
///
49+
/// ```rust
50+
/// pub struct SimpleSlot {
51+
/// slot_addr: *mut Atomic<Address>,
52+
/// }
53+
/// ```
54+
///
55+
/// In other cases, the VM need to implement its own `Slot` instances.
2856
///
2957
/// For example:
30-
/// - The VM uses compressed pointer (Compressed OOP in OpenJDK's terminology), where the heap
31-
/// size is limited, and a 64-bit pointer is stored in a 32-bit slot.
32-
/// - The VM uses tagged pointer, where some bits of a word are used as metadata while the rest
33-
/// are used as pointer.
34-
/// - A field holds a pointer to the middle of an object (an object field, or an array element,
35-
/// or some arbitrary offset) for some reasons.
58+
/// - The VM uses **compressed pointers** (Compressed OOPs in OpenJDK's terminology), where the
59+
/// heap size is limited, and a 64-bit pointer is stored in a 32-bit slot.
60+
/// - The VM uses **tagged pointers**, where some bits of a word are used as metadata while the
61+
/// rest are used as pointer.
62+
/// - The VM uses **offsetted pointers**, i.e. the value of the field is an address at an offset
63+
/// from the [`ObjectReference`] of the target object. Such offsetted pointers are usually used
64+
/// to represent **interior pointers**, i.e. pointers to an object field, an array element, etc.
65+
///
66+
/// If needed, the implementation of `Slot` can contain not only the pointer, but also additional
67+
/// information. The `OffsetSlot` example below also contains an offset which can be used when
68+
/// decoding the pointer. See `src/vm/tests/mock_tests/mock_test_slots.rs` for more concrete
69+
/// examples, such as `CompressedOopSlot` and `TaggedSlot`.
3670
///
37-
/// When loading, `Slot::load` shall decode its internal representation to a "regular"
38-
/// `ObjectReference`. The implementation can do this with any appropriate operations, usually
39-
/// shifting and masking bits or subtracting offset from the address. By doing this conversion,
40-
/// MMTk can implement GC algorithms in a VM-neutral way, knowing only `ObjectReference`.
71+
/// ```rust
72+
/// pub struct OffsetSlot {
73+
/// slot_addr: *mut Atomic<Address>,
74+
/// offset: usize,
75+
/// }
76+
/// ```
77+
///
78+
/// When loading, `Slot::load` shall load the value from the slot and decode the value into a
79+
/// regular `ObjectReference` (note that MMTk has specific requirements for `ObjectReference`, such
80+
/// as being aligned, pointing inside an object, and cannot be null. Please read the doc comments
81+
/// of [`ObjectReference`] for details). The decoding is VM-specific, but usually involves removing
82+
/// tag bits and/or adding an offset to the word, and (in the case of compressed pointers) extending
83+
/// the word size. By doing this conversion, MMTk can implement GC algorithms in a VM-neutral way,
84+
/// knowing only `ObjectReference`.
4185
///
4286
/// When GC moves object, `Slot::store` shall convert the updated `ObjectReference` back to the
4387
/// slot-specific representation. Compressed pointers remain compressed; tagged pointers preserve
4488
/// their tag bits; and offsetted pointers keep their offsets.
4589
///
90+
/// # Performance notes
91+
///
4692
/// The methods of this trait are called on hot paths. Please ensure they have high performance.
47-
/// Use inlining when appropriate.
4893
///
49-
/// Note: this trait only concerns the representation (i.e. the shape) of the slot, not its
50-
/// semantics, such as whether it holds strong or weak references. If a VM holds a weak reference
51-
/// in a word as a pointer, it can also use `SimpleSlot` for weak reference fields.
94+
/// The size of the data structure of the `Slot` implementation may affect the performance as well.
95+
/// During GC, MMTk enqueues `Slot` instances, and its size affects the overhead of copying. If
96+
/// your `Slot` implementation has multiple fields or uses `enum` for multiple kinds of slots, it
97+
/// may have extra cost when copying or decoding. You should measure it. If the cost is too much,
98+
/// you can implement `Slot` with a tagged word. For example, the [mmtk-openjdk] binding uses the
99+
/// low order bit to encode whether the slot is compressed or not.
100+
///
101+
/// [mmtk-openjdk]: https://github.com/mmtk/mmtk-openjdk/blob/master/mmtk/src/slots.rs
102+
///
103+
/// # About weak references
104+
///
105+
/// This trait only concerns the representation (i.e. the shape) of the slot, not its semantics,
106+
/// such as whether it holds strong or weak references. Therefore, one `Slot` implementation can be
107+
/// used for both slots that hold strong references and slots that hold weak references.
52108
pub trait Slot: Copy + Send + Debug + PartialEq + Eq + Hash {
53109
/// Load object reference from the slot.
54110
///

0 commit comments

Comments
 (0)