Hi Ogata,
On 09/04/2017 10:23 AM, Kazunori Ogata wrote:
Hi Peter,
Thank you for your comment. I thought the compiler must insert memory
fence at the end of object initializer, but I agree relying on it is not
correct w.r.t. JMM.
Then I'll take 1) 1) Put VarHandle.fullFence() between initialization of
ClassDataSlot[] and writing the reference to non-volatile dataLayout.
(Webrev: http://cr.openjdk.java.net/~horii/8187033/webrev.01-fence/), as
it achieved the best performance.
Regards,
Ogata
If playing with mutable plain fields in multiple threads, it is
mandatory to read the plain field just once in program. Your implementation:
1196 ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
1197 // REMIND: synchronize instead of relying on volatile?
1198 if (dataLayout == null) {
1199 ClassDataSlot[] slots = getClassDataLayout0();
1200 VarHandle.fullFence();
1201 dataLayout = slots;
1202 }
1203 return dataLayout;
1204 }
reads dataLayout field twice (line 1198 and 1203). Those two reads may
reorder and 1st return non-null value, while the 2nd return previous
value - null. You should use a local variable to store the 1st read and
return the local variable at the end. Like:
ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
ClassDataSlot[] slots = dataLayout;
if (slots == null) {
ClassDataSlot[] slots = getClassDataLayout0();
VarHandle.fullFence();
dataLayout = slots;
}
return slots;
}
Regards, Peter