EA-81358: use volatile store / volatile load to guarantee publication of deferred clinit results

This commit is contained in:
Dmitry Petrov
2016-04-13 12:12:41 +03:00
parent 9495257de3
commit 82946437d8
@@ -93,18 +93,24 @@ class MultifileClassPartCodegen(
if (requiresDeferredStaticInitialization) {
staticInitClassBuilder.apply {
newField(OtherOrigin(packageFragment), Opcodes.ACC_STATIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_VOLATILE,
CLINIT_SYNC_NAME, "I", null, null)
newSpecialMethod(packageFragment, CLINIT_TRIGGER_NAME).apply {
visitCode()
visitFieldInsn(Opcodes.GETSTATIC, staticInitClassType.internalName, CLINIT_SYNC_NAME, "I")
visitInsn(Opcodes.RETURN)
visitMaxs(0, 0)
visitMaxs(1, 0)
visitEnd()
}
newSpecialMethod(packageFragment, "<clinit>").apply {
visitCode()
visitMethodInsn(Opcodes.INVOKESTATIC, partType.internalName, DEFERRED_PART_CLINIT_NAME, "()V", false)
visitInsn(Opcodes.ICONST_0)
visitFieldInsn(Opcodes.PUTSTATIC, staticInitClassType.internalName, CLINIT_SYNC_NAME, "I")
visitInsn(Opcodes.RETURN)
visitMaxs(0, 0)
visitMaxs(1, 0)
visitEnd()
}
}
@@ -187,6 +193,7 @@ class MultifileClassPartCodegen(
private val STATIC_INIT_CLASS_SUFFIX = "__Clinit"
private val CLINIT_TRIGGER_NAME = "\$\$clinitTrigger"
private val CLINIT_SYNC_NAME = "\$\$clinitSync"
private val DEFERRED_PART_CLINIT_NAME = "\$\$clinit"
@JvmStatic fun isStaticInitTrigger(insn: AbstractInsnNode) =