Kotlin Компилятор: `nop`s в байт-коде - PullRequest
2 голосов
/ 08 января 2020

Я проверяю kotlinc байт-код захвата лямбд. И пытается понять причину, по которой полученный байт-код содержит 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
}

с несколько 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 с также.

  1. В чем причина наличия nop s в неоптимизированном коде? (отладочная информация /...)
  2. Есть ли причина иметь nop s в оптимизированном коде?

1 Ответ

3 голосов
/ 09 января 2020

Причиной nop s в байт-коде, который испускает компилятор Kotlin, является возможность для отладчика поставить точку останова на закрывающей скобке, т.е. после последнего оператора, функции или if - пункт и другие пункты, и сделать возможным шаг в эти места. Для этого требуется инструкция, присутствующая в байт-коде, которая также помечена номером строки.

Некоторые nop затем оптимизируются, если они являются избыточными, например, когда после последнего оператора уже есть действительная инструкция инструкции.

...