JVM prune exception edges in inliner-specific DFA
This commit is contained in:
@@ -467,12 +467,9 @@ class MethodInliner(
|
||||
|
||||
replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode)
|
||||
|
||||
val toDelete = SmartSet.create<AbstractInsnNode>()
|
||||
|
||||
val sources = analyzeMethodNodeWithInterpreter(processingNode, FunctionalArgumentInterpreter(this))
|
||||
val instructions = processingNode.instructions
|
||||
|
||||
markObsoleteInstruction(instructions, toDelete, sources)
|
||||
val toDelete = markObsoleteInstruction(instructions, sources)
|
||||
|
||||
var awaitClassReification = false
|
||||
var currentFinallyDeep = 0
|
||||
@@ -625,11 +622,9 @@ class MethodInliner(
|
||||
return processingNode
|
||||
}
|
||||
|
||||
private fun MethodInliner.markObsoleteInstruction(
|
||||
instructions: InsnList,
|
||||
toDelete: SmartSet<AbstractInsnNode>,
|
||||
sources: Array<out Frame<BasicValue>?>
|
||||
) {
|
||||
private fun markObsoleteInstruction(instructions: InsnList, sources: Array<out Frame<BasicValue>?>): SmartSet<AbstractInsnNode> {
|
||||
val toDelete = SmartSet.create<AbstractInsnNode>()
|
||||
|
||||
for (insn in instructions) {
|
||||
// Parameter checks are processed separately
|
||||
if (insn.isAloadBeforeCheckParameterIsNotNull()) continue
|
||||
@@ -658,6 +653,8 @@ class MethodInliner(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toDelete
|
||||
}
|
||||
|
||||
// Replace ALOAD 0
|
||||
|
||||
@@ -110,10 +110,12 @@ internal class Aload0Interpreter(private val node: MethodNode) : BasicInterprete
|
||||
|
||||
internal fun AbstractInsnNode.isAload0() = opcode == Opcodes.ALOAD && (this as VarInsnNode).`var` == 0
|
||||
|
||||
internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: BasicInterpreter): Array<out Frame<BasicValue>?> {
|
||||
val analyzer = object : FastMethodAnalyzer<BasicValue>("fake", node, interpreter) {
|
||||
internal fun analyzeMethodNodeWithInterpreter(
|
||||
node: MethodNode,
|
||||
interpreter: BasicInterpreter
|
||||
): Array<out Frame<BasicValue>?> {
|
||||
val analyzer = object : FastMethodAnalyzer<BasicValue>("fake", node, interpreter, pruneExceptionEdges = true) {
|
||||
override fun newFrame(nLocals: Int, nStack: Int): Frame<BasicValue> {
|
||||
|
||||
return object : Frame<BasicValue>(nLocals, nStack) {
|
||||
@Throws(AnalyzerException::class)
|
||||
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) {
|
||||
|
||||
+6
-2
@@ -78,7 +78,7 @@ open class FastMethodAnalyzer<V : Value>
|
||||
|
||||
val isTcbStart = BooleanArray(nInsns)
|
||||
for (tcb in method.tryCatchBlocks) {
|
||||
isTcbStart[tcb.start.indexOf()] = true
|
||||
isTcbStart[tcb.start.indexOf() + 1] = true
|
||||
}
|
||||
|
||||
val current = newFrame(method.maxLocals, method.maxStack)
|
||||
@@ -118,7 +118,11 @@ open class FastMethodAnalyzer<V : Value>
|
||||
// So, unless we have a store operation, anything we change on stack would be lost,
|
||||
// and there's no need to analyze exception handler again.
|
||||
// Add an exception edge from TCB start to make sure handler itself is still visited.
|
||||
if (!pruneExceptionEdges || insnOpcode in Opcodes.ISTORE..Opcodes.ASTORE || insnOpcode == Opcodes.IINC || isTcbStart[insn]) {
|
||||
if (!pruneExceptionEdges ||
|
||||
insnOpcode in Opcodes.ISTORE..Opcodes.ASTORE ||
|
||||
insnOpcode == Opcodes.IINC ||
|
||||
isTcbStart[insn]
|
||||
) {
|
||||
handlers[insn]?.forEach { tcb ->
|
||||
val exnType = Type.getObjectType(tcb.type ?: "java/lang/Throwable")
|
||||
val jump = tcb.handler.indexOf()
|
||||
|
||||
Reference in New Issue
Block a user