Use fastutil to reduce allocations in LiveVariableAnalyzer

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 5 years ago
parent 6c31bf9af7
commit e3095f4a7e
  1. 1
      buildSrc/src/main/java/Versions.kt
  2. 1
      deob/build.gradle.kts
  3. 47
      deob/src/main/java/dev/openrs2/deob/analysis/LiveVariableAnalyzer.kt

@ -4,6 +4,7 @@ object Versions {
const val clikt = "2.6.0" const val clikt = "2.6.0"
const val commonsCompress = "1.20" const val commonsCompress = "1.20"
const val dependencyLicenseReport = "1.13" const val dependencyLicenseReport = "1.13"
const val fastutil = "8.3.1"
const val fernflower = "1.0.3" const val fernflower = "1.0.3"
const val guava = "28.2-jre" const val guava = "28.2-jre"
const val guice = "4.2.3" const val guice = "4.2.3"

@ -14,6 +14,7 @@ dependencies {
implementation(project(":bundler")) implementation(project(":bundler"))
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}")
} }
publishing { publishing {

@ -1,5 +1,8 @@
package dev.openrs2.deob.analysis package dev.openrs2.deob.analysis
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import it.unimi.dsi.fastutil.ints.IntSet
import it.unimi.dsi.fastutil.ints.IntSets
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.AbstractInsnNode import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.IincInsnNode import org.objectweb.asm.tree.IincInsnNode
@ -7,17 +10,17 @@ import org.objectweb.asm.tree.MethodNode
import org.objectweb.asm.tree.VarInsnNode import org.objectweb.asm.tree.VarInsnNode
class LiveVariableAnalyzer(owner: String, method: MethodNode) : class LiveVariableAnalyzer(owner: String, method: MethodNode) :
DataFlowAnalyzer<Set<Int>>(owner, method, backwards = true) { DataFlowAnalyzer<IntSet>(owner, method, backwards = true) {
override fun createInitialSet(): Set<Int> { override fun createInitialSet(): IntSet {
return emptySet() return IntSets.EMPTY_SET
} }
override fun join(set1: Set<Int>, set2: Set<Int>): Set<Int> { override fun join(set1: IntSet, set2: IntSet): IntSet {
return set1 union set2 return set1 union set2
} }
override fun transfer(set: Set<Int>, insn: AbstractInsnNode): Set<Int> { override fun transfer(set: IntSet, insn: AbstractInsnNode): IntSet {
return when (insn) { return when (insn) {
is VarInsnNode -> when (insn.opcode) { is VarInsnNode -> when (insn.opcode) {
Opcodes.ILOAD, Opcodes.LLOAD, Opcodes.FLOAD, Opcodes.DLOAD, Opcodes.ALOAD -> set.plus(insn.`var`) Opcodes.ILOAD, Opcodes.LLOAD, Opcodes.FLOAD, Opcodes.DLOAD, Opcodes.ALOAD -> set.plus(insn.`var`)
@ -28,4 +31,38 @@ class LiveVariableAnalyzer(owner: String, method: MethodNode) :
else -> set else -> set
} }
} }
private infix fun IntSet.union(other: IntSet): IntSet {
if (this == other || other.isEmpty()) {
return this
} else if (isEmpty()) {
return other
}
val set = IntOpenHashSet(this)
set.addAll(other)
return set
}
private fun IntSet.plus(element: Int): IntSet {
if (contains(element)) {
return this
}
val newSet = IntOpenHashSet(this)
newSet.add(element)
return newSet
}
private fun IntSet.minus(element: Int): IntSet {
if (!contains(element)) {
return this
} else if (size == 1) {
return IntSets.EMPTY_SET
}
val newSet = IntOpenHashSet(this)
newSet.remove(element)
return newSet
}
} }

Loading…
Cancel
Save