Switch from Guava graphs to JGraphT

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 5 years ago
parent e3095f4a7e
commit 5d8dce0ed2
  1. 1
      buildSrc/src/main/java/Versions.kt
  2. 1
      deob/build.gradle.kts
  3. 21
      deob/src/main/java/dev/openrs2/deob/analysis/ControlFlowAnalyzer.kt
  4. 15
      deob/src/main/java/dev/openrs2/deob/analysis/DataFlowAnalyzer.kt

@ -11,6 +11,7 @@ object Versions {
const val inlineLogger = "1.0.2" const val inlineLogger = "1.0.2"
const val javaParser = "3.15.18" const val javaParser = "3.15.18"
const val jdom = "2.0.6" const val jdom = "2.0.6"
const val jgrapht = "1.4.0"
const val jimfs = "1.1" const val jimfs = "1.1"
const val junit = "5.6.1" const val junit = "5.6.1"
const val kotlin = "1.3.71" const val kotlin = "1.3.71"

@ -15,6 +15,7 @@ dependencies {
implementation(project(":deob-annotations")) implementation(project(":deob-annotations"))
implementation("com.google.guava:guava:${Versions.guava}") implementation("com.google.guava:guava:${Versions.guava}")
implementation("it.unimi.dsi:fastutil:${Versions.fastutil}") implementation("it.unimi.dsi:fastutil:${Versions.fastutil}")
implementation("org.jgrapht:jgrapht-core:${Versions.jgrapht}")
} }
publishing { publishing {

@ -1,29 +1,30 @@
package dev.openrs2.deob.analysis package dev.openrs2.deob.analysis
import com.google.common.graph.Graph import org.jgrapht.Graph
import com.google.common.graph.GraphBuilder import org.jgrapht.graph.AsUnmodifiableGraph
import org.jgrapht.graph.DefaultDirectedGraph
import org.jgrapht.graph.DefaultEdge
import org.objectweb.asm.tree.MethodNode import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.analysis.Analyzer import org.objectweb.asm.tree.analysis.Analyzer
import org.objectweb.asm.tree.analysis.BasicInterpreter import org.objectweb.asm.tree.analysis.BasicInterpreter
import org.objectweb.asm.tree.analysis.BasicValue import org.objectweb.asm.tree.analysis.BasicValue
class ControlFlowAnalyzer : Analyzer<BasicValue>(BasicInterpreter()) { class ControlFlowAnalyzer : Analyzer<BasicValue>(BasicInterpreter()) {
private val graph = GraphBuilder private val graph = DefaultDirectedGraph<Int, DefaultEdge>(DefaultEdge::class.java)
.directed()
.allowsSelfLoops(true)
.immutable<Int>()
override fun newControlFlowEdge(insnIndex: Int, successorIndex: Int) { override fun newControlFlowEdge(insnIndex: Int, successorIndex: Int) {
graph.putEdge(insnIndex, successorIndex) graph.addVertex(insnIndex)
graph.addVertex(successorIndex)
graph.addEdge(insnIndex, successorIndex)
} }
override fun newControlFlowExceptionEdge(insnIndex: Int, successorIndex: Int): Boolean { override fun newControlFlowExceptionEdge(insnIndex: Int, successorIndex: Int): Boolean {
graph.putEdge(insnIndex, successorIndex) newControlFlowEdge(insnIndex, successorIndex)
return true return true
} }
fun createGraph(owner: String, method: MethodNode): Graph<Int> { fun createGraph(owner: String, method: MethodNode): Graph<Int, DefaultEdge> {
analyze(owner, method) analyze(owner, method)
return graph.build() return AsUnmodifiableGraph(graph)
} }
} }

@ -1,19 +1,20 @@
package dev.openrs2.deob.analysis package dev.openrs2.deob.analysis
import com.google.common.graph.Graph import org.jgrapht.Graph
import com.google.common.graph.Graphs import org.jgrapht.graph.DefaultEdge
import org.jgrapht.graph.EdgeReversedGraph
import org.objectweb.asm.tree.AbstractInsnNode import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.MethodNode import org.objectweb.asm.tree.MethodNode
abstract class DataFlowAnalyzer<T>(owner: String, private val method: MethodNode, backwards: Boolean = false) { abstract class DataFlowAnalyzer<T>(owner: String, private val method: MethodNode, backwards: Boolean = false) {
private val graph: Graph<Int> private val graph: Graph<Int, DefaultEdge>
private val inSets = mutableMapOf<Int, T>() private val inSets = mutableMapOf<Int, T>()
private val outSets = mutableMapOf<Int, T>() private val outSets = mutableMapOf<Int, T>()
init { init {
val forwardsGraph = ControlFlowAnalyzer().createGraph(owner, method) val forwardsGraph = ControlFlowAnalyzer().createGraph(owner, method)
graph = if (backwards) { graph = if (backwards) {
Graphs.transpose(forwardsGraph) EdgeReversedGraph(forwardsGraph)
} else { } else {
forwardsGraph forwardsGraph
} }
@ -40,7 +41,7 @@ abstract class DataFlowAnalyzer<T>(owner: String, private val method: MethodNode
} }
fun analyze() { fun analyze() {
for (node in graph.nodes()) { for (node in graph.vertexSet()) {
outSets[node] = createInitialSet() outSets[node] = createInitialSet()
} }
@ -48,8 +49,8 @@ abstract class DataFlowAnalyzer<T>(owner: String, private val method: MethodNode
do { do {
changed = false changed = false
for (node in graph.nodes()) { for (node in graph.vertexSet()) {
val predecessors = graph.predecessors(node).map { pred -> outSets[pred]!! } val predecessors = graph.incomingEdgesOf(node).map { edge -> outSets[graph.getEdgeSource(edge)]!! }
val inSet = if (predecessors.isEmpty()) { val inSet = if (predecessors.isEmpty()) {
createInitialSet() createInitialSet()

Loading…
Cancel
Save