Kotlin 编译器:字节码中的 `nop`
Kotlin Compiler: `nop`s in bytecode
我正在检查 kotlinc
捕获 lambda 的字节码。并试图理解生成的字节码具有 nop
指令的原因。
kotlinc -jvm-target 1.6 .
private inline fun lambdaCapturing(f: () -> Int): Int = f()
fun main(args: Array<String>) {
lambdaCapturing { 42 }
}
结果我得到
public final class x.y.z.LambdaCaptKt {
private static final int lambdaCapturing(kotlin.jvm.functions.Function0<java.lang.Integer>);
Code:
0: ldc #8 // int 0
2: istore_1
3: aload_0
4: invokeinterface #14, 1 // InterfaceMethod kotlin/jvm/functions/Function0.invoke:()Ljava/lang/Object;
9: checkcast #16 // class java/lang/Number
12: invokevirtual #20 // Method java/lang/Number.intValue:()I
15: ireturn
public static final void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #29 // String args
3: invokestatic #35 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: iconst_0
7: istore_1
8: iconst_0
9: istore_2
10: nop
11: nop
12: nop
13: return
}
在 main 函数中有几个 nop
指令。
如果我用 -Xno-optimize
编译相同的代码片段,main
函数将类似于
public static final void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #29 // String args
3: invokestatic #35 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: nop
7: iconst_0
8: istore_1
9: nop
10: iconst_0
11: istore_2
12: bipush 10
14: nop
15: goto 18
18: invokestatic #41 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
21: checkcast #16 // class java/lang/Number
24: invokevirtual #20 // Method java/lang/Number.intValue:()I
27: nop
28: goto 31
31: pop
32: return
还有nop
。
- 未优化代码中有
nop
的原因是什么? (调试信息/...)
- 是否有任何理由在优化代码中包含
nop
?
Kotlin 编译器生成的字节码中出现 nop
的原因是调试器可能会在函数或 [= 的最后一个语句之后的右大括号处放置断点11=]-子句和其他子句,并使跳转到那些位置成为可能。这样做需要字节码中存在一条指令,该指令也标有行号。
一些 nop
如果它们是冗余的,例如当最后一条语句指令之后已经有一个有效指令时,它们将被优化掉。
我正在检查 kotlinc
捕获 lambda 的字节码。并试图理解生成的字节码具有 nop
指令的原因。
kotlinc -jvm-target 1.6 .
private inline fun lambdaCapturing(f: () -> Int): Int = f()
fun main(args: Array<String>) {
lambdaCapturing { 42 }
}
结果我得到
public final class x.y.z.LambdaCaptKt {
private static final int lambdaCapturing(kotlin.jvm.functions.Function0<java.lang.Integer>);
Code:
0: ldc #8 // int 0
2: istore_1
3: aload_0
4: invokeinterface #14, 1 // InterfaceMethod kotlin/jvm/functions/Function0.invoke:()Ljava/lang/Object;
9: checkcast #16 // class java/lang/Number
12: invokevirtual #20 // Method java/lang/Number.intValue:()I
15: ireturn
public static final void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #29 // String args
3: invokestatic #35 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: iconst_0
7: istore_1
8: iconst_0
9: istore_2
10: nop
11: nop
12: nop
13: return
}
在 main 函数中有几个 nop
指令。
如果我用 -Xno-optimize
编译相同的代码片段,main
函数将类似于
public static final void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #29 // String args
3: invokestatic #35 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: nop
7: iconst_0
8: istore_1
9: nop
10: iconst_0
11: istore_2
12: bipush 10
14: nop
15: goto 18
18: invokestatic #41 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
21: checkcast #16 // class java/lang/Number
24: invokevirtual #20 // Method java/lang/Number.intValue:()I
27: nop
28: goto 31
31: pop
32: return
还有nop
。
- 未优化代码中有
nop
的原因是什么? (调试信息/...) - 是否有任何理由在优化代码中包含
nop
?
Kotlin 编译器生成的字节码中出现 nop
的原因是调试器可能会在函数或 [= 的最后一个语句之后的右大括号处放置断点11=]-子句和其他子句,并使跳转到那些位置成为可能。这样做需要字节码中存在一条指令,该指令也标有行号。
一些 nop
如果它们是冗余的,例如当最后一条语句指令之后已经有一个有效指令时,它们将被优化掉。