VarHandles & LMAX Disruptor

John Rose john.r.rose at oracle.com
Tue Aug 4 19:31:09 UTC 2015


On Aug 2, 2015, at 6:53 PM, Michael Barker <mikeb01 at gmail.com> wrote:
> 
> 3)  return (E) entries[((int) sequence) & indexMask];  // indexMask is a
> final field of value entries.length - 1
> 
> I suspect this is because the compiler can't assume that final fields are
> actually final.

Yes.  The JIT does not track the identity indexMask==entries.length.
And it needs to work directly with entries.length if it is to prove a safe
array access.

> 4)  return (E) entries[BUFFER_PAD + (((int) sequence) & (entries.length -
> ((BUFFER_PAD * 2) + 1)))];
> 
> I'm guessing it gets just too complex for the compiler to figure our that
> the resulting value will be less that entries.length.

True.  In particular, the JIT (as of today) cannot prove that the subexpression
(entries.length - FOO) is positive.  If it goes negative, then the "&" hack fails
to do what we want.

You could try this one:

5)  return (E) entries[mapSequenceToIndex(sequence, entries.length >> 1) & entries.length];

where the following method may or may not be hand-inlined:

   static int mapSequenceToIndex(long sequence, int logicalLength) {
      return sequence & (logicalLength-1) + BUFFER_PAD;
   }

Season to taste…  The point is that the JIT sees any random int expression,
followed by "& entries.length", which is enough to elide the range check.

— John


More information about the valhalla-dev mailing list