in trace-recorder/src/main/org/jetbrains/lincheck/trace/recorder/TraceCollectingEventTracker.kt [606:654]
override fun onMethodCallReturn(
threadDescriptor: ThreadDescriptor,
methodId: Int,
receiver: Any?,
params: Array<Any?>,
result: Any?,
interceptor: ResultInterceptor?,
): Unit = threadDescriptor.runInsideInjectedCode {
val threadData = threadDescriptor.eventTrackerData as? ThreadData? ?: return
val thread = Thread.currentThread()
val methodDescriptor = context.getMethodDescriptor(methodId)
val methodSection = methodAnalysisSectionType(receiver, methodDescriptor.className, methodDescriptor.methodName)
if (methodSection == AnalysisSectionType.IGNORED) {
threadData.leaveAnalysisSection(methodSection)
return
}
// TODO: what about inline method calls? Inside them also could be loops.
// The inline methods should be closed after closing the loops inside them.
// close all existing loops
while (threadData.currentLoopTracePoint() != null) {
exitCurrentLoop(thread, threadData)
}
while (threadData.isCurrentMethodCallInline()) {
val inlineTracePoint = threadData.currentMethodCallTracePoint()!!
Logger.error {
"Forced exit from inline method ${inlineTracePoint.methodId} " +
"${inlineTracePoint.className}.${inlineTracePoint.methodName}" +
" due to return from method $methodId " +
"${methodDescriptor.className}.${methodDescriptor.methodName}"
}
onInlineMethodCallReturn(threadDescriptor, inlineTracePoint.methodId)
}
val tracePoint = threadData.popStackFrame()
if (tracePoint.methodId != methodId) {
Logger.error {
"Return from method $methodId ${methodDescriptor.className}.${methodDescriptor.methodName} " +
"but on stack ${tracePoint.methodId} ${tracePoint.className}.${tracePoint.methodName}"
}
}
tracePoint.result = TRObjectOrVoid(context, result)
strategy.completeContainerTracePoint(thread, tracePoint)
threadData.leaveAnalysisSection(methodSection)
}