Bounds Check Elimination with Fast-Range

John Rose john.r.rose at oracle.com
Mon Nov 18 17:45:38 UTC 2019


On Nov 18, 2019, at 5:10 AM, Florian Weimer <fweimer at redhat.com> wrote:
> 
>> 
>> The idea is that, given (int) hash h and (int) size N, then ((long) h)
>> * N) >>> 32 is a good mapping.
> 
> I looked at this in the past weeks in a different context, and I don't
> think this would work because we have:

That technique appears to require either a well-conditioned hash code
(which is not the case with Integer.hashCode) or else a value of N that
performs extra mixing on h.  (So a very *non-*power-of-two value of N
would be better here, i.e., N with larger popcount.)

A little more mixing should help the problem Florian reports with a
badly conditioned h.  Given this:

int fr(int h) { return (int)(((long)h * N) >>> 32); }
int h = x.hashCode();
//int bucket = fr(h);  // weak if h is badly conditioned

then, assuming multiplication is cheap:

int bucket = fr(h * M); // M = 0x2357BD or something

or maybe something fast and sloppy like:

int bucket = fr(h + (h << 8));

or even:

int bucket = fr(h) ^ (h & (N-1));



More information about the hotspot-compiler-dev mailing list