--- old/src/java.base/share/classes/java/io/ObjectStreamClass.java 2017-09-03 16:47:11.500344676 +0900 +++ new/src/java.base/share/classes/java/io/ObjectStreamClass.java 2017-09-03 16:47:11.428344658 +0900 @@ -1185,6 +1185,22 @@ } } + private static final Unsafe U = Unsafe.getUnsafe(); + private static final long CDS_OFFSET; + + static { + Field field = null; + try { + field = ObjectStreamClass.class.getDeclaredField("dataLayout"); + } catch(NoSuchFieldException | SecurityException e) { + } + if(field == null) { + CDS_OFFSET = Unsafe.INVALID_FIELD_OFFSET; + } else { + CDS_OFFSET = U.objectFieldOffset(field); + } + } + /** * Returns array of ClassDataSlot instances representing the data layout * (including superclass data) for serialized objects described by this @@ -1194,10 +1210,12 @@ */ ClassDataSlot[] getClassDataLayout() throws InvalidClassException { // REMIND: synchronize instead of relying on volatile? - if (dataLayout == null) { - dataLayout = getClassDataLayout0(); + ClassDataSlot[] slots = (ClassDataSlot[])U.getObjectAcquire(this, CDS_OFFSET); + if (slots == null) { + slots = getClassDataLayout0(); + U.putObjectRelease(this, CDS_OFFSET, slots); } - return dataLayout; + return slots; } private ClassDataSlot[] getClassDataLayout0()