RFR(s): 6764713: Enlarge the age field in object headers to allow a higher MaxTenuringThreshold

Peter Levart peter.levart at gmail.com
Fri Feb 13 13:47:53 UTC 2015


On 02/13/2015 03:54 AM, David Holmes wrote:
> Hi Tom,
>
> If you are potentially messing with the (identity) hash of all Java 
> objects in the 32-bit case then this needs a broader discussion eg on 
> core-libs-dev (cc'd) as this will impact end-user code the most!
>
> The rest seems okay but I'm still mulling over it. :)
>
> Thanks,
> David H.

Hi,

As I understand, this will make identity hashCode have 2^24 instead of 
2^25 distinct values on 32 bit architectures, right? This will mostly 
affect java.util.IdentityHashMap performance (and any use of objects 
that don't override hashCode in other hashCode-based Maps). IHM has a 
maximum capacity of 2^29 (key, value) slots. Performance will start to 
degrade sooner - at sizes > 2^24 / 1.5 (~10M) instead of 2^25 / 1.5 
(~20M) entries.

IHM has the following hashCode -> array slot index mapping function:

     /**
      * Returns index for Object x.
      */
     private static int hash(Object x, int length) {
         int h = System.identityHashCode(x);
         // Multiply by -127, and left-shift to use least bit as part of 
hash
         return ((h << 1) - (h << 8)) & (length - 1);
     }

Left-shift is added because keys are located at even indexes and 
associated values are at odd indexes in the same array. So the function 
to map hashCode to ordinal key index is actually:

     (h - (h << 7)) & (capacity - 1)

where capacity is a power of two <= 2^29, which means that it is 
necessary that 24 hash bits from Object header be mapped to lower 24 
bits of Object.hashCode(). Object.hashCode() in range 0..2^24-1 should 
still be enough to address the whole range of 2^29 capacity table given 
the above mapping function.

So the question is, how frequent are IdentityHashMap(s) with > 10M 
entries or any other HashMaps with keys that don't override 
Object.hashCode().

Here's an JMH (http://openjdk.java.net/projects/code-tools/jmh/) 
micro-benchmark you can use to measure the impact of change on 
IdentityHashMap:

     http://cr.openjdk.java.net/~plevart/misc/IHMBench/IHMBench.java

by default it creates an IdentityHashMap with size of 2^24 entries. This 
is where the performance difference is expected to start to be different 
between 24bit vs. 25bit hash codes. You can also try to use larger (up 
to 28) 'log2size' parameter, but you might want to increate -Xmx too in 
this case.

Regards, Peter

> On 13/02/2015 6:14 AM, Tom Benson wrote:
>> Hi,
>> I need reviewers and a commit sponsor for changes for bug 6764713, which
>> will increase the size of the age field in an object header from 4 bits
>> to 5. This will allow a maximum MaxTenuringThreshold of 31, though the
>> default will remain at the current value of 15.
>>
>> This includes the same change to the 32-bit version, which would close
>> bug 6719225 as well.  In that case, the hash field in the header is
>> affected, losing one bit (25 bits -> 24), so I have asked for review
>> from hotspot-runtime-dev as well as gc-dev.
>>
>> Webrev: http://cr.openjdk.java.net/~jprovino/6764713/webrev.00
>> JBS bug: https://bugs.openjdk.java.net/browse/JDK-6764713
>> Testing:  JPRT and reference server performance tests
>>
>> Notes:
>> Contrary to what earlier notes in the JBS entry said, this does not
>> require stronger alignment for the JavaThread structure for when biased
>> locking stores that pointer in the header.   The JavaThread* was already
>> being aligned 1 power of 2 more strongly than it needed to be, so there
>> was an unused bit that could be stolen.
>>
>> In the 32-bit version, it does require taking one bit from the hash
>> field, which goes from 25 to 24 bits.  This is something I'd especially
>> like feedback on.  Running reference server performance tests, I saw no
>> impact from this change.  We *could* make this change 64-bit-only, and
>> leave the age field at 4 bits for the 32-bit version.  If we did so, we
>> could also decrease the alignment required for the JavaThread* to 512
>> from the current 1024.
>>
>> The comment changes imply that the bits available for the JavaThread*
>> have been reduced by 1, and that the alignment is now stronger, but
>> neither is true.  The comments have been corrected to match the
>> alignment that was already enforced.
>>
>> Three tests needed to be corrected to match the new limits. These check
>> the maximum valid values, what value represents NeverTenure, and so on.
>>
>> Thanks,
>> Tom
>>



More information about the hotspot-runtime-dev mailing list