Skip to content

Add a stop-the-world, serial Compressor #1340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

no-defun-allowed
Copy link
Collaborator

This PR adds a Compressor-esque garbage collector, which is based on MarkCompact but uses a mark bitmap for forwarding metadata like the Compressor.

@k-sareen k-sareen self-requested a review July 15, 2025 05:37
@no-defun-allowed
Copy link
Collaborator Author

The current failure to compile mock_test_allocator_info is a one-line fix, but I don't think the mock VM tests are going to work, as the mock VM uses header metadata and the Compressor requires mark bits to be in a side bitmap.

@k-sareen
Copy link
Collaborator

Thanks for the PR @no-defun-allowed! The major thing I see is that currently the Compressor plan is not using the LOS. Was this intentional or accidental?

@no-defun-allowed
Copy link
Collaborator Author

Thanks for the PR @no-defun-allowed! The major thing I see is that currently the Compressor plan is not using the LOS. Was this intentional or accidental?

Definitely accidental. Thanks for the review.

@qinsoon
Copy link
Member

qinsoon commented Jul 16, 2025

The current failure to compile mock_test_allocator_info is a one-line fix, but I don't think the mock VM tests are going to work, as the mock VM uses header metadata and the Compressor requires mark bits to be in a side bitmap.

You can cherry pick this commit to the PR: qinsoon@ac90d4b.

It runs mock VM with side metadata. Compressor currently fails for tests that are not using contiguous space.

@no-defun-allowed
Copy link
Collaborator Author

You can cherry pick this commit to the PR: qinsoon@ac90d4b.

Thanks!

It runs mock VM with side metadata. Compressor currently fails for tests that are not using contiguous space.

Right. Should we skip such tests when running with the Compressor?


pub fn mark_end_of_object(&self, object: ObjectReference) {
let end_of_object =
object.to_raw_address() + VM::VMObjectModel::get_current_size(object) - MIN_OBJECT_SIZE;
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to minus MIN_OBJECT_SIZE? It looks like you try to compute an address that is guaranteed inside the object.

Also the start of the allocation should be object.to_object_start::<VM>() rather than object.to_raw_address() if you want to add the size to it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You need to set the bit at the end of the object. Consider an object at 0x10000000 of size 0x10, then we want the mark bits to be set for 0x10000000 and 0x1000000f, not 0x10000000 and 0x10000010. Since each machine word (8-byte on 64-bits and 4-byte on 32-bits) maps down to a single bit, it's sufficient to subtract the minimum object size to set the bit there.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Notably, this requires the start and end of the object to map to different bits. Hence the debug assertion in the function.

Copy link
Member

Choose a reason for hiding this comment

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

You need to set the bit at the end of the object. Consider an object at 0x10000000 of size 0x10, then we want the mark bits to be set for 0x10000000 and 0x1000000f, not 0x10000000 and 0x10000010.

Then why not just use -1?

Since each machine word (8-byte on 64-bits and 4-byte on 32-bits) maps down to a single bit, it's sufficient to subtract the minimum object size to set the bit there.

It seems you are assuming the min object size is one word, which might not be always true in the future. You could also use -word_size.

if KIND == TRACE_KIND_MARK {
self.trace_mark_object(queue, object)
} else if KIND == TRACE_KIND_FORWARD {
self.trace_forward_object(queue, object)
Copy link
Member

Choose a reason for hiding this comment

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

This looks like a second transitive closure. I assume this only happens for roots. Right? If so, I suggest making it much clearer (e.g. TRACE_KIND_FORWARD -> TRACE_KIND_FORWARD_ROOT, self.trace_forward_object -> self.forward_root, etc), and making the code more distinguishable from mark compact.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right and right.

@qinsoon
Copy link
Member

qinsoon commented Jul 16, 2025

It runs mock VM with side metadata. Compressor currently fails for tests that are not using contiguous space.

Right. Should we skip such tests when running with the Compressor?

Is there any intrinsic reason why the compressor cannot run with discontiguous spaces? I feel there is none. It would be better to allow running Compressor with discontiguous spaces.

At the same time, there might be practical reasons that this might be not easy, or it requires too much efforts. It is also okay to skip those tests.

};

lazy_static! {
/// When nogc_multi_space is disabled, force all the allocation go to the default allocator and space.
Copy link
Collaborator

@k-sareen k-sareen Jul 16, 2025

Choose a reason for hiding this comment

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

Suggested change
/// When nogc_multi_space is disabled, force all the allocation go to the default allocator and space.
/// When using `compressor_single_space`, force all the allocations to go to the default allocator and space.

@no-defun-allowed
Copy link
Collaborator Author

Is there any intrinsic reason why the compressor cannot run with discontiguous spaces? I feel there is none. It would be better to allow running Compressor with discontiguous spaces.

I feel that way too. The judgement was more about how closely we want to follow the Compressor paper - one simple approach to support discontiguous spaces would be to compress [sic] each chunk of a space, which would also give a simple way to parallelise (which is not the way in the paper).

The block offset vector is currently a Rust Vec<AtomicUsize> which I do the address-to-block calculation assuming a contiguous heap; I should be using some other metadata mechanism for that anyway.

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.

3 participants