[RFR] (M) 8143608: Don't 64-bit align start of InstanceKlass vtable, itable, and nonstatic_oopmap on 32-bit systems
Chris Plummer
chris.plummer at oracle.com
Mon Dec 7 02:30:23 UTC 2015
On 12/6/15 2:15 PM, David Holmes wrote:
> Hi Chris,
>
> On 5/12/2015 8:02 AM, Chris Plummer wrote:
>> Hello,
>>
>> Please review the following:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8143608
>> http://cr.openjdk.java.net/~cjplummer/8143608/webrev.00/webrev.hotspot/
>>
>> A bit of background would help. The InstanceKlass object has a number of
>> variable length fields that are laid out after the declared fields. When
>> an InstanceKlass object is allocated, extra memory is allocated for it
>> to leave room for these fields. The first three of these fields are
>> vtable, itable, and nonstatic_oopmap. They are all arrays of HeapWord
>> sized values, which means void* size, which means they only need 32-bit
>> alignment on 32-bit systems. However, they have always been 64-bit
>> aligned. This webrev removes the forced 64-bit alignment on 32-bit
>> systems, saving footprint.
>
> Theory sounds fine.
>
> Not so sure about the practice though. In instanceKlass.hpp you have
> removed a lot of alignment adjustments and I can't be sure they are
> all necessarily correct. In particular:
>
> 934 static int header_size() { return
> sizeof(InstanceKlass)/HeapWordSize; }
>
> seems to me this will truncate the header size if
> sizeof(InstanceKlass) is not already 32-bit aligned. Are we assuming
> the compiler will always pad things such that this is true?
>
> In general I would have expected all the align_object_offset (which
> aligns to 64-bit) to be replaced with something that aligns to
> sizeof(void*). Even if we can assume a minimum of 32-bit alignment it
> isn't clear to me that that always converts to 64-bit alignment on
> 64-bit.
>
Hi David,
I had looked into pre-existing alignment assumptions and made sure I
didn't add to the assumptions. It turns out the old alignment would
approach would fail if sizeof(InstanceKlass() is not already aligned to
sizeof(void*). Let's look at how things worked before any of my changes.
The code used to be:
static int header_size() { return
align_object_offset(sizeof(InstanceKlass)/HeapWordSize); }
Keep in mind that this is asking for 64-bit alignment on both 32-bit and
64-bit systems. That's what align_object_offset() does, although it's
not really obvious from the name. So first a 32 bit example. Let's
assume sizeof(InstanceKlass) is 10 (not 32-bit aligned), so / by
HeapWordSize and you get 2.
align_object_offset(2) ==
align_size_up_(2, HeapWordsPerLong) ==
align_size_up(2, 2) ==
(2 + 1) & ~1 = 2
This is the wrong answer. We would want an offset of 10 to align to
64-bit align to 16, which is 4 words, not 2. Now see the difference if
sizeof(InstanceKlass) is already 32-bit aligned. Assume
sizeof(InstanceKlass) is 12:
align_object_offset(3) ==
align_size_up_(3, HeapWordsPerLong) ==
align_size_up(3, 2) ==
(3+ 1) & ~1 = 4
Now we get the right answer. Now for 64-bit systems, using the
sizeof(InstanceKlass) == 10:
align_object_offset(2) ==
align_size_up_(2, HeapWordsPerLong) ==
align_size_up(2, 1) ==
(2 + 0) & ~0 = 2
Wrong answer again. Now for sizeof(InstanceKlass) == 12, so it is 32-bit
aligned, but not 64-bit:
align_object_offset(3) ==
align_size_up_(3, HeapWordsPerLong) ==
align_size_up(3, 1) ==
(3+ 0) & ~0 = 3
Again the wrong answer. Now sizeof(InstanceKlass) == 16:
align_object_offset(4) ==
align_size_up_(4, HeapWordsPerLong) ==
align_size_up(4, 1) ==
(4+ 0) & ~0 = 4
This is what we want. So my conclusion is that we already have a
requirement that sizeof(InstanceKlass) be 32-bit aligned on 32-bit
systems and 64-bit aligned on 64-bit systems. Also, it turns out that
align_object_offset() is a no-op on 64-bit systems. The call is just
there to 64-bit align on 32-bit systems.
I would appreciate someone double checking my assumptions here.
BTW, since the last InstanceKlass field is a pointer type, we at least
know that the current alignment assumption being made is true, although
a bit presumptive.
thanks,
Chris
> Thanks,
> David
>
>> This change affects all 32-bit platforms. It should have no net impact
>> on 64-bit platforms since the fields remain (naturally) 64-bit aligned
>> (unless of course I've introduced a bug). The intent is to not change
>> what is done for 64-bit platforms.
>>
>> BTW, there is a change to AARCH64, which may seem odd at first. It just
>> removes an "if" block where the condition should always have evaluated
>> to false, so it should have no net affect.
>>
>> Tested with JPRT "-testset hotspot". Please let me know if you think
>> there are any additional tests that should be run.
>>
>> thanks,
>>
>> Chris
>>
More information about the hotspot-runtime-dev
mailing list