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.
This commit is contained in:
+2
-29
@@ -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<ArgContext>,
|
||||
val calls: List<CallContext>,
|
||||
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) {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// FULL_JDK
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: WASM
|
||||
|
||||
interface Foo {
|
||||
val foos: List<Foo>
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> Sequence<*>.firstIsInstanceOrNull(): T? {
|
||||
for (element in this) if (element is T) return element
|
||||
return null
|
||||
}
|
||||
|
||||
fun faultyLvt() {
|
||||
sequenceOf<Foo>().firstIsInstanceOrNull<Foo>()?.foos.orEmpty()
|
||||
|
||||
listOf<Foo>().map { it }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
faultyLvt()
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user