Remove empty try catch nodes from inlined code
This commit is contained in:
@@ -356,7 +356,6 @@ public class MethodInliner {
|
||||
|
||||
AbstractInsnNode cur = node.instructions.getFirst();
|
||||
int index = 0;
|
||||
Set<LabelNode> possibleDeadLabels = new HashSet<LabelNode>();
|
||||
|
||||
while (cur != null) {
|
||||
Frame<SourceValue> frame = sources[index];
|
||||
@@ -416,15 +415,12 @@ public class MethodInliner {
|
||||
if (frame == null) {
|
||||
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
|
||||
if (prevNode.getType() == AbstractInsnNode.LABEL) {
|
||||
possibleDeadLabels.add((LabelNode) prevNode);
|
||||
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
|
||||
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
|
||||
//but as result all this labels will be merged into one (see KT-5863)
|
||||
} else {
|
||||
node.instructions.remove(prevNode);
|
||||
}
|
||||
} else {
|
||||
//Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
|
||||
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
|
||||
//but as result all this labels will be merged into one (see KT-5863)
|
||||
possibleDeadLabels.remove(prevNode.getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +428,7 @@ public class MethodInliner {
|
||||
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
|
||||
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
|
||||
TryCatchBlockNode block = iterator.next();
|
||||
if (possibleDeadLabels.contains(block.start) && possibleDeadLabels.contains(block.end)) {
|
||||
if (isEmptyTryInterval(block)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -440,6 +436,15 @@ public class MethodInliner {
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean isEmptyTryInterval(@NotNull TryCatchBlockNode tryCatchBlockNode) {
|
||||
LabelNode start = tryCatchBlockNode.start;
|
||||
AbstractInsnNode end = tryCatchBlockNode.end;
|
||||
while (end != start && end instanceof LabelNode) {
|
||||
end = end.getPrevious();
|
||||
}
|
||||
return start == end;
|
||||
}
|
||||
|
||||
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
|
||||
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
||||
int varIndex = ((VarInsnNode) insnNode).var;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import test.*
|
||||
|
||||
fun call(): String {
|
||||
return nonLocal()
|
||||
}
|
||||
|
||||
inline fun nonLocal(): String {
|
||||
mysynchronized(Object()) {
|
||||
return "nonLocal"
|
||||
}
|
||||
return "local"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val call = call()
|
||||
if (call != "nonLocal") return "fail $call"
|
||||
return "OK"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> mysynchronized(lock: Any, block: () -> R): R {
|
||||
try {
|
||||
return block()
|
||||
}
|
||||
finally {
|
||||
//do nothing
|
||||
1
|
||||
}
|
||||
}
|
||||
+6
@@ -567,6 +567,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("synchonized.1.kt")
|
||||
public void testSynchonized() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("throwInFinally.1.kt")
|
||||
public void testThrowInFinally() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.1.kt");
|
||||
|
||||
+6
@@ -567,6 +567,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("synchonized.1.kt")
|
||||
public void testSynchonized() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/synchonized.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("throwInFinally.1.kt")
|
||||
public void testThrowInFinally() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.1.kt");
|
||||
|
||||
Reference in New Issue
Block a user