Skip to content

Commit 82ab049

Browse files
fix: improper caching in JcTestVisitor inheritors (UnitTestBot#17)
* fix: improper caching in JcTestVisitor inheritors * sytle fixes
1 parent 47f86d9 commit 82ab049

3 files changed

Lines changed: 31 additions & 30 deletions

File tree

usvm-jvm-rendering/src/main/kotlin/org/usvm/jvm/rendering/testRenderer/JcTestRenderer.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import org.usvm.test.api.UTestConstExpression
1414
import org.usvm.test.api.UTestExpression
1515
import java.util.IdentityHashMap
1616
import org.jacodb.api.jvm.JcClasspath
17+
import org.usvm.test.api.UTestInst
1718

1819
open class JcTestRenderer(
1920
private val test: UTest,
@@ -53,14 +54,15 @@ open class JcTestRenderer(
5354

5455
inner class JcExprUsageVisitor: JcTestVisitor() {
5556

56-
private val exprCache: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
57+
private fun shouldDeclareVarCheck(expr: UTestExpression): Boolean {
58+
return !preventVarDeclarationOf(expr) && isVisited(expr) || requireVarDeclarationOf(expr)
59+
}
5760

58-
override fun visit(expr: UTestExpression) {
59-
if (!preventVarDeclarationOf(expr) && !exprCache.add(expr) || requireVarDeclarationOf(expr))
60-
// Multiple usage of expression
61-
shouldDeclareVar.add(expr)
61+
override fun visit(inst: UTestInst) {
62+
if (inst is UTestExpression && shouldDeclareVarCheck(inst))
63+
shouldDeclareVar.add(inst)
6264

63-
super.visit(expr)
65+
super.visit(inst)
6466
}
6567
}
6668

usvm-jvm-rendering/src/main/kotlin/org/usvm/jvm/rendering/testRenderer/JcTestVisitor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ open class JcTestVisitor {
4141

4242
private val cache: MutableSet<UTestInst> = Collections.newSetFromMap<UTestInst>(IdentityHashMap())
4343

44+
protected fun isVisited(inst: UTestInst) = cache.contains(inst)
45+
4446
fun visit(test: UTest) {
4547
for (inst in test.initStatements)
4648
visit(inst)
4749

48-
visitCall(test.callMethodExpression)
50+
visit(test.callMethodExpression as UTestInst)
4951
}
5052

5153
open fun visit(inst: UTestInst) {

usvm-jvm-rendering/src/main/kotlin/org/usvm/jvm/rendering/testTransformers/JcDeadCodeTransformer.kt

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ import org.usvm.test.api.UTestStatement
1717
class JcDeadCodeTransformer: JcTestTransformer() {
1818
private val roots: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
1919
private val reachable: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
20-
private lateinit var rootFetcher: ReachabilityRootFetcher
20+
21+
private val rootFetcher get() = ReachabilityRootFetcher(roots)
22+
2123
private class ReachabilityRootFetcher(val roots: MutableSet<UTestExpression>): JcTestVisitor() {
2224
val fetched: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
2325

2426
fun fetchFrom(expr: UTestExpression): MutableSet<UTestExpression> = fetchFrom(listOf(expr))
2527
fun fetchFrom(exprs: List<UTestExpression>): MutableSet<UTestExpression> {
26-
fetched.clear()
2728

2829
for (expr in exprs) {
2930
visitExpr(expr)
@@ -42,31 +43,14 @@ class JcDeadCodeTransformer: JcTestTransformer() {
4243
}
4344

4445
private class ReachabilityCollector(
45-
val test: UTest,
4646
val roots: MutableSet<UTestExpression>,
4747
val reachable: MutableSet<UTestExpression>
4848
) : JcTestVisitor() {
4949
private var marker = false
5050

51-
fun prepareRootFetcher(): ReachabilityRootFetcher {
52-
super.visit(test)
53-
propagateWhilePossible(test)
54-
return ReachabilityRootFetcher(roots)
55-
}
56-
57-
private fun propagateWhilePossible(test: UTest) {
58-
val clone: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
59-
60-
do {
61-
clone.clear()
62-
clone.addAll(reachable)
63-
check(clone.size == reachable.size)
64-
(test.initStatements + test.callMethodExpression).forEach { inst ->
65-
marker = false
66-
visit(inst)
67-
}
68-
69-
} while (clone.size != reachable.size)
51+
override fun visit(inst: UTestInst) {
52+
marker = false
53+
super.visit(inst)
7054
}
7155

7256
override fun visit(stmt: UTestSetStaticFieldStatement) {
@@ -140,8 +124,10 @@ class JcDeadCodeTransformer: JcTestTransformer() {
140124
}
141125

142126
override fun transform(test: UTest): UTest {
127+
roots.clear()
128+
reachable.clear()
143129

144-
rootFetcher = ReachabilityCollector(test, roots, reachable).prepareRootFetcher()
130+
propagateReachabilityIn(test)
145131

146132
val filteredInitInstList = test.initStatements.flatMap {
147133
transformInstProxy(it)
@@ -152,6 +138,17 @@ class JcDeadCodeTransformer: JcTestTransformer() {
152138
return UTest(filteredInitInstList, callMethodExpression)
153139
}
154140

141+
private fun propagateReachabilityIn(test: UTest) {
142+
val clone: MutableSet<UTestExpression> = Collections.newSetFromMap(IdentityHashMap())
143+
144+
do {
145+
clone.clear()
146+
clone.addAll(reachable)
147+
check(clone.size == reachable.size)
148+
ReachabilityCollector(roots, reachable).visit(test)
149+
} while (clone.size != reachable.size)
150+
}
151+
155152
private fun transformExprs(expr: UTestExpression): List<UTestInst?>{
156153
if (expr in reachable)
157154
return listOf(expr)

0 commit comments

Comments
 (0)