performance surprise with Object.hashCode()
Vitaly Davidovich
vitalyd at gmail.com
Mon May 13 10:20:49 PDT 2013
Object.hashCode is an intrinsic (see libraryCall.cpp), so it makes sense
you don't see any difference with your changes.
Looking at the assembly, when it knows statically that Integer is receiver
it simply reads the value field inline. When it doesn't know, it loads the
address of the receiver's hashCode method and compares against
Object.hashCode. If equal, then it proceeds with pulling hash out of
header. If it's not, it jumps to a vcall and then jumps again to function
prologue. I don't really see why you'd get such a large discrepancy. The
only thing is that if hashCode is overridden it jumps around a bit and may
get icache miss, but that would happen with plain vcall too. So basically
only thing "special" (in terms of vcall) I see for hashCode is a check
against an immediate (for seeing if hashCode is overridden or not), a
forward (short) jump to skip native object.hashCode impl and that's it.
Sent from my phone
On May 13, 2013 11:45 AM, "Andy Nuss" <andrew_nuss at yahoo.com> wrote:
> Hi,
>
> I was profiling various aspects of the JVM and hit a big surprise.
>
> * on my corei7, virtual calls are about .5 nanos
> * when a class has not derived a new behavior for hashCode(), this
> hashCode call is 1.5 nanos because native
> * for java.lang.Integer, which just returns the intValue(), hashCode is
> zero time when hotspot can inline
> (that is about one clock cycle when testing hits the same Integer
> instances keeping them in L1 cache)
> * but when you force HotSpot to go thru the vtable for Integer.hashCode,
> the call grows to 4 nanos!
>
> The last case was a big surprise, as I thought for Integer, a vcall to
> hashCode would only cost the 0.5 nanos of the vtable.
>
> Somehow, native code is involved even when hashCode() has been subclassed
> to not be native.
>
> ...
>
> Then I tried mucking with the code in openjdk. I compiled the sources. I
> edited Object.java to be this:
>
> public class Object {
> public int hashCode ()
> {
> return System.identityHashCode(this);
> }
> }
>
> To me, this seems like an ideal fix to this serious performance bug,
> making the entry point NON-native, but having the same effect by default.
> So that if you subclass, you are sure not to pay a doubled(!) native cost.
>
> But changing the source code had no effect on the results. Nor did it
> have any affect on /share/native/java/lang/Object.c.
>
> In both cases, with and without my change to the definition of
> Object.java, Object.c has NO native function definition for the hashCode
> function.
>
> This leads me to believe that this performance defect is endemic to the
> hotspot compiler code itself, in that it special cases the
> Object.hashCode() function.
>
> It seems that if somehow this performance defect (as I see it) where
> fixed, String hashing and Integer hashing and the like for classes which
> cache their hashvalue would be greatly improved.
>
> ???
>
> Andy
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20130513/ba497969/attachment-0001.html
More information about the hotspot-compiler-dev
mailing list