[RFR] (M) 8143608: Don't 64-bit align start of InstanceKlass vtable, itable, and nonstatic_oopmap on 32-bit systems
Dmitry Samersoff
dmitry.samersoff at oracle.com
Tue Dec 15 12:11:12 UTC 2015
Chris,
1. Please file a separate CR for SA (assign it to me) and go ahead with
your fix when it become ready.
2. As far as I understand the fix, you just removed explicit alignment
for all platforms (not only 32bit) and rely on compiler. I'm a bit
scared with it (see David's comments).
Also please contact SQE (Leonid Mesnik) about testing of the fix before
pushing it.
-Dmitry
On 2015-12-11 00:31, Chris Plummer wrote:
> Hi Mikael,
>
> See comments inline below:
>
> On 12/9/15 8:48 AM, Mikael Gerdin wrote:
>> On 2015-12-08 20:14, Chris Plummer wrote:
>>> [Adding serviceability-dev at openjdk.java.net]
>>>
>>> Hi Mikael,
>>>
>>> Thanks for pointing this out. I'll look into it some more. Are there any
>>> tests that should be failing as a result of this? I get the feeling no,
>>> since I see other issues here that existed before my change. For
>>> example, this code is not returning the proper size if the class is
>>> anonymous or is an interface. It needs to add 1 extra word in that case.
>>> See size() in instanceKlass.hpp.
>>>
>>> Another difference from the VM code is alignObjectSize() is being used
>>> by getSize(), but headerSize is set using alignObjectOffset(). The VM
>>> code uses align_object_offset in both cases.
>>>
>>> // Align the object size.
>>> public static long alignObjectSize(long size) {
>>> return VM.getVM().alignUp(size,
>>> VM.getVM().getMinObjAlignmentInBytes());
>>> }
>>>
>>> // All vm's align longs, so pad out certain offsets.
>>> public static long alignObjectOffset(long offset) {
>>> return VM.getVM().alignUp(offset, VM.getVM().getBytesPerLong());
>>> }
>>>
>>> So the difference here is in the use of getMinObjAlignmentInBytes (not
>>> what the VM does) vs getBytesPerLong (what the VM uses):
>>>
>>> public int getObjectAlignmentInBytes() {
>>> if (objectAlignmentInBytes == 0) {
>>> Flag flag = getCommandLineFlag("ObjectAlignmentInBytes");
>>> objectAlignmentInBytes = (flag == null) ? 8 :
>>> (int)flag.getIntx();
>>> }
>>> return objectAlignmentInBytes;
>>> }
>>>
>>> So this seems wrong for use in any InstanceKlass size or embedded field
>>> offset calculation. It is probably a remnant of when class metadata was
>>> stored in the java heap, and the size of InstanceKlass had to be padded
>>> out to the minimum heap object alignment. At least it is harmless if
>>> ObjectAlignmentInBytes is not set, and if set it is only supported for
>>> 64-bit:
>>>
>>> lp64_product(intx, ObjectAlignmentInBytes,
>>> 8, \
>>> "Default object alignment in bytes, 8 is
>>> minimum") \
>>> range(8,
>>> 256) \
>>> constraint(ObjectAlignmentInBytesConstraintFunc,AtParse) \
>>>
>>> I'll get these cleaned up, but it sure would be nice if there was a way
>>> to reliably test it.
>>
>> I'd say that it's quite possible to test it!
>> Create a whitebox.cpp entry point for determining the size of a class.
> Ok, but I instead decided to use jcmd with "GC.class_stats KlassBytes"
>>
>> Run a java program calling the entry point and printing the
>> InstanceKlass size as computed by calling InstanceKlass::size() on a
>> set of pre-determined set of complex and simple classes (vtables,
>> itables, anonymous, etc.)
> For now I just did this from the command line to do some quick checking.
> No test written.
>> Have the java program wait after it's finished printing.
>>
>> Launch the SA agent and attach it to the process.
>> Through several layers of magic, execute the incantation:
>>
>> mgerdin at mgerdin03:~/work/repos/hg/jdk9/hs-rt-work/hotspot$
>> ../build/linux-x86_64-normal-server-slowdebug/images/jdk/bin/java
>> sun.jvm.hotspot.CLHSDB 6211
>> Attaching to process 6211, please wait...
>> hsdb> jseval
>> "sapkg.utilities.SystemDictionaryHelper.findInstanceKlass('java/lang/Object').getSize();"
>>
>> 472
> Ok. I did this to get sizes as SA sees them. They were not just wrong
> for existing JDK, but in most cases off by a large margin. I did some
> investigating. This is InstanceKlass.getSize()
>
> public long getSize() {
> return Oop.alignObjectSize(getHeaderSize() +
> Oop.alignObjectOffset(getVtableLen()) +
> Oop.alignObjectOffset(getItableLen()) +
> Oop.alignObjectOffset(getNonstaticOopMapSize()));
> }
>
> The problem is that getHeaderSize() returns the size in bytes, but the
> others all return the size in words. They need to be multiplied by the
> word size to get the right value since the caller of getSize() expects
> the result to be in bytes.
>
> So we have multiple problems with SA with respect to the
> InstanceKlass.getSize() support:
>
> * Alignment issues introduced by me.
> * Some minor other issues like using alignObjectSize when it's not
> needed, and not taking into account extra fields for interfaces and
> anonymous classes.
> * Not multiplying the vtable, itable, and oopMapSize by the number of
> bytes in a word.
> * No test available.
>
> I'm not too sure how to proceed here w.r.t. my CR. I'm inclined to just
> make the SA adjustments needed to take into consideration the alignment
> changes I've made to InstanceKlass, and file a CRs for the rest (one for
> the existing bugs and one for the lack of any test).
>
> Please advise.
>
> thanks,
>
> Chris
>
>>
>> You could also create a javascript source file in the test directory
>> which performs the appropriate calls and do
>> hsdb> jsload /path/to/file.js
>> hsdb> jseval "doit()"
>>
>> where
>> file.js:
>> doit = function() {
>> sd = sapkg.utilities.SystemDictionaryHelper;
>> do_klass = function(name) {
>> writeln(sd.findInstanceKlass(name).getSize());
>> }
>>
>> do_klass('java/lang/Object');
>> do_klass('java/lang/Class');
>> }
>>
>>
>> The only problem is that the test can't reliably execute on
>> unconfigured os x setups because of OS level security requirements for
>> attaching to processes.
>>
>> After detaching HSDB with the "quit" command you tell the debugged
>> java process to terminate, for example by printing some string on its
>> stdin.
>>
>> Easy, right? :)
>>
>> /Mikael
>>
>>>
>>> thanks,
>>>
>>> Chris
>>>
>>> On 12/8/15 1:54 AM, Mikael Gerdin wrote:
>>>> Hi Chris,
>>>>
>>>> Not a review but I'm fairly sure that you need to update the
>>>> serviceability agent to reflect these changes, see for example:
>>>>
>>>> public long getSize() {
>>>> return Oop.alignObjectSize(
>>>> getHeaderSize() +
>>>> Oop.alignObjectOffset(getVtableLen()) +
>>>> Oop.alignObjectOffset(getItableLen()) +
>>>> Oop.alignObjectOffset(getNonstaticOopMapSize()));
>>>> }
>>>>
>>>> in InstanceKlass.java
>>>>
>>>> /Mikael
>>>>
>>>> On 2015-12-04 23:02, 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.
>>>>>
>>>>> 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
>>>>>
>>>>
>>>
>>
>
--
Dmitry Samersoff
Oracle Java development team, Saint Petersburg, Russia
* I would love to change the world, but they won't give me the source code.
More information about the serviceability-dev
mailing list