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:
Ilmir Usmanov
2021-08-22 07:51:24 +02:00
committed by Space
parent 92e94a4068
commit c01c356817
10 changed files with 68 additions and 29 deletions
@@ -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) {
@@ -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"
}
@@ -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 {
@@ -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 {
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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");