Skip to content
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

Compressed Oops Support #235

Merged
merged 70 commits into from
Oct 4, 2023
Merged

Compressed Oops Support #235

merged 70 commits into from
Oct 4, 2023

Conversation

wenyuzhao
Copy link
Member

@wenyuzhao wenyuzhao commented Aug 30, 2023

This PR adds compressed oops support for mmtk-openjdk, and enables it by default.

Implementation strategy and workarounds

Heap layout and compression policy

This PR uses the Edge type to abstract over the compressed edge and uncompressed edge. Object field loads and stores for uncompressed edges work as before. Loads and stores for compressed edges will involve an additional compression and decompression step.

In general, this is the function to decode a 32-bit compressed pointer to its uncompressed form:

fn decode(compressed_oop: u32) -> u64 {
    BASE + ((compressed_oop as u64) << SHIFT)
}

OpenJDK has a few optimizations to reduce the add and shift operations in JIT-compiled code, this PR supports them all:

  1. For heap <= 3G, if we set the heap range as 0x4000_0000..0x1_0000_0000, it is possible to totally remove the add and the shift. The compressed and uncompressed forms are identical.
    • Set BASE = 0 and SHIFT = 0 for this case.
  2. For heap <= 31G, if we set the heap range as 0x4000_0000..0x8_0000_0000, it is possible to remove the add.
    • Set BASE = 0 and SHIFT = 3 for this case.
  3. For heap > 31G, the add and shift operation is still necessary.

For cases (1) and (2), the jit compiled code will contain less or even no encoding/decoding instructions, and hence improve the mutator performance. However, in Rust code, we still do the add and shift unconditionally, even when BASE or SHIFT is set to zero.

NULL pointer checking

Generally, BASE can be any address as long as the memory is not reserved by others. However, BASE must be smaller than HEAP_START, otherwise HEAP_START will be encoded as 0 and be treated as a null pointer.

Same as openjdk, we set BASE to HEAP_START - 4096 to solve this issue.

Type specialization

Since we only support one edge type per binding, providing two OpenJDKEdge in one MMTK instance is not possible.

This PR solves the issue by specializing almost all the types in the binding, with a const COMPRESSED: bool generic type argument. It provides two MMTK singletons: MMTK<OpenJDK<COMPRESSED = true>> and MMTK<OpenJDK<COMPRESSED = false>>. MMTK<OpenJDK<COMPRESSED = true>> will have the OpenJDKEdge<COMPRESSED = true> edge that does the extra pointer compression/decompression.

The two MMTK singletons are wrapped in two lazy_static global variables. The binding will only initialize one of them depending on the OpenJDK command-line arguments. Initializing the wrong one that does not match the UseCompressedOops flag will trigger an assertion failure.

Pointer tagging

When compressed oops is enabled, all the fields are guaranteed to be compressed oops. However, stack or other global root pointers may be still uncompressed. The GC needs to handle both compressed and uncompressed edges and be able to distinguish between them.

To support this, this PR treats all the root OpenJDKEdge<COMPRESSED = true>s as tagged pointers. If the 63-th bit is set, this indicates that this edge points to a 64-nit uncompressed oop, instead of a compressed oop. And the OpenJDKEdge::{load, store} methods will skip the encoding/decoding step.

For object field edges, the encoding is performed unconditionally without the pointer tag check.

When compressed oops is disabled, there is no pointer tag check as well.

Embedded pointers

Some (or probably all) pointers embedded in code objects are also compressed. On x64, it is always compressed to a u32 integer that sits in an unaligned memory location. This means we need to (1) treat them as compressed oops just like other roots. (2) still performs the unaligned stores and loads.

However, for other architectures, the compressed embedded pointers may not be encoded as a u32 anymore.

Compressed Klass* pointers

When UseCompressedOops is enabled, by default it also enables UseCompressedClassPointers. This will make the Klass* pointer in the object header compressed to a u32 as well. This PR supports class pointer compression as well.

However, class pointer compression is only supported and tested when the compressed oops is enabled. The two flags must be enabled or disabled together. Enabling only one of them is not tested, not supported, and will trigger a runtime assertion failure.


Performance results

SemiSpace
Immix

@wenyuzhao
Copy link
Member Author

The PR is ready for review. Sometimes the CI job DaCapo Tests / test or DaCapo Tests / test-assertions can be cancelled for no reason... rerun it for a few more times can make it pass.

@qinsoon
Copy link
Member

qinsoon commented Sep 22, 2023

The PR is ready for review. Sometimes the CI job DaCapo Tests / test or DaCapo Tests / test-assertions can be cancelled for no reason... rerun it for a few more times can make it pass.

These are the runs that failed.
https://github.com/mmtk/mmtk-openjdk/actions/runs/6261214028/attempts/1
https://github.com/mmtk/mmtk-openjdk/actions/runs/6261214028/attempts/2

Error messages are:

The hosted runner: GitHub Actions 3 lost communication with the server. Anything in your workflow that terminates the runner process, starves it for CPU/Memory, or blocks its network access can cause this error.
The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.

If this only happened in a certain period of time, it simply could be a Github issue.

@qinsoon
Copy link
Member

qinsoon commented Sep 25, 2023

test-assertions failed again in https://github.com/mmtk/mmtk-openjdk/actions/runs/6293506467/job/17084111016 with the following error message. Github did not have reported performance downgrade when the job failed (https://www.githubstatus.com/). So it should not be a Github outage.

The runner has received a shutdown signal. This can happen when the runner service is stopped, or a manually started runner is canceled.

There are many discussions about this error for Github runners. It usually means the resources consumed in the process exceeded the limits. It could be related with the code change in the PR (if it consumes more memory or more CPU). It could also be changes in the Github runner specs. The simplest thing to try is to create another PR without any code change, and see if we see this error.

mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/api.rs Outdated Show resolved Hide resolved
mmtk/src/edges.rs Outdated Show resolved Hide resolved
mmtk/src/edges.rs Outdated Show resolved Hide resolved
mmtk/src/abi.rs Outdated Show resolved Hide resolved
mmtk/src/edges.rs Outdated Show resolved Hide resolved
mmtk/src/object_model.rs Outdated Show resolved Hide resolved
mmtk/src/object_model.rs Outdated Show resolved Hide resolved
mmtk/src/object_model.rs Outdated Show resolved Hide resolved
mmtk/src/object_scanning.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@wks wks left a comment

Choose a reason for hiding this comment

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

LGTM.

I also left a comment, but it may be too pedantic.

openjdk/mmtkHeap.cpp Outdated Show resolved Hide resolved
@wenyuzhao wenyuzhao merged commit f0ff0b5 into mmtk:master Oct 4, 2023
45 checks passed
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