Skip to content

Inliner could narrow invokeinterface to invokevirtual #388

Open
@retronym

Description

@retronym
scala> abstract class Inline5 extends (AnyRef => AnyRef) { def apply(a: AnyRef) = a; def test(ls: List[AnyRef]) = ls.mapConserve(this) }
defined class Inline5

scala> :javap -c Inline5#test
  public scala.collection.immutable.List<java.lang.Object> test(scala.collection.immutable.List<java.lang.Object>);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: aconst_null
       5: athrow
       6: aconst_null
       7: aconst_null
       8: aload_1
       9: aload_1
      10: astore        5
      12: astore        4
      14: astore_3
      15: astore_2
      16: aload         5
      18: invokevirtual #198                // Method scala/collection/immutable/List.isEmpty:()Z
      21: ifeq          47
      24: aload_2
      25: ifnonnull     35
      28: aload         4
      30: astore        14
      32: goto          230
      35: aload_3
      36: aload         4
      38: invokevirtual #204                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
      41: aload_2
      42: astore        14
      44: goto          230
      47: aload         5
      49: invokevirtual #208                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
      52: astore        6
      54: aload_0
      55: aload         6
      57: invokeinterface #210,  2          // InterfaceMethod scala/Function1.apply:(Ljava/lang/Object;)Ljava/lang/Object;
      62: astore        7
      64: aload         7
      66: aload         6
      68: if_acmpne     92
      71: aload_2
      72: aload_3
      73: aload         4
      75: aload         5
      77: invokevirtual #213                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
      80: checkcast     #194                // class scala/collection/immutable/List
      83: astore        5
      85: astore        4
      87: astore_3
      88: astore_2
      89: goto          16
      92: aload         4
      94: astore        8
      96: aload_2
      97: astore        9
      99: aload_3
     100: astore        10
     102: aload         8
     104: aload         5
     106: if_acmpeq     164
     109: new           #200                // class scala/collection/immutable/$colon$colon
     112: dup
     113: aload         8
     115: invokevirtual #208                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     118: getstatic     #219                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     121: invokespecial #223                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
     124: astore        11
     126: aload         9
     128: ifnonnull     135
     131: aload         11
     133: astore        9
     135: aload         10
     137: ifnull        147
     140: aload         10
     142: aload         11
     144: invokevirtual #204                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
     147: aload         11
     149: astore        10
     151: aload         8
     153: invokevirtual #213                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     156: checkcast     #194                // class scala/collection/immutable/List
     159: astore        8
     161: goto          102
     164: new           #200                // class scala/collection/immutable/$colon$colon
     167: dup
     168: aload         7
     170: getstatic     #219                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     173: invokespecial #223                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
     176: astore        12
     178: aload         9
     180: ifnonnull     187
     183: aload         12
     185: astore        9
     187: aload         10
     189: ifnull        199
     192: aload         10
     194: aload         12
     196: invokevirtual #204                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
     199: aload         12
     201: astore        10
     203: aload         5
     205: invokevirtual #213                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     208: checkcast     #194                // class scala/collection/immutable/List
     211: astore        13
     213: aload         9
     215: aload         10
     217: aload         13
     219: aload         13
     221: astore        5
     223: astore        4
     225: astore_3
     226: astore_2
     227: goto          16
     230: aload         14
     232: areturn

I'd like to see:

-      57: invokeinterface #210,  2          // InterfaceMethod scala/Function1.apply:(Ljava/lang/Object;)Ljava/lang/Object;
+      57: invokevirtual #210,  2          // Method scala/Inline5.apply:(Ljava/lang/Object;)Ljava/lang/Object;

I noticed this in TypeMap, which inlines mapConserve(this). Polymorpic invokeinterface call sites are a bit more expensive the invokevirtual.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions