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
|
||||
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);
|
||||
|
||||
|
||||
+1
-1
@@ -23,4 +23,4 @@ fun simpleFunVoid(f: () -> Unit): Unit {
|
||||
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()
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
||||
@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");
|
||||
|
||||
Reference in New Issue
Block a user