JVM skip methods without NEW insns in UninitializedStoresProcessor

This commit is contained in:
Dmitry Petrov
2021-07-22 08:23:38 +03:00
committed by teamcityserver
parent eff7c375ce
commit 6c734289be
@@ -87,10 +87,10 @@ class UninitializedStoresProcessor(
fun run() { fun run() {
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions) val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
val frames = CustomFramesMethodAnalyzer( if (methodNode.instructions.toArray().none { it.opcode == Opcodes.NEW })
"fake", methodNode, interpreter, return
this::UninitializedNewValueFrame
).analyze() val frames = CustomFramesMethodAnalyzer("fake", methodNode, interpreter, this::UninitializedNewValueFrame).analyze()
interpreter.analyzePopInstructions(frames) interpreter.analyzePopInstructions(frames)
@@ -115,12 +115,12 @@ class UninitializedStoresProcessor(
// POP // POP
val typeNameForClass = newInsn.desc.replace('/', '.') val typeNameForClass = newInsn.desc.replace('/', '.')
insertBefore(newInsn, LdcInsnNode(typeNameForClass)) insertBefore(newInsn, LdcInsnNode(typeNameForClass))
insertBefore(newInsn, MethodInsnNode( insertBefore(
Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false newInsn,
)) MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false)
)
set(newInsn, InsnNode(Opcodes.POP)) set(newInsn, InsnNode(Opcodes.POP))
} } else {
else {
remove(newInsn) remove(newInsn)
} }
} }
@@ -138,10 +138,7 @@ class UninitializedStoresProcessor(
} }
methodNode.maxLocals = max(methodNode.maxLocals, nextVarIndex) methodNode.maxLocals = max(methodNode.maxLocals, nextVarIndex)
methodNode.instructions.insertBefore(insn, insnListOf( methodNode.instructions.insertBefore(insn, insnListOf(TypeInsnNode(Opcodes.NEW, newInsn.desc), InsnNode(Opcodes.DUP)))
TypeInsnNode(Opcodes.NEW, newInsn.desc),
InsnNode(Opcodes.DUP)
))
for (type in storedTypes.reversed()) { for (type in storedTypes.reversed()) {
nextVarIndex -= type.size nextVarIndex -= type.size
@@ -174,8 +171,8 @@ class UninitializedStoresProcessor(
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" } assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1 val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?: val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue
if (isInSpecialMethod) ?: if (isInSpecialMethod)
return null return null
else else
error("Expected value generated with NEW") error("Expected value generated with NEW")
@@ -236,7 +233,8 @@ class UninitializedStoresProcessor(
private fun checkUninitializedObjectCopy(newInsn: TypeInsnNode, usageInsn: AbstractInsnNode) { private fun checkUninitializedObjectCopy(newInsn: TypeInsnNode, usageInsn: AbstractInsnNode) {
when (usageInsn.opcode) { when (usageInsn.opcode) {
Opcodes.DUP, Opcodes.ASTORE, Opcodes.ALOAD -> {} Opcodes.DUP, Opcodes.ASTORE, Opcodes.ALOAD -> {
}
else -> error("Unexpected copy instruction for ${newInsn.debugText}: ${usageInsn.debugText}") else -> error("Unexpected copy instruction for ${newInsn.debugText}: ${usageInsn.debugText}")
} }
} }