Code clean and some refactorings in 'getLambdaIfExistsAndMarkInstructions'
This commit is contained in:
@@ -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()
|
||||
|
||||
+51
-51
@@ -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)
|
||||
|
||||
+51
-51
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user