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();
|
AbstractInsnNode cur = node.instructions.getFirst();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
Set<LabelNode> possibleDeadLabels = new HashSet<LabelNode>();
|
|
||||||
|
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
Frame<SourceValue> frame = sources[index];
|
Frame<SourceValue> frame = sources[index];
|
||||||
@@ -416,15 +415,12 @@ public class MethodInliner {
|
|||||||
if (frame == null) {
|
if (frame == null) {
|
||||||
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
|
//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) {
|
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 {
|
} else {
|
||||||
node.instructions.remove(prevNode);
|
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;
|
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
|
||||||
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
|
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
|
||||||
TryCatchBlockNode block = iterator.next();
|
TryCatchBlockNode block = iterator.next();
|
||||||
if (possibleDeadLabels.contains(block.start) && possibleDeadLabels.contains(block.end)) {
|
if (isEmptyTryInterval(block)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,6 +436,15 @@ public class MethodInliner {
|
|||||||
return node;
|
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) {
|
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
|
||||||
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
||||||
int varIndex = ((VarInsnNode) insnNode).var;
|
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);
|
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")
|
@TestMetadata("throwInFinally.1.kt")
|
||||||
public void testThrowInFinally() throws Exception {
|
public void testThrowInFinally() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.1.kt");
|
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);
|
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")
|
@TestMetadata("throwInFinally.1.kt")
|
||||||
public void testThrowInFinally() throws Exception {
|
public void testThrowInFinally() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.1.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/tryFinally/exceptionTable/throwInFinally.1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user