Generate 'nop' instruction on lambda call when everything on line is going to be eliminated by inliner (KT-6477)

(cherry picked from commit 462bdb2)

 #KT-6477 Fixed
This commit is contained in:
Nikolay Krasko
2016-10-03 20:45:45 +03:00
committed by Nikolay Krasko
parent 708a0e3b5d
commit 87b628a3f7
11 changed files with 96 additions and 2 deletions
@@ -219,6 +219,12 @@ public class MethodInliner {
int valueParamShift = Math.max(getNextLocalIndex(), markerShift);//NB: don't inline cause it changes
putStackValuesIntoLocals(info.getInvokeParamsWithoutCaptured(), valueParamShift, this, desc);
if (invokeCall.lambdaInfo.getFunctionDescriptor().getValueParameters().isEmpty()) {
// There won't be no parameters processing and line call can be left without actual instructions.
// Note: if function is called on the line with other instructions like 1 + foo() no will still be generated.
visitInsn(Opcodes.NOP);
}
addInlineMarker(this, true);
Parameters lambdaParameters = info.addAllParameters(nodeRemapper);
@@ -23,4 +23,4 @@ fun simpleFunVoid(f: () -> Unit): Unit {
return f()
}
// 3 NOP
// 5 NOP
@@ -0,0 +1,14 @@
fun box() {
lookAtMe {
12
}
}
inline fun lookAtMe(f: () -> Int): Int {
val a = 42
a + f() // Even this line already has meaningful instraction nop is still generated
return 13
}
// TODO: Less NOPs is better
// 2 NOP
@@ -0,0 +1,12 @@
fun box() {
lookAtMe {
val c = "c"
}
}
inline fun lookAtMe(f: (String) -> Unit) {
val a = "a"
f(a) // Should be no unneeded nops on this line, that might be generated for zero-parameters lambda
}
// 2 NOP
@@ -13,4 +13,4 @@ inline fun foo(f: () -> Unit) {
f()
}
// 2 17 18 +3 4 19 +6 20 21 +7 8 22 +9 12 13 14
// 2 17 18 3 4 19 +6 20 21 7 8 22 +9 12 13 14
@@ -0,0 +1,12 @@
fun box() {
lookAtMe {
42
}
}
inline fun lookAtMe(f: () -> Int) {
val a = 21
a + f()
}
// 2 13 14 3 15 +5 8 9 10
@@ -1063,6 +1063,18 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName);
}
@TestMetadata("linenumberForNoParametersArgumentCallInExpression.kt")
public void testLinenumberForNoParametersArgumentCallInExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/linenumberForNoParametersArgumentCallInExpression.kt");
doTest(fileName);
}
@TestMetadata("linenumberForOneParametersArgumentCall.kt")
public void testLinenumberForOneParametersArgumentCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/linenumberForOneParametersArgumentCall.kt");
doTest(fileName);
}
@TestMetadata("noSynAccessor.kt")
public void testNoSynAccessor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/noSynAccessor.kt");
@@ -220,6 +220,12 @@ public class LineNumberTestGenerated extends AbstractLineNumberTest {
doTestCustom(fileName);
}
@TestMetadata("noParametersArgumentCallInExpression.kt")
public void testNoParametersArgumentCallInExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/noParametersArgumentCallInExpression.kt");
doTestCustom(fileName);
}
@TestMetadata("smapInlineAsArgument.kt")
public void testSmapInlineAsArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/smapInlineAsArgument.kt");
@@ -0,0 +1,8 @@
LineBreakpoint created at noParameterLambdaArgumentCallInInline.kt:16
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! noParameterLambdaArgumentCallInInline.NoParameterLambdaArgumentCallInInlineKt
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
noParameterLambdaArgumentCallInInline.kt:16
noParameterLambdaArgumentCallInInline.kt:17
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
@@ -0,0 +1,18 @@
package noParameterLambdaArgumentCallInInline
/*
KT-6477 Breakpoints do not work in inline functions at line where inlined argument without arguments is invoked
*/
fun main(args: Array<String>) {
lookAtMe {
val c = "c"
}
}
inline fun lookAtMe(f: () -> Unit) {
val a = "a"
//Breakpoint!
f()
val b = "b"
}
@@ -433,6 +433,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
doStepOverTest(fileName);
}
@TestMetadata("noParameterLambdaArgumentCallInInline.kt")
public void testNoParameterLambdaArgumentCallInInline() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/noParameterLambdaArgumentCallInInline.kt");
doStepOverTest(fileName);
}
@TestMetadata("stepOverCatchClause.kt")
public void testStepOverCatchClause() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverCatchClause.kt");