in jvm-agent/src/main/org/jetbrains/lincheck/jvm/agent/TransformationProfile.kt [284:338]
override fun getMethodConfiguration(className: String, methodName: String, descriptor: String): TransformationConfiguration {
val config = TransformationConfiguration()
// NOTE: `shouldWrapInIgnoredSection` should be before `shouldNotInstrument`,
// otherwise we may incorrectly forget to add some ignored sections
// and start tracking events in unexpected places
if (shouldWrapInIgnoredSection(className, methodName, descriptor)) {
return config.apply {
wrapInIgnoredSection = true
}
}
if (shouldNotInstrument(className, methodName, descriptor)) {
return config
}
// For `java.lang.Thread` class (and `ThreadContainer.start()` method),
// we only apply `ThreadTransformer` and skip all other transformations
if (isThreadClass(className) || isThreadContainerThreadStartMethod(className, methodName)) {
return config.apply {
trackAllThreadsOperations = true
}
}
// In trace debugger mode we record hash codes of tracked objects and substitute them on re-run.
// To intercept all hash codes, we need to use `DeterministicInvokeDynamicTransformer` transformer,
// to properly track events inside various primitives that use `invokedynamic`,
// such as string templates or lambda expressions.
config.interceptInvokeDynamic = true
// Debugger implicitly evaluates `toString()` for variables rendering.
// We need to ensure there are no `beforeEvents` calls inside `toString()`
// to ensure the event numeration will remain the same.
if (ideaPluginEnabled && isToStringMethod(methodName, descriptor)) {
return config.apply {
trackObjectCreations = true
}
}
return config.apply {
trackObjectCreations = true
trackLocalVariableWrites = true
trackAllSharedMemoryAccesses = true
trackMethodCalls = true
trackInlineMethodCalls = true
interceptMethodCallResults = true
trackAllThreadsOperations = true
trackAllSynchronizationOperations = true
trackCoroutineSuspensions = true
interceptCoroutineDelays = true
}
}