From 83dddd73b09a9ffffc0ceac8c8c000cbb5a1e623 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Fri, 16 Jul 2021 09:36:14 +0200 Subject: [PATCH] Always add a local variable for its live ranges. There used to be code that extended a previous range instead. However, that does not work as that extension could have the local cover code where it does not exists. Since we no longer extend the range of locals, we should always introduce a new one even if there was another one for a previous range. --- .../coroutines/CoroutineTransformerMethodVisitor.kt | 10 +++------- .../coroutines/debug/thisAndResultInLvt.kt | 2 +- .../codegen/bytecodeText/coroutines/mergeLvt.kt | 2 +- .../coroutines/varValueConflictsWithTableSameSort.kt | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 4998096ce05..fde67d392f2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -136,8 +136,6 @@ class CoroutineTransformerMethodVisitor( UninitializedStoresProcessor(methodNode, shouldPreserveClassInitialization).run() - updateLvtAccordingToLiveness(methodNode, isForNamedFunction) - val spilledToVariableMapping = spillVariables(suspensionPoints, methodNode) val suspendMarkerVarIndex = methodNode.maxLocals++ @@ -194,6 +192,8 @@ class CoroutineTransformerMethodVisitor( dropUnboxInlineClassMarkers(methodNode, suspensionPoints) methodNode.removeEmptyCatchBlocks() + updateLvtAccordingToLiveness(methodNode, isForNamedFunction) + if (languageVersionSettings.isReleaseCoroutines()) { writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping) } @@ -1298,7 +1298,6 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction: method.localVariables.clear() // Skip `this` for suspend lambda val start = if (isForNamedFunction) 0 else 1 - val oldLvtNodeToLatestNewLvtNode = mutableMapOf() for (variableIndex in start until method.maxLocals) { if (oldLvt.none { it.index == variableIndex }) continue var startLabel: LabelNode? = null @@ -1337,10 +1336,7 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction: // startLabel can be null in case of parameters @Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index) - if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) { - method.localVariables.add(node) - } - oldLvtNodeToLatestNewLvtNode[lvtRecord] = node + method.localVariables.add(node) } } } diff --git a/compiler/testData/codegen/bytecodeText/coroutines/debug/thisAndResultInLvt.kt b/compiler/testData/codegen/bytecodeText/coroutines/debug/thisAndResultInLvt.kt index 8d82b4840f7..967f79eda03 100644 --- a/compiler/testData/codegen/bytecodeText/coroutines/debug/thisAndResultInLvt.kt +++ b/compiler/testData/codegen/bytecodeText/coroutines/debug/thisAndResultInLvt.kt @@ -21,7 +21,7 @@ class A { // BEs generate continuation classes differently, JVM_IR generates more correctly // foo, c's lambda and foo's continuation -// 3 LOCALVARIABLE \$result Ljava/lang/Object; +// 8 LOCALVARIABLE \$result Ljava/lang/Object; // foo x 3 since we split the local over restore code for the two calls to block(), and // 4 LOCALVARIABLE this LA; diff --git a/compiler/testData/codegen/bytecodeText/coroutines/mergeLvt.kt b/compiler/testData/codegen/bytecodeText/coroutines/mergeLvt.kt index 71f61f61bb4..4ead75c2b6a 100644 --- a/compiler/testData/codegen/bytecodeText/coroutines/mergeLvt.kt +++ b/compiler/testData/codegen/bytecodeText/coroutines/mergeLvt.kt @@ -22,4 +22,4 @@ class MyBlockingAdapter() { } } -// 1 LOCALVARIABLE \$this\$extensionFun\$iv\$iv LAtomicInt; +// 2 LOCALVARIABLE \$this\$extensionFun\$iv\$iv LAtomicInt; diff --git a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt index 88f3783d8ce..c158d26224e 100644 --- a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt +++ b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt @@ -43,7 +43,7 @@ fun box(): String { // 1 LOCALVARIABLE i Ljava/lang/String; L.* 3 // We merge LVT records for two consequent branches, but we split the local over the restore code. -// 2 LOCALVARIABLE s Ljava/lang/String; L.* 3 +// 3 LOCALVARIABLE s Ljava/lang/String; L.* 3 // 1 PUTFIELD VarValueConflictsWithTableSameSortKt\$box\$1.L\$0 : Ljava/lang/Object; /* 1 load in the catch (e: Throwable) { throw e } block which is implicitly wrapped around try/finally */ // 1 ALOAD 3\s+ATHROW