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.
This commit is contained in:
+3
-7
@@ -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<LocalVariableNode, LocalVariableNode>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 <init>
|
||||
// 4 LOCALVARIABLE this LA;
|
||||
|
||||
@@ -22,4 +22,4 @@ class MyBlockingAdapter() {
|
||||
}
|
||||
}
|
||||
|
||||
// 1 LOCALVARIABLE \$this\$extensionFun\$iv\$iv LAtomicInt;
|
||||
// 2 LOCALVARIABLE \$this\$extensionFun\$iv\$iv LAtomicInt;
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user