[JVM] Fully move analyze method into FastAnalyzer

This commit is contained in:
Ivan Kylchik
2023-08-24 12:07:59 +02:00
committed by Space Team
parent abe727fdd7
commit 02d8a62cb0
4 changed files with 27 additions and 42 deletions
@@ -28,7 +28,19 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
private val queue = IntArray(nInsns)
private var top = 0
protected fun analyzeInner() {
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return frames
checkAssertions()
computeExceptionHandlers(method)
beforeAnalyze()
analyzeMainLoop()
return frames
}
private fun analyzeMainLoop() {
val current = newFrame(method.maxLocals, method.maxStack)
val handler = newFrame(method.maxLocals, method.maxStack)
initLocals(current)
@@ -37,8 +49,7 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
while (top > 0) {
val insn = queue[--top]
@Suppress("UNCHECKED_CAST")
val f = frames[insn]!! as F
val f = getFrame(insn)!!
queued[insn] = false
val insnNode = method.instructions[insn]
@@ -63,6 +74,8 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
}
}
protected open fun beforeAnalyze() {}
protected abstract fun initLocals(current: F)
protected abstract fun mergeControlFlowEdge(dest: Int, frame: F, canReuse: Boolean = false)
@@ -89,8 +102,6 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
frames[index] = newFrame
}
protected fun getFrames(): Array<Frame<V>?> = frames
protected fun visitMeaningfulInstruction(insnNode: AbstractInsnNode, insnType: Int, insnOpcode: Int, current: F, insn: Int) {
when {
insnType == AbstractInsnNode.JUMP_INSN ->
@@ -111,7 +122,7 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
protected abstract fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: F)
protected abstract fun visitOpInsn(insnNode: AbstractInsnNode, current: F, insn: Int)
protected fun checkAssertions() {
private fun checkAssertions() {
if (method.instructions.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6")
}
@@ -119,9 +130,11 @@ abstract class FastAnalyzer<V : Value, I : Interpreter<V>, F : Frame<V>>(
protected fun AbstractInsnNode.indexOf() =
method.instructions.indexOf(this)
protected fun computeExceptionHandlers(m: MethodNode, forEachInsn: Boolean = true) {
protected open fun useFastComputeExceptionHandlers(): Boolean = false
private fun computeExceptionHandlers(m: MethodNode) {
for (tcb in m.tryCatchBlocks) {
if (forEachInsn) computeExceptionHandlersForEachInsn(tcb) else computeExceptionHandlerFast(tcb)
if (useFastComputeExceptionHandlers()) computeExceptionHandlerFast(tcb) else computeExceptionHandlersForEachInsn(tcb)
}
}
@@ -57,19 +57,10 @@ open class FastMethodAnalyzer<V : Value>
override fun newFrame(nLocals: Int, nStack: Int): Frame<V> =
Frame(nLocals, nStack)
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return getFrames()
checkAssertions()
computeExceptionHandlers(method)
override fun beforeAnalyze() {
for (tcb in method.tryCatchBlocks) {
isTcbStart[tcb.start.indexOf() + 1] = true
}
analyzeInner()
return getFrames()
}
override fun analyzeInstruction(
@@ -44,6 +44,8 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Value
/**
* @see org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
*/
// This is a very specific version of method bytecode analyzer that doesn't perform any DFA,
// but infers stack types for reachable instructions instead.
internal open class FastStackAnalyzer<V : Value>(
owner: String,
method: MethodNode,
@@ -55,21 +57,8 @@ internal open class FastStackAnalyzer<V : Value>(
protected open fun visitControlFlowExceptionEdge(insn: Int, successor: Int): Boolean = true
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return getFrames()
// This is a very specific version of method bytecode analyzer that doesn't perform any DFA,
// but infers stack types for reachable instructions instead.
checkAssertions()
// Don't have to visit same exception handler multiple times - we care only about stack state at TCB start.
computeExceptionHandlers(method, forEachInsn = false)
analyzeInner()
return getFrames()
}
// Don't have to visit the same exception handler multiple times - we care only about stack state at TCB start.
override fun useFastComputeExceptionHandlers(): Boolean = true
override fun analyzeInstruction(
insnNode: AbstractInsnNode,
@@ -106,16 +106,8 @@ class FastStoreLoadAnalyzer<V : StoreLoadValue>(
) : FastAnalyzer<V, StoreLoadInterpreter<V>, StoreLoadFrame<V>>(owner, method, interpreter) {
private val isMergeNode = BooleanArray(nInsns)
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return getFrames()
checkAssertions()
computeExceptionHandlers(method)
override fun beforeAnalyze() {
initMergeNodes()
analyzeInner()
return getFrames()
}
override fun analyzeInstruction(