Skip to content

Redesign SpaceDescriptor for 64-bit architecture #1459

@wks

Description

@wks

The SpaceDescriptor type is inherited from JikesRVM, and it is designed for 32-bit architectures.

With 64-bit layout (Map64, more precisely, the generous layout where each space occupies a large contiguous region), the underlying value of the SpaceDescriptor will encode a tuple of (space_index: int62, is_high: bool, is_contiguous: bool), and is_contiguous is always true.

TODO list:

  • Stop confusing word size (32 or 64 bits) with memory layout (confined or generous). See: Refactor VMMap and introduce ChunkResource #932
  • Completely disable contiguous spaces in the confined layout, or design a new encoding that supports 64-bit machines.

With 32-bit layout (Map32, more precisely, the confined layout where some spaces can be contiguous, while others share one discontiguous range), a SpaceDescriptor encodes more information.

For discontiguous spaces in Map32, a SpaceDescriptor also encodes (space_index: int62, is_high: bool, is_contiguous: bool) like Map64, but is_contiguous is always false, and is_high is always false, too. And SpaceDescriptor also plays the role of automatically assigning space indices to discontiguous spaces (see SpaceDescriptor::create_descriptor() which atomically increments DISCONTIGUOUS_SPACE_INDEX).

For contiguous spaces in Map32, a SpaceDescriptor encodes the following: (mantissa: int14, exponent: int5, chunks: int10, is_high: bool, is_contiguous: bool). The starting address of the space is mantissa << (BASE_EXPONENT + exponent), and the extent is chunks << LOG_BYTES_IN_CHUNK. This allows any starting addresses that have at most 14 significant figures (binary) and at most 1023 chunks in size.

Currently, it is not a problem for the generous layout because we don't depend on the space descriptor to find any information. Given any address, we can find the space index from the address directly, and we know all spaces are contiguous, and we know their exact ranges.

It is not a problem for the confined layout if a space is discontiguous. Map32Inner::descriptor_map maintains a chunk-to-SpaceDescriptor map, and each SpaceDescriptor effectively only encodes the space index of the given chunk. We always know the memory range of the discontiguous memory when VM_MAP.finalize_static_space_map is called.

Although currently we are not having problem with contiguous spaces in confined layout because all spaces are discontiguous (including nursery), in theory the current design of SpaceDescriptor is problematic.

The problem

First of all, the terms Map32 vs Map64 continues to cause confusion about the address size and the generous/confined layout. Consequently, the encoding (mantissa: int14, exponent: int5, chunks: int10, is_high: bool, is_contiguous: bool) used by Map32 is designed for 32-bit machines. In this encoding, the significant figures (binary) are limited to 14 bits, and the space size is capped at 1023 chunks.

While this is not a problem for 32-bit machines, it is problematic on 64-bit machines. The OpenJDK binding, when using CompressedOops, uses Map32 on 64-bit machines, and the encoding is insufficient for such a large address space. With a large amount of memory, it should have no problem having a contiguous space of 1024 or more chunks (4GiB or more).

We may decode it is unwise to do so, but we need an answer whether we forbid it (and give a good reason), or design a new SpaceDescriptor encoding that can support such cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions