Fix linenumbers written to debug metadata

#KT-26848 Fixed
This commit is contained in:
Ilmir Usmanov
2018-09-18 16:26:59 +03:00
parent c0f4933356
commit 5dea245a37
5 changed files with 88 additions and 12 deletions
@@ -129,12 +129,17 @@ class CoroutineTransformerMethodVisitor(
val suspendMarkerVarIndex = methodNode.maxLocals++
val suspensionPointLabels = suspensionPoints.withIndex().map {
val suspensionPointLineNumbers =
suspensionPoints.map { suspensionPoint ->
suspensionPoint.suspensionCallBegin.findPreviousOrNull { it is LineNumberNode } as LineNumberNode?
}
val continuationLabels = suspensionPoints.withIndex().map {
transformCallAndReturnContinuationLabel(it.index + 1, it.value, methodNode, suspendMarkerVarIndex)
}
val tableSwitchLabel = LabelNode()
methodNode.instructions.apply {
val tableSwitchLabel = LabelNode()
val firstStateLabel = LabelNode()
val defaultLabel = LabelNode()
@@ -153,7 +158,7 @@ class CoroutineTransformerMethodVisitor(
0,
suspensionPoints.size,
defaultLabel,
firstStateLabel, *suspensionPointLabels.toTypedArray()
firstStateLabel, *continuationLabels.toTypedArray()
),
firstStateLabel
)
@@ -182,11 +187,7 @@ class CoroutineTransformerMethodVisitor(
fixLvtForParameters(methodNode, startLabel, endLabel)
if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) {
val suspensionPointLabelNodes = listOf(tableSwitchLabel) + suspensionPointLabels.map {
it.label.info.safeAs<LabelNode>()
.sure { "suspensionPointLabel shall have valid info. Check state-machine generation." }
}
writeDebugMetadata(methodNode, suspensionPointLabelNodes, spilledToVariableMapping)
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
}
}
@@ -217,12 +218,10 @@ class CoroutineTransformerMethodVisitor(
private fun writeDebugMetadata(
methodNode: MethodNode,
suspensionPointLabels: List<LabelNode>,
suspensionPointLineNumbers: List<LineNumberNode?>,
spilledToLocalMapping: List<List<SpilledVariableDescriptor>>
) {
val lines = suspensionPointLabels.map { label ->
label.safeAs<AbstractInsnNode>()?.findNextOrNull { it is LineNumberNode }.safeAs<LineNumberNode>()?.line ?: -1
}
val lines = suspensionPointLineNumbers.map { it?.line ?: -1 }
val metadata = classBuilderForCoroutineState.newAnnotation(DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor, true)
metadata.visit(COROUTINES_METADATA_SOURCE_FILE_JVM_NAME, sourceFile)
metadata.visit(COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME, lines.toIntArray())
@@ -0,0 +1,62 @@
// !LANGUAGE: +ReleaseCoroutines
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FULL_JDK
// WITH_COROUTINES
import helpers.*
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
suspend fun foo() {
/*
A
LOT
OF
EMPTY
LINES
*/
suspendHere()
suspendHere()
}
val lambda: suspend () -> Unit = {
/*
A
LOT
OF
EMPTY
LINES
*/
suspendHere()
suspendHere()
}
var continuation: Continuation<Unit>? = null
suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn<Unit> {
continuation = it
COROUTINE_SUSPENDED
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
builder {
foo()
}
if (!"$continuation".contains("21")) return "$continuation"
continuation!!.resumeWith(Result.success(Unit))
if (!"$continuation".contains("22")) return "$continuation"
builder {
lambda()
}
if (!"$continuation".contains("33")) return "$continuation"
continuation!!.resumeWith(Result.success(Unit))
if (!"$continuation".contains("34")) return "$continuation"
return "OK"
}
@@ -6461,6 +6461,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
}
@TestMetadata("firstSuspensionPoint.kt")
public void testFirstSuspensionPoint() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
}
@TestMetadata("runtimeDebugMetadata.kt")
public void testRuntimeDebugMetadata() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
@@ -6461,6 +6461,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
}
@TestMetadata("firstSuspensionPoint.kt")
public void testFirstSuspensionPoint() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
}
@TestMetadata("runtimeDebugMetadata.kt")
public void testRuntimeDebugMetadata() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
@@ -6461,6 +6461,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
}
@TestMetadata("firstSuspensionPoint.kt")
public void testFirstSuspensionPoint() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
}
@TestMetadata("runtimeDebugMetadata.kt")
public void testRuntimeDebugMetadata() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");