From c01c3568178b177909fcd1914a3bf8793a8e040f Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Sun, 22 Aug 2021 07:51:24 +0200 Subject: [PATCH] Do not extend LVT ranges during inplace arguments inlining Otherwise, R8 does not transform kotlin-reflect, failing bootstrap. Leaving end label the same is safe, since we do not remove labels during transformation. --- .../InplaceArgumentsMethodTransformer.kt | 31 ++----------------- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++ .../box/inlineArgsInPlace/kotlinReflect.kt | 23 ++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++ .../IrJsCodegenBoxTestGenerated.java | 5 +++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++ 10 files changed, 68 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt index c2d3a00c74c..b8fd0bf4318 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables import org.jetbrains.kotlin.codegen.optimization.common.updateMaxStack import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer -import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.tree.* @@ -25,7 +24,6 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { collectSuspensionPoints(methodContext) transformMethod(methodContext) - updateLvtEntriesForMovedInstructions(methodContext) methodNode.removeUnusedLocalVariables() methodNode.updateMaxStack() @@ -48,7 +46,6 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { val callEndMarker: AbstractInsnNode, val args: List, val calls: List, - val endLabel: LabelNode ) private class ArgContext( @@ -95,19 +92,8 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { when { insn.isInplaceCallStartMarker() -> calls.add(parseCall(methodNode, insn, iter)) - insn.isInplaceCallEndMarker() -> { - val previous = insn.previous - val endLabel = - if (previous.type == AbstractInsnNode.LABEL) - previous as LabelNode - else - LabelNode(Label()).also { - // Make sure each call with inplace arguments has an endLabel - // (we need it to update LVT after transformation). - methodNode.instructions.insertBefore(insn, it) - } - return CallContext(start, insn, args, calls, endLabel) - } + insn.isInplaceCallEndMarker() -> + return CallContext(start, insn, args, calls) insn.isInplaceArgumentStartMarker() -> args.add(parseArg(methodNode, insn, iter)) insn.isInplaceArgumentEndMarker() -> @@ -354,19 +340,6 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { insnList.remove(callContext.callEndMarker) } - private fun updateLvtEntriesForMovedInstructions(methodContext: MethodContext) { - val insnList = methodContext.methodNode.instructions - for ((insn, callContext) in methodContext.varInstructionMoved.entries) { - // Extend local variable interval to call end label if needed - val lv = methodContext.lvtEntryForInstruction[insn] ?: continue - val lvEndIndex = insnList.indexOf(lv.end) - val endLabelIndex = insnList.indexOf(callContext.endLabel) - if (endLabelIndex > lvEndIndex) { - lv.end = callContext.endLabel - } - } - } - private fun stripMarkers(methodNode: MethodNode) { var insn = methodNode.instructions.first while (insn != null) { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index b02a2a2fd93..9d66ea64a65 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -18270,6 +18270,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @Test + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @Test @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { diff --git a/compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt b/compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt new file mode 100644 index 00000000000..ef0ab7b700f --- /dev/null +++ b/compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt @@ -0,0 +1,23 @@ +// FULL_JDK +// WITH_RUNTIME +// IGNORE_BACKEND: WASM + +interface Foo { + val foos: List +} + +inline fun Sequence<*>.firstIsInstanceOrNull(): T? { + for (element in this) if (element is T) return element + return null +} + +fun faultyLvt() { + sequenceOf().firstIsInstanceOrNull()?.foos.orEmpty() + + listOf().map { it } +} + +fun box(): String { + faultyLvt() + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index d721fbd2d59..847659d0cb3 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -18126,6 +18126,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @Test + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @Test @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 7d067df7456..f087b7d302d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -18270,6 +18270,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @Test + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @Test @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 9b524303546..c453f7b412c 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15024,6 +15024,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index e2ea92f5efb..29d595f6e45 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -13098,6 +13098,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 9c8ad21de8a..53664e72bdb 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -12504,6 +12504,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 7e9ddd52ae7..b963e8722fd 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -12569,6 +12569,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index c643c63f45e..385b9263adb 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -6659,6 +6659,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineArgsInPlace/inlineCircularDedepency.kt"); } + @TestMetadata("kotlinReflect.kt") + public void testKotlinReflect() throws Exception { + runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt"); + } + @TestMetadata("mapSet.kt") public void testMapSet() throws Exception { runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");