Update maxStack on synthetic instruction insertion
#KT-19723 Fixed
This commit is contained in:
+22
-8
@@ -44,13 +44,14 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
private var changes = false
|
private var changes = false
|
||||||
|
|
||||||
fun run(): Boolean {
|
fun run(): Boolean {
|
||||||
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode()
|
val stackOnThrowExceptions = hashMapOf<AbstractInsnNode, Int>()
|
||||||
eliminateRedundantChecks(checkedReferenceTypes)
|
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode(stackOnThrowExceptions)
|
||||||
|
eliminateRedundantChecks(checkedReferenceTypes, stackOnThrowExceptions)
|
||||||
|
|
||||||
return changes
|
return changes
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyzeTypesAndRemoveDeadCode(): Map<AbstractInsnNode, Type> {
|
private fun analyzeTypesAndRemoveDeadCode(stackOnThrowExceptionsHolder: MutableMap<AbstractInsnNode, Int>): Map<AbstractInsnNode, Type> {
|
||||||
val insns = methodNode.instructions.toArray()
|
val insns = methodNode.instructions.toArray()
|
||||||
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
||||||
|
|
||||||
@@ -64,6 +65,9 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
else if (insn.isCheckParameterIsNotNull() || insn.isCheckExpressionValueIsNotNull()) {
|
else if (insn.isCheckParameterIsNotNull() || insn.isCheckExpressionValueIsNotNull()) {
|
||||||
checkedReferenceTypes[insn] = frame?.peek(1)?.type ?: continue
|
checkedReferenceTypes[insn] = frame?.peek(1)?.type ?: continue
|
||||||
}
|
}
|
||||||
|
else if (insn.isThrowNpeIntrinsic()) {
|
||||||
|
stackOnThrowExceptionsHolder[insn] = frame?.maxStackSize ?: continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val dceResult = DeadCodeEliminationMethodTransformer().removeDeadCodeByFrames(methodNode, frames)
|
val dceResult = DeadCodeEliminationMethodTransformer().removeDeadCodeByFrames(methodNode, frames)
|
||||||
@@ -74,8 +78,11 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
return checkedReferenceTypes
|
return checkedReferenceTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun eliminateRedundantChecks(checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
private fun eliminateRedundantChecks(
|
||||||
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes)
|
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||||
|
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||||
|
) {
|
||||||
|
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes, stackOnThrowExceptions)
|
||||||
|
|
||||||
val nullabilityMap = analyzeNullabilities()
|
val nullabilityMap = analyzeNullabilities()
|
||||||
|
|
||||||
@@ -84,8 +91,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
transformTrivialChecks(nullabilityMap)
|
transformTrivialChecks(nullabilityMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun injectNullabilityAssumptions(checkedReferenceTypes: Map<AbstractInsnNode, Type>) =
|
private fun injectNullabilityAssumptions(
|
||||||
NullabilityAssumptionsBuilder(checkedReferenceTypes).injectNullabilityAssumptions()
|
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||||
|
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||||
|
) = NullabilityAssumptionsBuilder(checkedReferenceTypes, stackOnThrowExceptions).injectNullabilityAssumptions()
|
||||||
|
|
||||||
private fun analyzeNullabilities(): Map<AbstractInsnNode, StrictBasicValue> {
|
private fun analyzeNullabilities(): Map<AbstractInsnNode, StrictBasicValue> {
|
||||||
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
|
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
|
||||||
@@ -168,7 +177,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class NullabilityAssumptionsBuilder(val checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
private inner class NullabilityAssumptionsBuilder(
|
||||||
|
val checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||||
|
val stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||||
|
) {
|
||||||
|
|
||||||
private val checksDependingOnVariable = HashMap<Int, MutableList<AbstractInsnNode>>()
|
private val checksDependingOnVariable = HashMap<Int, MutableList<AbstractInsnNode>>()
|
||||||
|
|
||||||
@@ -362,6 +374,8 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
|||||||
athrow()
|
athrow()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
methodNode.maxStack = Math.max(methodNode.maxStack, (stackOnThrowExceptions[insn] ?: -1) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// FILE: 1.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
inline fun String.fire(message: String? = null) {
|
||||||
|
val res = this + message!!
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: 2.kt
|
||||||
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
|
||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val receiver = "receiver"
|
||||||
|
"".let {
|
||||||
|
{
|
||||||
|
receiver.fire()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -224,6 +224,12 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt19723.kt")
|
||||||
|
public void testKt19723() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt19723.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6552.kt")
|
@TestMetadata("kt6552.kt")
|
||||||
public void testKt6552() throws Exception {
|
public void testKt6552() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||||
|
|||||||
+6
@@ -224,6 +224,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt19723.kt")
|
||||||
|
public void testKt19723() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt19723.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6552.kt")
|
@TestMetadata("kt6552.kt")
|
||||||
public void testKt6552() throws Exception {
|
public void testKt6552() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||||
|
|||||||
@@ -224,6 +224,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt19723.kt")
|
||||||
|
public void testKt19723() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt19723.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6552.kt")
|
@TestMetadata("kt6552.kt")
|
||||||
public void testKt6552() throws Exception {
|
public void testKt6552() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||||
|
|||||||
+6
@@ -224,6 +224,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt19723.kt")
|
||||||
|
public void testKt19723() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt19723.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6552.kt")
|
@TestMetadata("kt6552.kt")
|
||||||
public void testKt6552() throws Exception {
|
public void testKt6552() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user