EA-81358: use volatile store / volatile load to guarantee publication of deferred clinit results
This commit is contained in:
@@ -93,18 +93,24 @@ class MultifileClassPartCodegen(
|
|||||||
|
|
||||||
if (requiresDeferredStaticInitialization) {
|
if (requiresDeferredStaticInitialization) {
|
||||||
staticInitClassBuilder.apply {
|
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 {
|
newSpecialMethod(packageFragment, CLINIT_TRIGGER_NAME).apply {
|
||||||
visitCode()
|
visitCode()
|
||||||
|
visitFieldInsn(Opcodes.GETSTATIC, staticInitClassType.internalName, CLINIT_SYNC_NAME, "I")
|
||||||
visitInsn(Opcodes.RETURN)
|
visitInsn(Opcodes.RETURN)
|
||||||
visitMaxs(0, 0)
|
visitMaxs(1, 0)
|
||||||
visitEnd()
|
visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
newSpecialMethod(packageFragment, "<clinit>").apply {
|
newSpecialMethod(packageFragment, "<clinit>").apply {
|
||||||
visitCode()
|
visitCode()
|
||||||
visitMethodInsn(Opcodes.INVOKESTATIC, partType.internalName, DEFERRED_PART_CLINIT_NAME, "()V", false)
|
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)
|
visitInsn(Opcodes.RETURN)
|
||||||
visitMaxs(0, 0)
|
visitMaxs(1, 0)
|
||||||
visitEnd()
|
visitEnd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +193,7 @@ class MultifileClassPartCodegen(
|
|||||||
|
|
||||||
private val STATIC_INIT_CLASS_SUFFIX = "__Clinit"
|
private val STATIC_INIT_CLASS_SUFFIX = "__Clinit"
|
||||||
private val CLINIT_TRIGGER_NAME = "\$\$clinitTrigger"
|
private val CLINIT_TRIGGER_NAME = "\$\$clinitTrigger"
|
||||||
|
private val CLINIT_SYNC_NAME = "\$\$clinitSync"
|
||||||
private val DEFERRED_PART_CLINIT_NAME = "\$\$clinit"
|
private val DEFERRED_PART_CLINIT_NAME = "\$\$clinit"
|
||||||
|
|
||||||
@JvmStatic fun isStaticInitTrigger(insn: AbstractInsnNode) =
|
@JvmStatic fun isStaticInitTrigger(insn: AbstractInsnNode) =
|
||||||
|
|||||||
Reference in New Issue
Block a user