Code clean and some refactorings in 'getLambdaIfExistsAndMarkInstructions'

This commit is contained in:
Michael Bogdanov
2016-02-08 14:59:49 +03:00
parent c75b514551
commit 0f90dc1649
19 changed files with 143 additions and 154 deletions
@@ -19,12 +19,10 @@ package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.Nullable;
class InvokeCall {
private final int index;
public final LambdaInfo lambdaInfo;
public final int finallyDepthShift;
InvokeCall(int index, @Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
this.index = index;
InvokeCall(@Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
this.lambdaInfo = lambdaInfo;
this.finallyDepthShift = finallyDepthShift;
}
@@ -431,13 +431,12 @@ public class MethodInliner {
Set<AbstractInsnNode> toDelete = SmartSet.create();
InsnList instructions = node.instructions;
AbstractInsnNode cur = instructions.getFirst();
int index = 0;
boolean awaitClassReification = false;
int currentFinallyDeep = 0;
while (cur != null) {
Frame<SourceValue> frame = sources[index];
Frame<SourceValue> frame = sources[instructions.indexOf(cur)];
if (frame != null) {
if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) {
@@ -460,17 +459,11 @@ public class MethodInliner {
if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) {
SourceValue sourceValue = frame.getStack(firstParameterIndex);
LambdaInfo lambdaInfo = null;
int varIndex = -1;
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), true, instructions, sources, toDelete
);
AbstractInsnNode insnNode = MethodInlinerUtilKt.singleOrNullInsn(sourceValue);
if (insnNode != null) {
lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, insnNode, frame, true, instructions, sources, toDelete
);
}
invokeCalls.add(new InvokeCall(varIndex, lambdaInfo, currentFinallyDeep));
invokeCalls.add(new InvokeCall(lambdaInfo, currentFinallyDeep));
}
else if (isAnonymousConstructorCall(owner, name)) {
Map<Integer, LambdaInfo> lambdaMapping = new HashMap<Integer, LambdaInfo>();
@@ -478,15 +471,13 @@ public class MethodInliner {
int offset = 0;
for (int i = 0; i < paramCount; i++) {
SourceValue sourceValue = frame.getStack(firstParameterIndex + i);
AbstractInsnNode insnNode = MethodInlinerUtilKt.singleOrNullInsn(sourceValue);
if (insnNode != null) {
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, insnNode, frame, false, instructions, sources, toDelete
);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
}
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), false, instructions, sources, toDelete
);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
}
offset += i == 0 ? 1 : argTypes[i - 1].getSize();
}
@@ -513,7 +504,6 @@ public class MethodInliner {
}
AbstractInsnNode prevNode = cur;
cur = cur.getNext();
index++;
//given frame is <tt>null</tt> if and only if the corresponding instruction cannot be reached (dead code).
if (frame == null) {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
@@ -26,46 +27,46 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
insnNode: AbstractInsnNode,
localFrame: Frame<SourceValue>,
insnNode: AbstractInsnNode?,
processSwap: Boolean,
insnList: InsnList,
frames: Array<Frame<SourceValue>?>,
toDelete: MutableSet<AbstractInsnNode>
): LambdaInfo? {
if (insnNode == null) return null
val processingInsnNode = if (processSwap && insnNode.opcode == Opcodes.SWAP) InlineCodegenUtil.getPrevMeaningful(insnNode) else insnNode
getLambdaIfExists(insnNode)?.let {
//delete lambda aload instruction
toDelete.add(insnNode)
return it
}
var lambdaInfo = getLambdaIfExists(processingInsnNode)
if (lambdaInfo == null && processingInsnNode is VarInsnNode && processingInsnNode.opcode == Opcodes.ALOAD) {
val varIndex = processingInsnNode.`var`
val local = localFrame.getLocal(varIndex)
val storeIns = local.singleOrNullInsn()
if (insnNode is VarInsnNode && insnNode.opcode == Opcodes.ALOAD) {
val varIndex = insnNode.`var`
val localFrame = frames[insnList.indexOf(insnNode)] ?: return null
val storeIns = localFrame.getLocal(varIndex).singleOrNullInsn()
if (storeIns is VarInsnNode && storeIns.getOpcode() == Opcodes.ASTORE) {
val frame = frames[insnList.indexOf(storeIns)]
if (frame != null) {
val topOfStack = frame.getStack(frame.stackSize - 1)
val lambdaAload = topOfStack.singleOrNullInsn()
if (lambdaAload != null) {
lambdaInfo = getLambdaIfExistsAndMarkInstructions(lambdaAload, frame, processSwap, insnList, frames, toDelete)
if (lambdaInfo != null) {
toDelete.add(storeIns)
toDelete.add(lambdaAload)
}
}
val frame = frames[insnList.indexOf(storeIns)] ?: return null
val topOfStack = frame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(topOfStack, processSwap, insnList, frames, toDelete)?.let {
//remove intermediate lambda astore, aload instruction: see 'complexStack/simple.1.kt' test
toDelete.add(storeIns)
toDelete.add(insnNode)
return it
}
}
}
if (lambdaInfo != null) {
InsnSequence(processingInsnNode!!, insnNode).forEach { toDelete.add(it) }
toDelete.add(insnNode)
else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
val dispatchReceiver = swapFrame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete).let {
//remove swap instruction (dispatch receiver would be deleted on recursion call): see 'complexStack/simpleExtension.1.kt' test
toDelete.add(insnNode)
return it
}
}
return lambdaInfo
return null
}
fun SourceValue.singleOrNullInsn(): AbstractInsnNode? {
return insns.singleOrNull()
}
fun SourceValue.singleOrNullInsn() = insns.singleOrNull()
@@ -548,57 +548,6 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
}
}
@TestMetadata("compiler/testData/codegen/boxInline/compexStack")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CompexStack extends AbstractBlackBoxInlineCodegenTest {
public void testAllFilesPresentInCompexStack() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/compexStack"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("asCheck.1.kt")
public void testAsCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/asCheck.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("asCheck2.1.kt")
public void testAsCheck2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/asCheck2.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple2.1.kt")
public void testSimple2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple2.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple3.1.kt")
public void testSimple3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple3.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple4.1.kt")
public void testSimple4() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple4.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simpleExtension.1.kt")
public void testSimpleExtension() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simpleExtension.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/complex")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -638,6 +587,57 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
}
}
@TestMetadata("compiler/testData/codegen/boxInline/complexStack")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ComplexStack extends AbstractBlackBoxInlineCodegenTest {
public void testAllFilesPresentInComplexStack() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/complexStack"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("asCheck.1.kt")
public void testAsCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/asCheck.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("asCheck2.1.kt")
public void testAsCheck2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/asCheck2.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple2.1.kt")
public void testSimple2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple2.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple3.1.kt")
public void testSimple3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple3.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple4.1.kt")
public void testSimple4() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple4.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simpleExtension.1.kt")
public void testSimpleExtension() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simpleExtension.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/defaultValues")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -548,57 +548,6 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
}
}
@TestMetadata("compiler/testData/codegen/boxInline/compexStack")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CompexStack extends AbstractCompileKotlinAgainstInlineKotlinTest {
public void testAllFilesPresentInCompexStack() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/compexStack"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("asCheck.1.kt")
public void testAsCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/asCheck.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("asCheck2.1.kt")
public void testAsCheck2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/asCheck2.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple2.1.kt")
public void testSimple2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple2.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple3.1.kt")
public void testSimple3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple3.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple4.1.kt")
public void testSimple4() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simple4.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simpleExtension.1.kt")
public void testSimpleExtension() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/compexStack/simpleExtension.1.kt");
doBoxTestWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/complex")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -638,6 +587,57 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
}
}
@TestMetadata("compiler/testData/codegen/boxInline/complexStack")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ComplexStack extends AbstractCompileKotlinAgainstInlineKotlinTest {
public void testAllFilesPresentInComplexStack() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/complexStack"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("asCheck.1.kt")
public void testAsCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/asCheck.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("asCheck2.1.kt")
public void testAsCheck2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/asCheck2.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple2.1.kt")
public void testSimple2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple2.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple3.1.kt")
public void testSimple3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple3.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple4.1.kt")
public void testSimple4() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simple4.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simpleExtension.1.kt")
public void testSimpleExtension() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/complexStack/simpleExtension.1.kt");
doBoxTestWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/defaultValues")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)