JDK-8270308: Amalloc aligns size but not return value #4784
may I have reviews for this fix to Arena alignment handling in hotspot. This affects the old Arena classes as well as child classes (ResourceArea, HandleArea etc). This is a followup to https://bugs.openjdk.java.net/browse/JDK-8270179 and other recent Arena fixes.
This makes arenas more flexible, allowing to allocate with different alignments to achieve tighter packing. Theoretically arenas should be able to do that today, but it is actually broken. We did not notice any errors though, probably because the only platforms affected are 32-bit platforms other than x86 (x86 allows unaligned access). Also, today in the VM nobody mixes different alignments - you either allocate only with Amalloc, so with 64bit alignment, or only with AmallocWords (former Amalloc_4), which is 32bit on 32bit.
I redid this patch twice. My first attempts rewrote a lot of the code, but I scratched that and in this patch kept it focused only on the alignment issue. Defer cleanups to separate RFEs.
This patch establishes new alignment rules, but actual behavioral changes to current Arena users should be minimal and should only affect 32-bit anyway.
Before this patch, Arena allocation checked (or auto-aligned) the allocation size in an attempt to guarantee alignment of the allocation start address. That was neither needed nor sufficient - see JBS text.
The new code just allows any allocation size, aligned or unaligned. However, it now clearly guarantees alignment of the allocation start address. E.g., theoretically, you could allocate a 16bit word at a 64bit boundary.
The arena does this by aligning, if needed, before an allocation. Alignment gaps are filled (debug build + ZapResourceArea) with a special zap pattern.
Ran all tests on 32bit and 64bit Linux on my box.
Nightlies at SAP are in progress.
The text was updated successfully, but these errors were encountered:
thank you for looking at this.
The benefit of having the caller choose the alignment would be to allow the caller to allocate with tighter alignments than 64bit, wasting less space. Currently, the vast majority of allocations come via NEW_RESOURCE_ARRAY in allocation.hpp, which just allocates with 64bit alignment. For many allocations, this alignment is unnecessary. For example, strings need no alignment at all. If you repeatedly put strings into RA, you may waste a lot of memory due to this alignment. And we put a lot of strings into RAs. I should probably measure how much space we really waste this way.
(Side note, due to the fact that Arenas use C-heap, and the fact that the glibc caches way too aggressively, the JVM never really recovers from spikes in arena usage. See also #4510. We even have a proprietary patch at SAP where we switched to mmap() forCompilerarenas for that very reason. So, reducing the Arena footprint is actually worthwhile).
ATM we allow two alignments, pointer size and 64bit. But you cannot actually mix those since you may end up with unaligned allocations - the original bug. So the fix for that would be to correctly align at allocation time. I thought allowing just any alignment would be even simpler, and might make it possible later on have something like, say, a NEW_RESOURCE_ARRAY_1 to allocate unaligned space for strings which need no alignment at all.
However, if you don't like this, here is a different proposal. We could make the alignment a property of an arena: every arena has a fixed allocation alignment, that's what you get when allocating. Things like HandleAreas would have pointer-sized alignments, since allocating with a different alignment makes no sense there and introduces errors (alignment gaps would be misinterpreted as oops). Thread ResourceAreas could be 64bit aligned. That way, we even could reduce the number of Amalloc.. functions to just one: Amalloc(). Which would allocate with whatever default alignment the arena has.
That way we don't benefit from tighter packing, but the code would be simpler and more correct and safer. Since you cannot mix different alignments, _hwm would never be unaligned.