Is there a reason kotlinc generates sam wrappers w...
# compiler
v
Is there a reason kotlinc generates sam wrappers within inline functions? In other words, the bytecode for the following function becomes significantly worse when the function is inline:
Copy code
inline fun test(x: java.util.stream.Stream<out String>) {
    x.map {
        it.length  
    }
}
non-inline
test
bytecode:
Copy code
// access flags 0x19
  // signature (Ljava/util/stream/Stream<+Ljava/lang/String;>;)V
  // declaration: void test(java.util.stream.Stream<? extends java.lang.String>)
  public final static test(Ljava/util/stream/Stream;)V
    // annotable parameter count: 1 (invisible)
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 0
    LDC "x"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 143 L1
    ALOAD 0
    INVOKEDYNAMIC invoke()Lkotlin/jvm/functions/Function1; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)Ljava/lang/Object;, 
      // handle kind 0x6 : INVOKESTATIC
      net/jqwik/kotlin/api/JqwikGlobalsKt.test$lambda$5(Ljava/lang/String;)Ljava/lang/Integer;, 
      (Ljava/lang/String;)Ljava/lang/Integer;
    ]
    INVOKEDYNAMIC apply(Lkotlin/jvm/functions/Function1;)Ljava/util/function/Function; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)Ljava/lang/Object;, 
      // handle kind 0x6 : INVOKESTATIC
      net/jqwik/kotlin/api/JqwikGlobalsKt.test$lambda$6(Lkotlin/jvm/functions/Function1;Ljava/lang/Object;)Ljava/lang/Integer;, 
      (Ljava/lang/Object;)Ljava/lang/Integer;
    ]
    INVOKEINTERFACE java/util/stream/Stream.map (Ljava/util/function/Function;)Ljava/util/stream/Stream; (itf)
    POP
   L2
    LINENUMBER 146 L2
    RETURN
   L3
    LOCALVARIABLE x Ljava/util/stream/Stream; L0 L3 0
    MAXSTACK = 2
    MAXLOCALS = 1
inline
test
Copy code
// access flags 0x19
  // signature (Ljava/util/stream/Stream<+Ljava/lang/String;>;)V
  // declaration: void test(java.util.stream.Stream<? extends java.lang.String>)
  public final static test(Ljava/util/stream/Stream;)V
    // annotable parameter count: 1 (invisible)
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 0
    LDC "x"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
    ICONST_0
    ISTORE 1
   L1
    LINENUMBER 143 L1
    ALOAD 0
    GETSTATIC net/jqwik/kotlin/api/JqwikGlobalsKt$test$1.INSTANCE : Lnet/jqwik/kotlin/api/JqwikGlobalsKt$test$1;
    CHECKCAST kotlin/jvm/functions/Function1
    ASTORE 2
    NEW net/jqwik/kotlin/api/JqwikGlobalsKt$sam$i$java_util_function_Function$0
    DUP
    ALOAD 2
    INVOKESPECIAL net/jqwik/kotlin/api/JqwikGlobalsKt$sam$i$java_util_function_Function$0.<init> (Lkotlin/jvm/functions/Function1;)V
    CHECKCAST java/util/function/Function
    INVOKEINTERFACE java/util/stream/Stream.map (Ljava/util/function/Function;)Ljava/util/stream/Stream; (itf)
    POP
   L2
    LINENUMBER 146 L2
    RETURN
   L3
    LOCALVARIABLE $i$f$test I L1 L3 1
    LOCALVARIABLE x Ljava/util/stream/Stream; L0 L3 0
    MAXSTACK = 4
    MAXLOCALS = 3
The issue is that extra
JqwikGlobalsKt$sam$i$java_util_function_Function$0
sam wrapper defeats jqwik’s caching as the sam wrapper misses
equals/hashCode