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:
committed by
Nikolay Krasko
parent
708a0e3b5d
commit
87b628a3f7
@@ -219,6 +219,12 @@ public class MethodInliner {
|
|||||||
int valueParamShift = Math.max(getNextLocalIndex(), markerShift);//NB: don't inline cause it changes
|
int valueParamShift = Math.max(getNextLocalIndex(), markerShift);//NB: don't inline cause it changes
|
||||||
putStackValuesIntoLocals(info.getInvokeParamsWithoutCaptured(), valueParamShift, this, desc);
|
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);
|
addInlineMarker(this, true);
|
||||||
Parameters lambdaParameters = info.addAllParameters(nodeRemapper);
|
Parameters lambdaParameters = info.addAllParameters(nodeRemapper);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -23,4 +23,4 @@ fun simpleFunVoid(f: () -> Unit): Unit {
|
|||||||
return f()
|
return f()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 NOP
|
// 5 NOP
|
||||||
|
|||||||
Vendored
+14
@@ -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
|
||||||
+12
@@ -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()
|
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);
|
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")
|
@TestMetadata("noSynAccessor.kt")
|
||||||
public void testNoSynAccessor() throws Exception {
|
public void testNoSynAccessor() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/noSynAccessor.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inline/noSynAccessor.kt");
|
||||||
|
|||||||
@@ -220,6 +220,12 @@ public class LineNumberTestGenerated extends AbstractLineNumberTest {
|
|||||||
doTestCustom(fileName);
|
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")
|
@TestMetadata("smapInlineAsArgument.kt")
|
||||||
public void testSmapInlineAsArgument() throws Exception {
|
public void testSmapInlineAsArgument() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/lineNumber/custom/smapInlineAsArgument.kt");
|
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
|
||||||
Vendored
+18
@@ -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);
|
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")
|
@TestMetadata("stepOverCatchClause.kt")
|
||||||
public void testStepOverCatchClause() throws Exception {
|
public void testStepOverCatchClause() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverCatchClause.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/stepOverCatchClause.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user