Skip to content

Conversation

@wks
Copy link
Collaborator

@wks wks commented Oct 27, 2025

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.

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 into sections.

We also replace overly general wording with more specific examples, such
as explicitly mentioning JVM, CRuby and JS engines.
src/vm/slot.rs Outdated
/// or any other places (such as global variables). A slot may hold an object reference. We can
/// load the object reference from it, and we can update the object reference in it after the GC
/// moves the object.
/// A `Slot` value *points to* a slot, and is intended for loading and updating the reference held
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Slot value points to a slot
Note that a Slot is not the slot itself.

When people are reading this comment, they probably don't know what a MMTK's Slot is, and they may or may not be sure about what a slot is for their runtime. You are trying to differentiate the subtle difference between a Slot and a slot -- I feel this makes it more confusing. I would go with something like this, and then use more examples to explain it:

`Slot` is an abstraction for MMTk to load and update object references in memory.

Besides, a Slot could be the slot itself (if we don't require Slot to be Copy).

struct MyObjectLayout {
  header: MyHeader,
  field1: Arc<MySlot>,
}

impl mmtk::vm::Slot for Arc<MySlot> {
  ...
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to add something like this as well, apart from the line about Slot being an abstraction, "In case of most runtimes, a Slot is a pointer to a field in the object."

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I'd prefer if we use 'fields' instead of 'slots' everywhere, there is a good scope of confusion between Slot and 'slot'.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is that a slot encompasses more than a field inside an object. A slot can be a stack slot. Or a global root. These are not fields.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When people are reading this comment, they probably don't know what a MMTK's Slot is, and they may or may not be sure about what a slot is for their runtime. You are trying to differentiate the subtle difference between a Slot and a slot -- I feel this makes it more confusing. I would go with something like this, and then use more examples to explain it:

`Slot` is an abstraction for MMTk to load and update object references in memory.

Yes. I think this sentence is clear and conveys the main intention of the Slot trait. I edited the comment and used this as the first sentence of the doc comment of Slot.

But I think the difference between slots in general and MMTk's Slot trait is important. I reorganized the doc and used one section to compare the two.

Besides, a Slot could be the slot itself (if we don't require Slot to be Copy).

struct MyObjectLayout {
  header: MyHeader,
  field1: Arc<MySlot>,
}

impl mmtk::vm::Slot for Arc<MySlot> {
  ...
}

Although this is possible with some tricks, it is not the intended way to use Slot. MMTk will internally make use of the fact that Slot is trivially copy-able. I added a section to emphasized that Slot should have pointer semantics and implement the Copy trait.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to add something like this as well, apart from the line about Slot being an abstraction, "In case of most runtimes, a Slot is a pointer to a field in the object."

I inlined the code of SimpleSlot as an example of Slot implementation, and I also added OffsetSlot as another example to show a case where a Slot implementation can have more than a pointer.

Also, I'd prefer if we use 'fields' instead of 'slots' everywhere, there is a good scope of confusion between Slot and 'slot'.

The GC Handbook uses the term field and slot interchangeably as you suggested, which is unfortunate. The problem is, as @k-sareen mentioned, that in MMTk and real-world VMs (including JikesRVM), a slot can also refer to stack slots (local variables) and global roots (including global variables, slots in JNI handle tables, and any other global tables). We use the term "field" specifically for heap objects, and "slot" more generally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually have to copy Slots? Or is it just convenient if Slot is Copy?

It is intended to have pointer semantics, and it implies it should be copy-able. Of course if we talk about "have to", we can always use Clone instead and cope with .clone(). But that's very inconvenient.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the pointer semantics are important because otherwise we're sort of lying to ourselves/making life inconvenient. Consider a slot that we get from a write barrier modbuf vs a slot that we get from scanning an object. They both might be the same. But if we prevent Copy, we sort of imply that they are not the same. At least in my head, it makes much more sense that Slots are Copy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy only means it is easy to obtain multiple copies of the Slots. I don't see why we need to copy slots, except that it might be just a coincidence or a convenience. It sounds possible to me that when we are given a Slot, we just keep use that instance without copying or cloning it. In that case, we should not extend the doc to say that it has to be Copy (because it does not have to be Copy).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy only means it is easy to obtain multiple copies of the Slots. I don't see why we need to copy slots, except that it might be just a coincidence or a convenience. It sounds possible to me that when we are given a Slot, we just keep use that instance without copying or cloning it. In that case, we should not extend the doc to say that it has to be Copy (because it does not have to be Copy).

If it is not Copy or Clone, it will follow Rust's ownership rules. Types that use ownership rules usually have resource management concerns. For example, Box<T> uniquely owns the underlying malloc memory, and cloning a Box<T> will make a deep-copy. Arc maintains reference count. It is Clone but not Copy because cloning an Arc has non-trivial cost (atomically incrementing ref count), and dropping an Arc may free the object. A File owns a file. It cannot be cloned, and File::try_clone has semantics like the dup system call.

But a Slot is not like these. It simply points to a slot, and it doesn't have other "resources". It doesn't "own" the slot, and it doesn't release any handles when we drop a Slot. And it doesn't grant MMTk unique access to the slot, either. Scanning::scan_objects will generate Slot instances, and repeated calling of Scanning::scan_objects can generate multiple Slot instances that point to the same slot. And it should be trivial to copy the data of a Slot instances (which is a pointer most of the time), for performance reasons. Implementing Copy will emphasize that it should be trivial to copy.

Maybe in some distributed GC systems, we can have Slot that refer to a slot in a remote instance, and closing a Slot will release the network connection. But MMTk is not designed for that. If a Slot is a heavy-weight handle, maybe MMTk will need to be redesigned.

src/vm/slot.rs Outdated
/// VMs. If the VM represent a reference field as a word that holds the pointer to the object, it
/// can use the default `SimpleSlot` we provide. In some cases, the VM need to implement its own
/// `Slot` instances.
/// The `Slot` trait is intended to abstract out the differences of reference field representation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Slot trait is intended to abstract out the differences of reference field representation
(compressed, tagged, offsetted, etc.) among different VMs.

I feel this is also a good definition for Slot. It is just an abstraction. It does not really define what a Slot would be -- whether it is a value that points to the slot, or is the slot itself. It doesn't really matter, as long as it allows MMTk to access the object reference in the memory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used this in the "# Slots and the Slot trait" section to describe what the Slot trait is.

Use a simple statement as the first paragraph

Make clear distinction between slots and the `Slot` trait.

Give example of what a `Slot` implementation can hold.
Copy link
Collaborator

@k-sareen k-sareen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks! Just some minor comments

src/vm/slot.rs Outdated
///
/// If a reference field of a VM is just a word that holds the pointer to an object, and uses the 0
/// word as the null pointer, it can use the default [`SimpleSlot`] we provide. It simply contains
/// a pointer to a memory location that holds an address.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importantly, SimpleSlot loads usize-sized values from the Address. If you have something like ART wherein you still have just a simple Address there, but have to load u32-sized values from the Address as ART object references are 32-bit. You already mention compressed pointers below, but maybe just explicitly say usize or word-size here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right. SimpleSlot is supposed to be simple and does not support compressed oops. There is a CompressedOopSlot in mock_test_slots.rs which the user can use as an example.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I just meant make it explicit that SimpleSlot operates on word-sized pointers.

/// shifting and masking bits or subtracting offset from the address. By doing this conversion,
/// MMTk can implement GC algorithms in a VM-neutral way, knowing only `ObjectReference`.
/// ```rust
/// pub struct OffsetSlot {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that a Slot like this will not be word-sized so may not have the best performance. It should be flagged.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I think this is why the OpenJDK binding uses tagged word instead of Rust enum to distinguish between narrow and wide slots.

wks added 2 commits October 29, 2025 12:30
Emphasize that the use case of SimpleSlot is word-sized raw pointers.

Mention CompressedOopSlot and TaggedSlot.

Mention that the size of `Slot` implementation may affect performance.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants