diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index d9392f96029..5fcf0800390 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -389,7 +389,7 @@ internal class StackLocalsManagerImpl( internal class FunctionGenerationContext(val function: LLVMValueRef, val codegen: CodeGenerator, - startLocation: LocationInfo?, + private val startLocation: LocationInfo?, private val endLocation: LocationInfo?, private val switchToRunnable: Boolean, internal val irFunction: IrFunction? = null): ContextUtils { @@ -1333,14 +1333,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, returnSlot = LLVMGetParam(function, numParameters(function.type) - 1) } - if (context.memoryModel == MemoryModel.EXPERIMENTAL && switchToRunnable) { - check(!forbidRuntime) { "Attempt to switch the thread state when runtime is forbidden" } - positionAtEnd(prologueBb) - // TODO: Do we need to do it for every c->kotlin bridge? - call(context.llvm.initRuntimeIfNeeded, emptyList()) - switchThreadState(Runnable) - } - positionAtEnd(localsInitBb) slotsPhi = phi(kObjHeaderPtrPtr) // Is removed by DCE trivially, if not needed. @@ -1351,10 +1343,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, internal fun epilogue() { appendingTo(prologueBb) { - if (needsRuntimeInit && context.config.memoryModel != MemoryModel.EXPERIMENTAL) { - check(!forbidRuntime) { "Attempt to init runtime where runtime usage is forbidden" } - call(context.llvm.initRuntimeIfNeeded, emptyList()) - } val slots = if (needSlotsPhi) LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!! else @@ -1364,7 +1352,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, // Zero-init slots. val slotsMem = bitcast(kInt8Ptr, slots) memset(slotsMem, 0, slotCount * codegen.runtime.pointerSize) - call(context.llvm.enterFrameFunction, listOf(slots, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) } addPhiIncoming(slotsPhi!!, prologueBb to slots) memScoped { @@ -1388,7 +1375,26 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, br(stackLocalsInitBb) } + appendingTo(stackLocalsInitBb) { + /** + * Function calls need to have !dbg, otherwise llvm rejects full module debug information + * On the other hand, we don't want prologue to have debug info, because it can lead to debugger stops in + * places with inconsistent stack layout. So we setup debug info only for this part of bb. + */ + startLocation?.let { debugLocation(it, it) } + val needStateSwitch = context.memoryModel == MemoryModel.EXPERIMENTAL && switchToRunnable + if (needsRuntimeInit || needStateSwitch) { + check(!forbidRuntime) { "Attempt to init runtime where runtime usage is forbidden" } + call(context.llvm.initRuntimeIfNeeded, emptyList()) + } + if (needStateSwitch) { + switchThreadState(Runnable) + } + if (needSlots) { + call(context.llvm.enterFrameFunction, listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) + } + resetDebugLocation() br(entryBb) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index fb670e07ea1..6d62568240d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -1870,10 +1870,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map b 1 - Breakpoint 1: where = kt47198.kexe`kfun:#foo(kotlin.Int){} [..] at kt47198.kt:1:29, [..] + Breakpoint 1: where = kt47198.kexe`kfun:#foo(kotlin.Int){} [..] at kt47198.kt:1:1, [..] > ${lldbCommandRunOrContinue()} > fr v (int) a = 33 @@ -364,7 +364,7 @@ class LldbTests { val binary = arrayOf(kt47198).binary("kt47198", "-g") """ > b 1 - Breakpoint 1: where = kt47198.kexe`kfun:#foo(kotlin.Int){} [..] at kt47198.kt:2:[..] + Breakpoint 1: where = kt47198.kexe`kfun:#foo(kotlin.Int){} [..] at kt47198.kt:1:[..] > ${lldbCommandRunOrContinue()} > fr v (int) a = 33