JVM skip methods without NEW insns in UninitializedStoresProcessor
This commit is contained in:
committed by
teamcityserver
parent
eff7c375ce
commit
6c734289be
+21
-23
@@ -73,8 +73,8 @@ import kotlin.math.max
|
||||
* - restore constructor arguments
|
||||
*/
|
||||
class UninitializedStoresProcessor(
|
||||
private val methodNode: MethodNode,
|
||||
private val shouldPreserveClassInitialization: Boolean
|
||||
private val methodNode: MethodNode,
|
||||
private val shouldPreserveClassInitialization: Boolean
|
||||
) {
|
||||
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
|
||||
//
|
||||
@@ -87,10 +87,10 @@ class UninitializedStoresProcessor(
|
||||
fun run() {
|
||||
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
|
||||
|
||||
val frames = CustomFramesMethodAnalyzer(
|
||||
"fake", methodNode, interpreter,
|
||||
this::UninitializedNewValueFrame
|
||||
).analyze()
|
||||
if (methodNode.instructions.toArray().none { it.opcode == Opcodes.NEW })
|
||||
return
|
||||
|
||||
val frames = CustomFramesMethodAnalyzer("fake", methodNode, interpreter, this::UninitializedNewValueFrame).analyze()
|
||||
|
||||
interpreter.analyzePopInstructions(frames)
|
||||
|
||||
@@ -115,12 +115,12 @@ class UninitializedStoresProcessor(
|
||||
// POP
|
||||
val typeNameForClass = newInsn.desc.replace('/', '.')
|
||||
insertBefore(newInsn, LdcInsnNode(typeNameForClass))
|
||||
insertBefore(newInsn, MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false
|
||||
))
|
||||
insertBefore(
|
||||
newInsn,
|
||||
MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false)
|
||||
)
|
||||
set(newInsn, InsnNode(Opcodes.POP))
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
remove(newInsn)
|
||||
}
|
||||
}
|
||||
@@ -138,10 +138,7 @@ class UninitializedStoresProcessor(
|
||||
}
|
||||
methodNode.maxLocals = max(methodNode.maxLocals, nextVarIndex)
|
||||
|
||||
methodNode.instructions.insertBefore(insn, insnListOf(
|
||||
TypeInsnNode(Opcodes.NEW, newInsn.desc),
|
||||
InsnNode(Opcodes.DUP)
|
||||
))
|
||||
methodNode.instructions.insertBefore(insn, insnListOf(TypeInsnNode(Opcodes.NEW, newInsn.desc), InsnNode(Opcodes.DUP)))
|
||||
|
||||
for (type in storedTypes.reversed()) {
|
||||
nextVarIndex -= type.size
|
||||
@@ -174,11 +171,11 @@ class UninitializedStoresProcessor(
|
||||
|
||||
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 newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
|
||||
if (isInSpecialMethod)
|
||||
return null
|
||||
else
|
||||
error("Expected value generated with NEW")
|
||||
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue
|
||||
?: if (isInSpecialMethod)
|
||||
return null
|
||||
else
|
||||
error("Expected value generated with NEW")
|
||||
|
||||
assert(peek(paramsCountIncludingReceiver - 1) is UninitializedNewValue) {
|
||||
"Next value after NEW should be one generated by DUP"
|
||||
@@ -188,8 +185,8 @@ class UninitializedStoresProcessor(
|
||||
}
|
||||
|
||||
private class UninitializedNewValue(
|
||||
val newInsn: TypeInsnNode,
|
||||
val internalName: String
|
||||
val newInsn: TypeInsnNode,
|
||||
val internalName: String
|
||||
) : StrictBasicValue(Type.getObjectType(internalName)) {
|
||||
override fun toString() = "UninitializedNewValue(internalName='$internalName')"
|
||||
}
|
||||
@@ -236,7 +233,8 @@ class UninitializedStoresProcessor(
|
||||
|
||||
private fun checkUninitializedObjectCopy(newInsn: TypeInsnNode, usageInsn: AbstractInsnNode) {
|
||||
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}")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user