From 7e943ab757305bb8ad0a9d61060899cd10e4d407 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 23 Aug 2021 13:27:17 +0300 Subject: [PATCH] JVM don't optimize out starting ASTORE of TCB handler --- .../codegen/optimization/temporaryVals/TemporaryVals.kt | 8 ++++++++ .../coroutines/varValueConflictsWithTableSameSort.kt | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt index bb358175814..269e35def71 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt @@ -64,6 +64,14 @@ class TemporaryValsAnalyzer { } } + // Some coroutine transformations require exception handler to start from an ASTORE instruction. + for (tcb in methodNode.tryCatchBlocks) { + val handlerFirstInsn = tcb.handler.next ?: continue + if (handlerFirstInsn.opcode == Opcodes.ASTORE) { + potentiallyTemporaryStores.remove(handlerFirstInsn) + } + } + // If the method is big, and we couldn't eliminate enough temporary variable store candidates, // bail out, treat all variables as non-temporary. // Here we estimate memory required to store all relevant information as O(N * M * K), diff --git a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt index 5a0cfdb5d8b..98890b07764 100644 --- a/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt +++ b/compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTableSameSort.kt @@ -43,6 +43,8 @@ fun box(): String { // 1 LOCALVARIABLE i 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 /* 1 load in result = s */ // 1 ALOAD 3\s+PUTFIELD kotlin/jvm/internal/Ref\$ObjectRef\.element /* 1 load in spill */ @@ -50,7 +52,7 @@ fun box(): String { /* 2 loads in println(s) */ // 2 ALOAD 3\s+INVOKEVIRTUAL java/io/PrintStream.println \(Ljava/lang/Object;\)V /* But no further load when spilling 's' to the continuation */ -// 4 ALOAD 3 +// 5 ALOAD 3 // We merge LVT records for two consequent branches, but we split the local over the restore code. // JVM_IR_TEMPLATES