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