Extend LVT record of alive variables to end of next suspension point

Otherwise, arguments of suspend call become invisible in async stack
trace
 #KT-44714
This commit is contained in:
Ilmir Usmanov
2021-03-08 18:12:51 +01:00
parent b6bb8a576e
commit e79c9a3618
3 changed files with 16 additions and 16 deletions
@@ -1217,18 +1217,18 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
fun isAlive(insnIndex: Int, variableIndex: Int): Boolean =
liveness[insnIndex].isAlive(variableIndex)
fun nextSuspensionPointLabel(insn: AbstractInsnNode): LabelNode {
fun nextSuspensionPointEndLabel(insn: AbstractInsnNode): LabelNode {
val suspensionPoint =
InsnSequence(insn, method.instructions.last).firstOrNull { isAfterSuspendMarker(it) } ?: method.instructions.last
return suspensionPoint as? LabelNode ?: suspensionPoint.findNextOrNull { it is LabelNode } as LabelNode
}
fun nextSuspensionPointStartLabel(insn: AbstractInsnNode): LabelNode {
val suspensionPoint =
InsnSequence(insn, method.instructions.last).firstOrNull { isBeforeSuspendMarker(it) } ?: method.instructions.last
return suspensionPoint as? LabelNode ?: suspensionPoint.findPreviousOrNull { it is LabelNode } as LabelNode
}
fun previousSuspensionPointLabel(insn: AbstractInsnNode): LabelNode {
val suspensionPoint =
InsnSequence(method.instructions.first, insn).lastOrNull { isAfterSuspendMarker(it) } ?: method.instructions.first
return suspensionPoint as? LabelNode ?: suspensionPoint.findNextOrNull { it is LabelNode } as LabelNode
}
fun min(a: LabelNode, b: LabelNode): LabelNode =
if (method.instructions.indexOf(a) < method.instructions.indexOf(b)) a else b
@@ -1259,7 +1259,7 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
val lvtRecord = oldLvt.findRecord(insnIndex, variableIndex) ?: continue
if (lvtRecord.name == CONTINUATION_VARIABLE_NAME) continue
// Extend lvt record to the next suspension point
val endLabel = min(lvtRecord.end, nextSuspensionPointLabel(insn))
val endLabel = min(lvtRecord.end, nextSuspensionPointEndLabel(insn))
// startLabel can be null in case of parameters
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
// Attempt to extend existing local variable node corresponding to the record in
@@ -1280,7 +1280,6 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
val deadVariables = arrayListOf<Int>()
outer@for (variableIndex in start until method.maxLocals) {
if (oldLvt.none { it.index == variableIndex }) continue
if (oldLvt.none { it.index == variableIndex }) continue
for (insnIndex in 0 until (method.instructions.size() - 1)) {
if (isAlive(insnIndex, variableIndex)) continue@outer
@@ -1312,7 +1311,7 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
variable.desc,
variable.signature,
variable.start,
nextSuspensionPointLabel(variable.start),
nextSuspensionPointStartLabel(variable.start),
variable.index
)
)
@@ -14,12 +14,13 @@ fun main(args: Array<String>) {
@BuilderInference
suspend fun SequenceScope<Int>.awaitSeq(): Int = 42
// 1 LOCALVARIABLE a I L[0-9]+ L19
/* TODO: JVM_IR does not generate LINENUMBER at the end of the lambda */
// JVM_TEMPLATES
// 1 LINENUMBER 9 L19
// JVM_IR_TEMPLATES
// 1 LOCALVARIABLE a I L[0-9]+ L4
// JVM_TEMPLATES
// 1 LOCALVARIABLE a I L[0-9]+ L19
// TODO: Old BE generates LINENUMBER label after suspension point, unlike JVM_BE
// IGNORE_BACKEND_FIR: JVM_IR
@@ -4,7 +4,7 @@ Connected to the target VM
suspendMain.kt:15
Thread stack trace:
CoroutinePreflightFrame invokeSuspend:!LINE_NUMBER!, SuspendMainKt$main$2 (continuation)
($result, this)
($result, $this$coroutineScope, this)
CoroutineInfo: -1 coroutine UNKNOWN
CoroutineStackFrame startUndispatchedOrReturn:!LINE_NUMBER!, UndispatchedKt (kotlinx.coroutines.intrinsics)
($i$a$-undispatchedResult-UndispatchedKt$startUndispatchedOrReturn$2, $i$f$undispatchedResult, $this$startUndispatchedOrReturn, $this$undispatchedResult$iv, block, receiver)