From 717e087fd92c198250b43f0b9f941d26426a8113 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Tue, 8 Dec 2020 15:56:05 +0100 Subject: [PATCH] [JVM] Do not collaps unrelated locals in state machine transform. --- .../CoroutineTransformerMethodVisitor.kt | 28 ++++++------------- .../inlineLocalsStateMachineTransform.kt | 8 +++--- .../suspend/localsStateMachineTransform.kt | 8 +++--- 3 files changed, 17 insertions(+), 27 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 d43f9884a96..2099d5c044f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.codegen.coroutines -import com.sun.org.apache.bcel.internal.generic.StoreInstruction import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.optimization.common.* @@ -1223,8 +1222,9 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction: oldLvt += record } method.localVariables.clear() - // Skip `this` for suspend lamdba + // 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 @@ -1240,25 +1240,15 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction: val endLabel = insn as? LabelNode ?: insn.findNextOrNull { it is LabelNode } as? LabelNode ?: continue // startLabel can be null in case of parameters @Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start - var recordToExtend: LocalVariableNode? = null - for (record in method.localVariables) { - if (record.name == lvtRecord.name && - record.desc == lvtRecord.desc && - record.signature == lvtRecord.signature && - record.index == lvtRecord.index - ) { - if (InsnSequence(record.end, startLabel).none { isBeforeSuspendMarker(it) }) { - recordToExtend = record - break - } - } - } - if (recordToExtend != null) { + // Attempt to extend existing local variable node corresponding to the record in + // the original local variable table. + var recordToExtend: LocalVariableNode? = oldLvtNodeToLatestNewLvtNode[lvtRecord] + if (recordToExtend != null && InsnSequence(recordToExtend.end, startLabel).none { isBeforeSuspendMarker(it) }) { recordToExtend.end = endLabel } else { - method.localVariables.add( - LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index) - ) + val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index) + method.localVariables.add(node) + oldLvtNodeToLatestNewLvtNode[lvtRecord] = node } } } diff --git a/compiler/testData/debug/localVariables/suspend/inlineLocalsStateMachineTransform.kt b/compiler/testData/debug/localVariables/suspend/inlineLocalsStateMachineTransform.kt index d29c27117cf..602172aa480 100644 --- a/compiler/testData/debug/localVariables/suspend/inlineLocalsStateMachineTransform.kt +++ b/compiler/testData/debug/localVariables/suspend/inlineLocalsStateMachineTransform.kt @@ -36,8 +36,8 @@ suspend fun box() { // test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null // test.kt:4 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$hasLocal:int=0:int // test.kt:5 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$hasLocal:int=0:int, x$iv:int=41:int -// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x$iv:int=41:int -// test.kt:18 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x$iv:int=41:int -// test.kt:4 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x$iv:int=41:int, $i$f$hasLocal:int=0:int -// test.kt:5 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x$iv:int=41:int, $i$f$hasLocal:int=0:int +// test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:18 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:4 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$hasLocal:int=0:int +// test.kt:5 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, $i$f$hasLocal:int=0:int, x$iv:int=41:int // test.kt:19 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null diff --git a/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt b/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt index 1048cc68a54..0ae1b1c2f09 100644 --- a/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt +++ b/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt @@ -32,13 +32,13 @@ suspend fun box() { // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:5 f: x:int=0:int // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int -// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int +// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int // test.kt:5 f: x:int=1:int // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int -// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int -// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int -// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int +// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:5 f: x:int=0:int // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int