Skip to content

Commit e930e6c

Browse files
authored
Avoid calling JcClass.methods in instrumentation (#227)
* Extract `TraceDeserializer` from `RdProcessRunner` * Avoid calling `JcClass.methods` in instrumentation
1 parent 24a7df7 commit e930e6c

File tree

3 files changed

+36
-26
lines changed

3 files changed

+36
-26
lines changed

usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/executor/RdProcessRunner.kt

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ import com.jetbrains.rd.util.lifetime.LifetimeDefinition
77
import com.jetbrains.rd.util.threading.SingleThreadScheduler
88
import com.jetbrains.rd.util.threading.SynchronousScheduler
99
import kotlinx.coroutines.delay
10-
import org.jacodb.api.jvm.JcClassOrInterface
1110
import org.jacodb.api.jvm.JcClasspath
1211
import org.jacodb.api.jvm.cfg.JcInst
13-
import org.jacodb.api.jvm.ext.methods
1412
import org.usvm.instrumentation.generated.models.*
1513
import org.usvm.instrumentation.rd.*
1614
import org.usvm.instrumentation.util.findFieldByFullNameOrNull
@@ -22,7 +20,6 @@ import org.usvm.instrumentation.testcase.api.*
2220
import org.usvm.instrumentation.testcase.descriptor.UTestExceptionDescriptor
2321
import java.util.concurrent.CompletableFuture
2422
import java.util.concurrent.TimeUnit
25-
import kotlin.math.pow
2623
import kotlin.time.Duration
2724
import kotlin.time.Duration.Companion.milliseconds
2825
import kotlin.time.Duration.Companion.seconds
@@ -38,8 +35,7 @@ class RdProcessRunner(
3835
private val serializationContext = SerializationContext(jcClasspath)
3936
private val scheduler = SingleThreadScheduler(lifetime, "usvm-executor-scheduler")
4037
private val coroutineScope = UsvmRdCoroutineScope(lifetime, scheduler)
41-
private val deserializedInstructionsCache = HashMap<Long, JcInst>()
42-
private val deserializedClassesCache = HashMap<Long, JcClassOrInterface>()
38+
private val traceDeserializer = TraceDeserializer(jcClasspath)
4339
lateinit var rdProcess: RdServerProcess
4440

4541

@@ -186,25 +182,7 @@ class RdProcessRunner(
186182
}
187183

188184
private fun deserializeTrace(trace: List<Long>, coveredClasses: List<ClassToId>): List<JcInst> =
189-
trace.map { encodedInst ->
190-
deserializedInstructionsCache.getOrPut(encodedInst) {
191-
val classIdOffset = (2.0.pow(Byte.SIZE_BITS * 3).toLong() - 1) shl (Byte.SIZE_BITS * 5 - 1)
192-
val classId = encodedInst and classIdOffset shr (Byte.SIZE_BITS * 5)
193-
val methodIdOffset = (2.0.pow(Byte.SIZE_BITS * 2).toLong() - 1) shl (Byte.SIZE_BITS * 3 - 1)
194-
val methodId = encodedInst and methodIdOffset shr (Byte.SIZE_BITS * 3)
195-
val instructionId = (encodedInst and (2.0.pow(Byte.SIZE_BITS * 3).toLong() - 1)).toInt()
196-
val jcClass =
197-
deserializedClassesCache.getOrPut(classId) {
198-
val className = coveredClasses.find { it.classId == classId }
199-
?: error("Deserialization error")
200-
jcClasspath.findClassOrNull(className.className) ?: error("Deserialization error")
201-
}
202-
val jcMethod = jcClass.methods.sortedBy { it.description }[methodId.toInt()]
203-
jcMethod.instList
204-
.find { it.location.index == instructionId }
205-
?: error("Deserialization error")
206-
}
207-
}
185+
traceDeserializer.deserializeTrace(trace, coveredClasses)
208186

209187
fun destroy() {
210188
lifetime.terminate()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.usvm.instrumentation.executor
2+
3+
import org.jacodb.api.jvm.JcClassOrInterface
4+
import org.jacodb.api.jvm.JcClasspath
5+
import org.jacodb.api.jvm.cfg.JcInst
6+
import org.usvm.instrumentation.generated.models.ClassToId
7+
import kotlin.math.pow
8+
9+
class TraceDeserializer(private val jcClasspath: JcClasspath) {
10+
private val deserializedInstructionsCache = HashMap<Long, JcInst>()
11+
private val deserializedClassesCache = HashMap<Long, JcClassOrInterface>()
12+
13+
fun deserializeTrace(trace: List<Long>, coveredClasses: List<ClassToId>): List<JcInst> =
14+
trace.map { encodedInst ->
15+
deserializedInstructionsCache.getOrPut(encodedInst) {
16+
val classIdOffset = (2.0.pow(Byte.SIZE_BITS * 3).toLong() - 1) shl (Byte.SIZE_BITS * 5 - 1)
17+
val classId = encodedInst and classIdOffset shr (Byte.SIZE_BITS * 5)
18+
val methodIdOffset = (2.0.pow(Byte.SIZE_BITS * 2).toLong() - 1) shl (Byte.SIZE_BITS * 3 - 1)
19+
val methodId = encodedInst and methodIdOffset shr (Byte.SIZE_BITS * 3)
20+
val instructionId = (encodedInst and (2.0.pow(Byte.SIZE_BITS * 3).toLong() - 1)).toInt()
21+
val jcClass =
22+
deserializedClassesCache.getOrPut(classId) {
23+
val className = coveredClasses.find { it.classId == classId }
24+
?: error("Deserialization error")
25+
jcClasspath.findClassOrNull(className.className) ?: error("Deserialization error")
26+
}
27+
val jcMethod = jcClass.declaredMethods.sortedBy { it.description }[methodId.toInt()]
28+
jcMethod.instList
29+
.find { it.location.index == instructionId }
30+
?: error("Deserialization error")
31+
}
32+
}
33+
}

usvm-jvm-instrumentation/src/main/kotlin/org/usvm/instrumentation/instrumentation/JcInstructionTracer.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import org.jacodb.api.jvm.JcField
66
import org.jacodb.api.jvm.JcMethod
77
import org.jacodb.api.jvm.cfg.JcInst
88
import org.jacodb.api.jvm.cfg.JcRawFieldRef
9-
import org.jacodb.api.jvm.ext.methods
109
import org.usvm.instrumentation.collector.trace.TraceCollector
1110
import org.usvm.instrumentation.instrumentation.JcInstructionTracer.StaticFieldAccessType
1211
import org.usvm.instrumentation.util.enclosingClass
@@ -75,7 +74,7 @@ object JcInstructionTracer : Tracer<Trace> {
7574

7675
private fun encodeMethod(jcClass: JcClassOrInterface, jcMethod: JcMethod): EncodedMethod {
7776
val encodedClass = encodeClass(jcClass)
78-
val methodIndex = jcClass.methods
77+
val methodIndex = jcClass.declaredMethods
7978
.sortedBy { it.description }
8079
.indexOf(jcMethod)
8180
.also { if (it == -1) error("Encoding error") }

0 commit comments

Comments
 (0)