[JVM] Fully move analyze method into FastAnalyzer
This commit is contained in:
+21
-8
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-10
@@ -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(
|
||||
|
||||
+4
-15
@@ -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,
|
||||
|
||||
+1
-9
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user