<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 02/13/2015 03:54 AM, David Holmes
wrote:<br>
</div>
<blockquote cite="mid:54DD677F.10101@oracle.com" type="cite">Hi Tom,
<br>
<br>
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!
<br>
<br>
The rest seems okay but I'm still mulling over it. :)
<br>
<br>
Thanks,
<br>
David H.
<br>
</blockquote>
<br>
Hi,<br>
<br>
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.<br>
<br>
IHM has the following hashCode -> array slot index mapping
function:<br>
<br>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
/**<br>
* Returns index for Object x.<br>
*/<br>
private static int hash(Object x, int length) {<br>
int h = System.identityHashCode(x);<br>
// Multiply by -127, and left-shift to use least bit as part
of hash<br>
return ((h << 1) - (h << 8)) & (length - 1);<br>
}<br>
<br>
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:<br>
<br>
(h - (h << 7)) & (capacity - 1)<br>
<br>
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.<br>
<br>
So the question is, how frequent are IdentityHashMap(s) with >
10M entries or any other HashMaps with keys that don't override
Object.hashCode().<br>
<br>
Here's an JMH (<a class="moz-txt-link-freetext" href="http://openjdk.java.net/projects/code-tools/jmh/">http://openjdk.java.net/projects/code-tools/jmh/</a>)
micro-benchmark you can use to measure the impact of change on
IdentityHashMap:<br>
<br>
<a class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/~plevart/misc/IHMBench/IHMBench.java">http://cr.openjdk.java.net/~plevart/misc/IHMBench/IHMBench.java</a><br>
<br>
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.<br>
<br>
Regards, Peter<br>
<br>
<blockquote cite="mid:54DD677F.10101@oracle.com" type="cite">On
13/02/2015 6:14 AM, Tom Benson wrote:
<br>
<blockquote type="cite">Hi,
<br>
I need reviewers and a commit sponsor for changes for bug
6764713, which
<br>
will increase the size of the age field in an object header from
4 bits
<br>
to 5. This will allow a maximum MaxTenuringThreshold of 31,
though the
<br>
default will remain at the current value of 15.
<br>
<br>
This includes the same change to the 32-bit version, which would
close
<br>
bug 6719225 as well. In that case, the hash field in the header
is
<br>
affected, losing one bit (25 bits -> 24), so I have asked for
review
<br>
from hotspot-runtime-dev as well as gc-dev.
<br>
<br>
Webrev: <a class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/~jprovino/6764713/webrev.00">http://cr.openjdk.java.net/~jprovino/6764713/webrev.00</a>
<br>
JBS bug: <a class="moz-txt-link-freetext" href="https://bugs.openjdk.java.net/browse/JDK-6764713">https://bugs.openjdk.java.net/browse/JDK-6764713</a>
<br>
Testing: JPRT and reference server performance tests
<br>
<br>
Notes:
<br>
Contrary to what earlier notes in the JBS entry said, this does
not
<br>
require stronger alignment for the JavaThread structure for when
biased
<br>
locking stores that pointer in the header. The JavaThread* was
already
<br>
being aligned 1 power of 2 more strongly than it needed to be,
so there
<br>
was an unused bit that could be stolen.
<br>
<br>
In the 32-bit version, it does require taking one bit from the
hash
<br>
field, which goes from 25 to 24 bits. This is something I'd
especially
<br>
like feedback on. Running reference server performance tests, I
saw no
<br>
impact from this change. We *could* make this change
64-bit-only, and
<br>
leave the age field at 4 bits for the 32-bit version. If we did
so, we
<br>
could also decrease the alignment required for the JavaThread*
to 512
<br>
from the current 1024.
<br>
<br>
The comment changes imply that the bits available for the
JavaThread*
<br>
have been reduced by 1, and that the alignment is now stronger,
but
<br>
neither is true. The comments have been corrected to match the
<br>
alignment that was already enforced.
<br>
<br>
Three tests needed to be corrected to match the new limits.
These check
<br>
the maximum valid values, what value represents NeverTenure, and
so on.
<br>
<br>
Thanks,
<br>
Tom
<br>
<br>
</blockquote>
</blockquote>
<br>
</body>
</html>