[jmm-dev] VarHandle.safepoint() methods
Andrew Haley
aph at redhat.com
Thu Jan 5 14:09:18 UTC 2017
On 05/01/17 12:55, Doug Lea wrote:
> On 01/05/2017 04:56 AM, Andrew Haley wrote:
>
>>> The runtime is free to insert "checkpoint crossing boundaries"
>>> anywhere in code (between any two bytecodes), except where
>>> specifically prohibited by contract.
>>
>> I think I see. The underlying implementation mechanism would be
>> essentially the same, and would still allow references to be hoisted
>> out of loops, but we have an easier way to describe it in the
>> specification language.
>
> A complementary approach would be to allow programmers
> to manually insert safepoint checks, such that the JVM would
> not insert one if already there.
>
> As in (for some field x, VH X, and local r:)
> r = X.get(this);
> ...
> if (VarHandles.checkPointed()) // returns true if safepoint
> r = X.getAcquire(this);
>
> (This is analogous to cases when you manually null-check
> a reference -- the VM does not insert another one.)
>
> There would need to be some rules and/or a checker tool,
> which seem hard to come up with. But it would at least
> avoid needing to specify a special variant of VH.get,
> which seems even harder.
It's an interesting idea, for sure, but I'm not sure exactly what it
means. VarHandles.checkPointed() would say if there had been a
checkpoint, but since when? How would you specify that?
Let's say we have a loop, expanded for clarity.
for (int i = 0; i < n; i ++) {
sum += wrappedByteBuf.getSafepoint(vh).get(i);
}
I'd like the compiler to turn this into
MappedByteBuffer buf = wrappedByteBuf.getSafepoint(vh);
for (int i = 0; i < n; i ++) {
sum += buf.get(i);
}
and this would naturally be vectorized.
So your form would be
for (int i = 0; i < n; i ++) {
MappedByteBuffer buf = wrappedByteBuf.get();
if (VarHandles.checkPointed()) // returns true if safepoint
buf = wrappedByteBuf.getAcquire();
sum += buf.get(i);
}
I guess a smart compiler could see that VarHandles.checkPointed() will
never be true inside that loop. And it could decay into
MappedByteBuffer buf = wrappedByteBuf.get();
if (VarHandles.checkPointed()) // returns true if safepoint
buf = wrappedByteBuf.getAcquire();
for (int i = 0; i < n; i ++) {
sum += buf.get(i);
}
I think it'd be easier to specify this in terms of a full fence, like
so:
if (VarHandles.checkPointed()) // returns true if safepoint
VarHandles.fullFence();
It'd certainly be easier to implement, and it naturally matches
exactly what a safepoint does.
Andrew.
More information about the jmm-dev
mailing list