Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor
  • Loading branch information
egiptipavel committed Aug 3, 2023
commit 0c5cfd662c834869a804bf57d28f3dd01380d0fa
2 changes: 1 addition & 1 deletion utbot-instrumentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ dependencies {

implementation("org.ow2.asm:asm:$asmVersion")
implementation("org.ow2.asm:asm-commons:$asmVersion")
implementation("org.ow2.asm:asm-util:$asmVersion")
implementation("org.ow2.asm:asm-util:$asmVersion") // TODO: remove
implementation("io.github.microutils:kotlin-logging:$kotlinLoggingVersion")

implementation("com.jetbrains.rd:rd-framework:$rdVersion")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package org.jacoco.core.internal.instr

import org.jacoco.core.internal.flow.ClassProbesAdapter
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.util.TraceClassVisitor
import org.utbot.instrumentation.Settings
import java.io.PrintWriter
import java.io.StringWriter

val sw: StringWriter = StringWriter()

fun createJacocoClassVisitorForCollectionBranchCoverage(writer: ClassWriter): ClassVisitor {
fun createJacocoClassVisitorForCollectionBranchCoverage(writer: ClassWriter): MyMethodToProbesVisitor {
val strategy = NoneProbeArrayStrategy()
val tcv = TraceClassVisitor(writer, PrintWriter(sw))
return ClassProbesAdapter(
MyClassInstrumenter(strategy, tcv),
true
)
return MyMethodToProbesVisitor(Settings.ASM_API, strategy, tcv)
}

fun createJacocoClassVisitorForBytecodeInstrumentation(writer: ClassWriter, className: String): ClassVisitor {
fun createJacocoClassVisitorForBytecodeInstrumentation(writer: ClassWriter, className: String): ClassProbesAdapter {
val strategy = MyClassFieldProbeArrayStrategy(className)
val tcv = TraceClassVisitor(writer, PrintWriter(sw))
return ClassProbesAdapter(
ClassInstrumenter(strategy, tcv),
ClassInstrumenter(strategy, writer),
true
)
}
Original file line number Diff line number Diff line change
@@ -1,93 +1,19 @@
package org.jacoco.core.internal.instr

import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.Label
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.utbot.instrumentation.Settings

/**
* Inspired by [org.jacoco.core.internal.instr.ClassFieldProbeArrayStrategy]
*/
class MyClassFieldProbeArrayStrategy(private val className: String) : IProbeArrayStrategy {

private val FRAME_STACK_EMPTY = arrayOf<Any>(0)

private val FRAME_LOCALS_EMPTY = arrayOfNulls<Any>(0)

override fun storeInstance(mv: MethodVisitor, clinit: Boolean, variable: Int): Int {
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
className,
// TODO change method name
InstrSupport.INITMETHOD_NAME,
InstrSupport.INITMETHOD_DESC,
false
)
mv.visitFieldInsn(Opcodes.GETSTATIC, className, Settings.PROBES_ARRAY_NAME, Settings.PROBES_ARRAY_DESC)
mv.visitVarInsn(Opcodes.ASTORE, variable)
return 1
}

override fun addMembers(cv: ClassVisitor, probeCount: Int) {
createDataField(cv)
createInitMethod(cv, probeCount)
}

private fun createDataField(cv: ClassVisitor) {
cv.visitField(
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC,
Settings.PROBES_ARRAY_NAME,
Settings.PROBES_ARRAY_DESC,
null,
null
)
}

private fun createInitMethod(cv: ClassVisitor, probeCount: Int) {
val mv = cv.visitMethod(
InstrSupport.INITMETHOD_ACC,
// TODO change method name
InstrSupport.INITMETHOD_NAME,
InstrSupport.INITMETHOD_DESC,
null,
null
)

mv.visitCode()
mv.visitFieldInsn(
Opcodes.GETSTATIC,
className,
Settings.PROBES_ARRAY_NAME,
Settings.PROBES_ARRAY_DESC
)
val alreadyInitialized = Label()
mv.visitJumpInsn(Opcodes.IFNONNULL, alreadyInitialized)
mv.visitIntInsn(Opcodes.BIPUSH, probeCount)
mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BOOLEAN)
mv.visitFieldInsn(
Opcodes.PUTSTATIC,
className,
Settings.PROBES_ARRAY_NAME,
Settings.PROBES_ARRAY_DESC
)
mv.visitFrame(
Opcodes.F_NEW,
0,
FRAME_LOCALS_EMPTY,
0,
FRAME_STACK_EMPTY
)
mv.visitLabel(alreadyInitialized)
mv.visitFieldInsn(
Opcodes.GETSTATIC,
className,
Settings.PROBES_ARRAY_NAME,
Settings.PROBES_ARRAY_DESC
)
mv.visitInsn(Opcodes.ARETURN)

mv.visitMaxs(1, 0)
mv.visitEnd()
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.jacoco.core.internal.instr

import org.jacoco.core.internal.flow.ClassProbesAdapter
import org.objectweb.asm.ClassVisitor

class MyMethodToProbesVisitor(
api: Int,
strategy: IProbeArrayStrategy,
writer: ClassVisitor,
val methodToProbes: MutableMap<String, MutableList<Int>> = mutableMapOf()
) : ClassVisitor(
api,
ClassProbesAdapter(
NoneClassInstrumenter(strategy, writer, methodToProbes),
true
)
)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package org.jacoco.core.internal.instr
import org.jacoco.core.internal.flow.MethodProbesVisitor
import org.objectweb.asm.ClassVisitor

class MyClassInstrumenter(
class NoneClassInstrumenter(
probeArrayStrategy: IProbeArrayStrategy,
cv: ClassVisitor
cv: ClassVisitor,
private val methodToProbes: MutableMap<String, MutableList<Int>>,
) : ClassInstrumenter(probeArrayStrategy, cv) {

override fun visitMethod(
Expand All @@ -18,8 +19,8 @@ class MyClassInstrumenter(
val mv = cv.visitMethod(access, name, desc, signature, exceptions)

val frameEliminator = DuplicateFrameEliminator(mv)
val probeVariableInserter = MyProbeInserter(name, frameEliminator)
return MyMethodInstrumenter(probeVariableInserter, probeVariableInserter)
val probeVariableInserter = NoneProbeInserter(name, methodToProbes, frameEliminator)
return MethodInstrumenter(probeVariableInserter, probeVariableInserter)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jacoco.core.internal.instr

import org.objectweb.asm.MethodVisitor
import org.utbot.instrumentation.Settings

/**
* The probe inserter does not emit any code at all. This is used to collect method probes.
*/
class NoneProbeInserter(
private val methodName: String,
private val methodToProbes: MutableMap<String, MutableList<Int>>,
mv: MethodVisitor,
) : IProbeInserter, MethodVisitor(Settings.ASM_API, mv) {

override fun insertProbe(id: Int) {
methodToProbes.getOrPut(methodName) { mutableListOf() }.add(id)
}

}
Loading