You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our code about allocation and alignment calculation is ported from Java MMTk. There is an assumption about Java MMTk that an object size is always a multiple of known alignment. (code)
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(size == Conversions.roundDown(size, knownAlignment));
known_alignment means we know the actual alignment of the current allocation cursor, e.g. the start of a cell (free list allocator), or the start of a page (large object allocator). known_alignment is a multiple of min alignment. So in Java MMTk, an object size is always a multiple of min alignment. When we do not have an actual known_alignment, MIN_ALIGNMENT is used instead.
With this assumption, we know that the start of an allocation is aligned to min alignment, and the size is aligned to min alignment. Then we know that at the end of an allocation, the address is always aligned to min alignment. That means when we start the next allocation, the address is aligned to min alignment. (code)
We initially ported all the code from Java MMTk, so mmtk-core also has those assumptions.
Rust MMTk: ALLOC_END_ALIGNMENT
We noticed that the assertion about object size failed, and changed that assertion in #140 by introducing a VM-specific constant ALLOC_END_ALIGNMENT. This allows the VM to specify the alignment at the end of an allocation (start + size), and when we calculate the alignment of the next allocation, we know the current cursor is at least aligned to ALLOC_END_ALIGNMENT.
With this change, a VM can call MMTk with arbitrary object sizes. However, though we changed the assertion, we did not correctly change some of the code that still needs this object size assumption to work. For example,
We should also use known_alignment whenever we know the known alignment, e.g. mimalloc allocator's cell is aligned to address size, large object allocator's allocation is aligned to pages.
Bug in Java MMTk?
Java MMTk calculates aligned size without using offset. (code)
(MIN_ALIGNMENT = 4, MAX_ALIGNMENT = 8 for Java MMTk/JikesRVM)
I think this is incorrect. For example, when we try allocate an object of size = 8, alignment = 8, offset = 4 in a free list cell that is aligned to 8 (knownAlignment = 8). As alignment <= knowAlignment, this method will simply return the size 8. But we need at least 12 bytes to accomodate the request of size = 8, alignment = 8, offset = 4 with a cursor aligned at 8.
Similarly under those conditions, alignAllocation also just returns region without any alignment padding. (code)
We possibly need to pass offset to get_maximum_aligned_size. When offset is not used, or is zero, we can do the simple check as what it is now. Otherwise, we will have to compute the alignment padding, and count that into the size.
The text was updated successfully, but these errors were encountered:
Java MMTk object size assumption
Our code about allocation and alignment calculation is ported from Java MMTk. There is an assumption about Java MMTk that an object size is always a multiple of known alignment. (code)
known_alignment
means we know the actual alignment of the current allocation cursor, e.g. the start of a cell (free list allocator), or the start of a page (large object allocator).known_alignment
is a multiple of min alignment. So in Java MMTk, an object size is always a multiple of min alignment. When we do not have an actualknown_alignment
,MIN_ALIGNMENT
is used instead.With this assumption, we know that the start of an allocation is aligned to min alignment, and the size is aligned to min alignment. Then we know that at the end of an allocation, the address is always aligned to min alignment. That means when we start the next allocation, the address is aligned to min alignment. (code)
This is also why Java MMTk often uses
MIN_ALIGNMENT
as the default value forknown_alignment
.Java MMTk also assumes the alignment offset is a multiple of minimal alignment. (code)
We initially ported all the code from Java MMTk, so
mmtk-core
also has those assumptions.Rust MMTk:
ALLOC_END_ALIGNMENT
We noticed that the assertion about object size failed, and changed that assertion in #140 by introducing a VM-specific constant
ALLOC_END_ALIGNMENT
. This allows the VM to specify the alignment at the end of an allocation(start + size)
, and when we calculate the alignment of the next allocation, we know the current cursor is at least aligned toALLOC_END_ALIGNMENT
.mmtk-core/src/util/alloc/allocator.rs
Line 58 in 06237f1
With this change, a VM can call MMTk with arbitrary object sizes. However, though we changed the assertion, we did not correctly change some of the code that still needs this object size assumption to work. For example,
mmtk-core/src/util/alloc/allocator.rs
Lines 23 to 39 in 06237f1
ALLOC_END_ALIGNMENT
instead.known_alignment
whenever we know the known alignment, e.g. mimalloc allocator's cell is aligned to address size, large object allocator's allocation is aligned to pages.Bug in Java MMTk?
Java MMTk calculates aligned size without using
offset
. (code)(
MIN_ALIGNMENT = 4, MAX_ALIGNMENT = 8
for Java MMTk/JikesRVM)I think this is incorrect. For example, when we try allocate an object of
size = 8, alignment = 8, offset = 4
in a free list cell that is aligned to 8 (knownAlignment = 8
). Asalignment <= knowAlignment
, this method will simply return the size 8. But we need at least 12 bytes to accomodate the request ofsize = 8, alignment = 8, offset = 4
with a cursor aligned at 8.Similarly under those conditions,
alignAllocation
also just returnsregion
without any alignment padding. (code)offset
toget_maximum_aligned_size
. When offset is not used, or is zero, we can do the simple check as what it is now. Otherwise, we will have to compute the alignment padding, and count that into the size.The text was updated successfully, but these errors were encountered: