scala / scala-dev

Scala 2 team issues. Not for user-facing bugs or directly actionable user-facing improvements. For build/test/infra and for longer-term planning and idea tracking. Our bug tracker is at https://github.com/scala/bug/issues
Apache License 2.0
130 stars 15 forks source link

Investigate whether or not scalac's AOT inlining hurts our warm up #517

Open retronym opened 6 years ago

retronym commented 6 years ago

Flight Recorder logs unusually long JIT compilation times. For instance scala.reflect.internal.TreeGen#mkTemplate reports 680ms to generated 192k of code.

The method itself isn't that big, but it uses a bunch of combinators that scalac -opt inlines.

Are we paying a price for this indiscriminate inlining? More code to compile could be slowing down our warm up; having too much native code could be hurting our instruction cache hit rate, etc.

/cc @lrytz @vjovanov

  def mkTemplate(parents: List[Tree], self: ValDef, constrMods: Modifiers,
                 vparamss: List[List[ValDef]], body: List[Tree], superPos: Position = NoPosition): Template = {
    /* Add constructor to template */

    // create parameters for <init> as synthetic trees.
    var vparamss1 = mmap(vparamss) { vd =>
      val param = atPos(vd.pos.makeTransparent) {
        val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR)
        ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, duplicateAndKeepPositions(vd.rhs))
      }
      param
    }

    val (edefs, rest) = body span treeInfo.isEarlyDef
    val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
    val gvdefs = evdefs map {
      case vdef @ ValDef(_, _, tpt, _) =>
        copyValDef(vdef)(
        // atPos for the new tpt is necessary, since the original tpt might have no position
        // (when missing type annotation for ValDef for example), so even though setOriginal modifies the
        // position of TypeTree, it would still be NoPosition. That's what the author meant.
        tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus),
        rhs = EmptyTree
      )
    }
    val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = vdef.mods | PRESUPER) }

    val constr = {
      if (constrMods.isTrait) {
        if (body forall treeInfo.isInterfaceMember) None
        else Some(
          atPos(wrappingPos(superPos, lvdefs)) (
            DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, mkLiteralUnit))))
      }
      else {
        // convert (implicit ... ) to ()(implicit ... ) if it's the only parameter section
        if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
          vparamss1 = List() :: vparamss1
        val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass
                                         // this requires knowing which of the parents is a type macro and which is not
                                         // and that's something that cannot be found out before typer
                                         // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon)
                                         // this means that we don't know what will be the arguments of the super call
                                         // therefore here we emit a dummy which gets populated when the template is named and typechecked
        Some(
          atPos(wrappingPos(superPos, lvdefs ::: vparamss1.flatten).makeTransparent) (
            DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), mkLiteralUnit))))
      }
    }
    constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false))
    // Field definitions for the class - remove defaults.

    val fieldDefs = vparamss.flatten map (vd => {
      val field = copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)
      // Prevent overlapping of `field` end's position with default argument's start position.
      // This is needed for `Positions.Locator(pos).traverse` to return the correct tree when
      // the `pos` is a point position with all its values equal to `vd.rhs.pos.start`.
      if(field.pos.isRange && vd.rhs.pos.isRange) field.pos = field.pos.withEnd(vd.rhs.pos.start - 1)
      field
    })

    global.Template(parents, self, gvdefs ::: fieldDefs ::: constr ++: etdefs ::: rest)
  }
scala> :javap -c scala.reflect.internal.TreeGen#mkTemplate
  public scala.reflect.internal.Trees$Template mkTemplate(scala.collection.immutable.List<scala.reflect.internal.Trees$Tree>, scala.reflect.internal.Trees$ValDef, scala.reflect.internal.Trees$Modifiers, scala.collection.immutable.List<scala.collection.immutable.List<scala.reflect.internal.Trees$ValDef>>, scala.collection.immutable.List<scala.reflect.internal.Trees$Tree>, scala.reflect.internal.util.Position);
    Code:
       0: aload_0
       1: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
       4: aload_0
       5: invokedynamic #1172,  0           // InvokeDynamic #1:apply:(Lscala/reflect/internal/TreeGen;)Lscala/Function1;
      10: astore        43
      12: ifnonnull     17
      15: aconst_null
      16: athrow
      17: aload         4
      19: aload         43
      21: invokedynamic #1184,  0           // InvokeDynamic #2:apply:(Lscala/Function1;)Lscala/Function1;
      26: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
      29: invokevirtual #423                // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
      32: astore        45
      34: astore        44
      36: ifnonnull     41
      39: aconst_null
      40: athrow
      41: aload         45
      43: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
      46: invokevirtual #883                // Method scala/collection/immutable/List$.ReusableCBF:()Lscala/collection/generic/GenTraversableFactory$GenericCanBuildFrom;
      49: if_acmpne     179
      52: aload         4
      54: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
      57: if_acmpne     68
      60: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
      63: astore        50
      65: goto          190
      68: new           #468                // class scala/collection/immutable/$colon$colon
      71: dup
      72: aload         4
      74: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
      77: checkcast     #398                // class scala/collection/immutable/List
      80: astore        52
      82: aload         43
      84: aload         52
      86: invokestatic  #1178               // InterfaceMethod scala/reflect/internal/util/Collections.$anonfun$mmap$1:(Lscala/Function1;Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
      89: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
      92: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      95: astore        46
      97: aload         46
      99: astore        47
     101: aload         4
     103: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     106: checkcast     #398                // class scala/collection/immutable/List
     109: astore        48
     111: aload         48
     113: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     116: if_acmpeq     172
     119: new           #468                // class scala/collection/immutable/$colon$colon
     122: dup
     123: aload         48
     125: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     128: checkcast     #398                // class scala/collection/immutable/List
     131: astore        52
     133: aload         43
     135: aload         52
     137: invokestatic  #1178               // InterfaceMethod scala/reflect/internal/util/Collections.$anonfun$mmap$1:(Lscala/Function1;Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
     140: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     143: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
     146: astore        49
     148: aload         47
     150: aload         49
     152: invokevirtual #486                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
     155: aload         49
     157: astore        47
     159: aload         48
     161: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     164: checkcast     #398                // class scala/collection/immutable/List
     167: astore        48
     169: goto          111
     172: aload         46
     174: astore        50
     176: goto          190
     179: aload         4
     181: aload         44
     183: aload         45
     185: invokestatic  #889                // InterfaceMethod scala/collection/TraversableLike.map$:(Lscala/collection/TraversableLike;Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
     188: astore        50
     190: aload         50
     192: checkcast     #398                // class scala/collection/immutable/List
     195: astore        51
     197: aload         51
     199: astore        7
     201: aload         5
     203: ifnonnull     208
     206: aconst_null
     207: athrow
     208: new           #1186               // class scala/collection/mutable/ListBuffer
     211: dup
     212: invokespecial #1187               // Method scala/collection/mutable/ListBuffer."<init>":()V
     215: astore        24
     217: aload         5
     219: astore        25
     221: aload         25
     223: invokevirtual #853                // Method scala/collection/immutable/List.isEmpty:()Z
     226: ifne          272
     229: aload         25
     231: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     234: checkcast     #201                // class scala/reflect/internal/Trees$Tree
     237: astore        53
     239: aload_0
     240: aload         53
     242: invokestatic  #1191               // Method $anonfun$mkTemplate$2:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$Tree;)Z
     245: ifeq          272
     248: aload         24
     250: aload         25
     252: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     255: invokevirtual #1195               // Method scala/collection/mutable/ListBuffer.$plus$eq:(Ljava/lang/Object;)Lscala/collection/mutable/ListBuffer;
     258: pop
     259: aload         25
     261: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     264: checkcast     #398                // class scala/collection/immutable/List
     267: astore        25
     269: goto          221
     272: aload         24
     274: invokevirtual #1198               // Method scala/collection/mutable/ListBuffer.toList:()Lscala/collection/immutable/List;
     277: astore        8
     279: aload         25
     281: astore        9
     283: aload         8
     285: astore        10
     287: aload         9
     289: astore        11
     291: aload         10
     293: aload_0
     294: invokedynamic #1206,  0           // InvokeDynamic #3:apply:(Lscala/reflect/internal/TreeGen;)Lscala/Function1;
     299: invokevirtual #1210               // Method scala/collection/immutable/List.partition:(Lscala/Function1;)Lscala/Tuple2;
     302: astore        12
     304: aload         12
     306: ifnull        332
     309: aload         12
     311: invokevirtual #1215               // Method scala/Tuple2._1:()Ljava/lang/Object;
     314: checkcast     #398                // class scala/collection/immutable/List
     317: astore        13
     319: aload         12
     321: invokevirtual #1218               // Method scala/Tuple2._2:()Ljava/lang/Object;
     324: checkcast     #398                // class scala/collection/immutable/List
     327: astore        14
     329: goto          342
     332: new           #751                // class scala/MatchError
     335: dup
     336: aload         12
     338: invokespecial #752                // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
     341: athrow
     342: aload         13
     344: astore        15
     346: aload         14
     348: astore        16
     350: aload         15
     352: aload_0
     353: invokedynamic #1226,  0           // InvokeDynamic #4:apply:(Lscala/reflect/internal/TreeGen;)Lscala/Function1;
     358: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
     361: invokevirtual #423                // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
     364: astore        27
     366: astore        26
     368: ifnonnull     373
     371: aconst_null
     372: athrow
     373: aload         27
     375: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
     378: invokevirtual #883                // Method scala/collection/immutable/List$.ReusableCBF:()Lscala/collection/generic/GenTraversableFactory$GenericCanBuildFrom;
     381: if_acmpne     509
     384: aload         15
     386: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     389: if_acmpne     400
     392: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     395: astore        32
     397: goto          520
     400: new           #468                // class scala/collection/immutable/$colon$colon
     403: dup
     404: aload         15
     406: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     409: checkcast     #201                // class scala/reflect/internal/Trees$Tree
     412: astore        54
     414: aload_0
     415: aload         54
     417: invokestatic  #1222               // Method $anonfun$mkTemplate$4:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$Tree;)Lscala/reflect/internal/Trees$ValDef;
     420: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     423: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
     426: astore        28
     428: aload         28
     430: astore        29
     432: aload         15
     434: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     437: checkcast     #398                // class scala/collection/immutable/List
     440: astore        30
     442: aload         30
     444: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     447: if_acmpeq     502
     450: new           #468                // class scala/collection/immutable/$colon$colon
     453: dup
     454: aload         30
     456: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     459: checkcast     #201                // class scala/reflect/internal/Trees$Tree
     462: astore        54
     464: aload_0
     465: aload         54
     467: invokestatic  #1222               // Method $anonfun$mkTemplate$4:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$Tree;)Lscala/reflect/internal/Trees$ValDef;
     470: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     473: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
     476: astore        31
     478: aload         29
     480: aload         31
     482: invokevirtual #486                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
     485: aload         31
     487: astore        29
     489: aload         30
     491: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
     494: checkcast     #398                // class scala/collection/immutable/List
     497: astore        30
     499: goto          442
     502: aload         28
     504: astore        32
     506: goto          520
     509: aload         15
     511: aload         26
     513: aload         27
     515: invokestatic  #889                // InterfaceMethod scala/collection/TraversableLike.map$:(Lscala/collection/TraversableLike;Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
     518: astore        32
     520: aload         32
     522: checkcast     #398                // class scala/collection/immutable/List
     525: astore        17
     527: aload         15
     529: new           #99                 // class scala/reflect/internal/TreeGen$$anonfun$1
     532: dup
     533: aload_0
     534: invokespecial #1229               // Method scala/reflect/internal/TreeGen$$anonfun$1."<init>":(Lscala/reflect/internal/TreeGen;)V
     537: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
     540: invokevirtual #423                // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
     543: invokevirtual #1233               // Method scala/collection/immutable/List.collect:(Lscala/PartialFunction;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
     546: checkcast     #398                // class scala/collection/immutable/List
     549: astore        18
     551: aload_3
     552: invokevirtual #1236               // Method scala/reflect/internal/Trees$Modifiers.isTrait:()Z
     555: ifeq          724
     558: aload         5
     560: astore        33
     562: aload         33
     564: invokeinterface #639,  1          // InterfaceMethod scala/collection/LinearSeqOptimized.isEmpty:()Z
     569: ifne          614
     572: aload         33
     574: invokeinterface #640,  1          // InterfaceMethod scala/collection/LinearSeqOptimized.head:()Ljava/lang/Object;
     579: checkcast     #201                // class scala/reflect/internal/Trees$Tree
     582: astore        55
     584: aload_0
     585: aload         55
     587: invokestatic  #1239               // Method $anonfun$mkTemplate$5:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$Tree;)Z
     590: ifne          599
     593: iconst_0
     594: istore        34
     596: goto          617
     599: aload         33
     601: invokeinterface #648,  1          // InterfaceMethod scala/collection/LinearSeqOptimized.tail:()Ljava/lang/Object;
     606: checkcast     #636                // class scala/collection/LinearSeqOptimized
     609: astore        33
     611: goto          562
     614: iconst_1
     615: istore        34
     617: iload         34
     619: ifeq          628
     622: getstatic     #653                // Field scala/None$.MODULE$:Lscala/None$;
     625: goto          923
     628: new           #646                // class scala/Some
     631: dup
     632: aload_0
     633: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     636: aload_0
     637: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     640: aload         6
     642: aload         18
     644: invokevirtual #1243               // Method scala/reflect/internal/SymbolTable.wrappingPos:(Lscala/reflect/internal/util/Position;Lscala/collection/immutable/List;)Lscala/reflect/internal/util/Position;
     647: new           #159                // class scala/reflect/internal/Trees$DefDef
     650: dup
     651: aload_0
     652: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     655: aload_0
     656: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     659: invokevirtual #1247               // Method scala/reflect/internal/SymbolTable.NoMods:()Lscala/reflect/api/Trees$ModifiersApi;
     662: checkcast     #177                // class scala/reflect/internal/Trees$Modifiers
     665: aload_0
     666: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     669: invokevirtual #339                // Method scala/reflect/internal/SymbolTable.nme:()Lscala/reflect/internal/StdNames$nme$;
     672: invokevirtual #1250               // Method scala/reflect/internal/StdNames$nme$.MIXIN_CONSTRUCTOR:()Lscala/reflect/internal/Names$TermName;
     675: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     678: getstatic     #1255               // Field scala/reflect/internal/util/package$.MODULE$:Lscala/reflect/internal/util/package$;
     681: invokevirtual #1258               // Method scala/reflect/internal/util/package$.ListOfNil:()Lscala/collection/immutable/List;
     684: new           #210                // class scala/reflect/internal/Trees$TypeTree
     687: dup
     688: aload_0
     689: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     692: invokespecial #1261               // Method scala/reflect/internal/Trees$TypeTree."<init>":(Lscala/reflect/internal/SymbolTable;)V
     695: new           #150                // class scala/reflect/internal/Trees$Block
     698: dup
     699: aload_0
     700: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     703: aload         18
     705: aload_0
     706: invokevirtual #1077               // Method mkLiteralUnit:()Lscala/reflect/internal/Trees$Literal;
     709: invokespecial #1099               // Method scala/reflect/internal/Trees$Block."<init>":(Lscala/reflect/internal/SymbolTable;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$Tree;)V
     712: invokespecial #1264               // Method scala/reflect/internal/Trees$DefDef."<init>":(Lscala/reflect/internal/SymbolTable;Lscala/reflect/internal/Trees$Modifiers;Lscala/reflect/internal/Names$TermName;Lscala/collection/immutable/List;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$Tree;Lscala/reflect/internal/Trees$Tree;)V
     715: invokevirtual #696                // Method scala/reflect/internal/SymbolTable.atPos:(Lscala/reflect/internal/util/Position;Lscala/reflect/internal/Trees$Tree;)Lscala/reflect/internal/Trees$Tree;
     718: invokespecial #647                // Method scala/Some."<init>":(Ljava/lang/Object;)V
     721: goto          923
     724: aload         51
     726: invokevirtual #853                // Method scala/collection/immutable/List.isEmpty:()Z
     729: ifne          773
     732: aload         51
     734: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     737: checkcast     #1266               // class scala/collection/SeqLike
     740: invokeinterface #1267,  1         // InterfaceMethod scala/collection/SeqLike.isEmpty:()Z
     745: ifne          787
     748: aload         51
     750: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
     753: checkcast     #1269               // class scala/collection/IterableLike
     756: invokeinterface #1270,  1         // InterfaceMethod scala/collection/IterableLike.head:()Ljava/lang/Object;
     761: checkcast     #216                // class scala/reflect/internal/Trees$ValDef
     764: invokevirtual #1274               // Method scala/reflect/internal/Trees$ValDef.mods:()Lscala/reflect/internal/Trees$Modifiers;
     767: invokevirtual #1277               // Method scala/reflect/internal/Trees$Modifiers.isImplicit:()Z
     770: ifeq          787
     773: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     776: astore        20
     778: aload         51
     780: aload         20
     782: invokevirtual #1278               // Method scala/collection/immutable/List.$colon$colon:(Ljava/lang/Object;)Lscala/collection/immutable/List;
     785: astore        7
     787: aload_0
     788: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     791: invokevirtual #1282               // Method scala/reflect/internal/SymbolTable.pendingSuperCall:()Lscala/reflect/internal/Trees$pendingSuperCall$;
     794: astore        21
     796: new           #646                // class scala/Some
     799: dup
     800: aload_0
     801: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     804: aload_0
     805: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     808: aload         6
     810: aload         7
     812: getstatic     #570                // Field scala/Predef$.MODULE$:Lscala/Predef$;
     815: invokevirtual #1286               // Method scala/Predef$.$conforms:()Lscala/Predef$$less$colon$less;
     818: invokevirtual #1290               // Method scala/collection/immutable/List.flatten:(Lscala/Function1;)Lscala/collection/GenTraversable;
     821: checkcast     #398                // class scala/collection/immutable/List
     824: aload         18
     826: invokevirtual #1293               // Method scala/collection/immutable/List.$colon$colon$colon:(Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
     829: invokevirtual #1243               // Method scala/reflect/internal/SymbolTable.wrappingPos:(Lscala/reflect/internal/util/Position;Lscala/collection/immutable/List;)Lscala/reflect/internal/util/Position;
     832: invokevirtual #1296               // Method scala/reflect/internal/util/Position.makeTransparent:()Lscala/reflect/internal/util/Position;
     835: new           #159                // class scala/reflect/internal/Trees$DefDef
     838: dup
     839: aload_0
     840: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     843: aload_3
     844: aload_0
     845: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     848: invokevirtual #339                // Method scala/reflect/internal/SymbolTable.nme:()Lscala/reflect/internal/StdNames$nme$;
     851: invokevirtual #1157               // Method scala/reflect/internal/StdNames$nme$.CONSTRUCTOR:()Lscala/reflect/internal/Names$TermName;
     854: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
     857: aload         7
     859: new           #210                // class scala/reflect/internal/Trees$TypeTree
     862: dup
     863: aload_0
     864: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     867: invokespecial #1261               // Method scala/reflect/internal/Trees$TypeTree."<init>":(Lscala/reflect/internal/SymbolTable;)V
     870: new           #150                // class scala/reflect/internal/Trees$Block
     873: dup
     874: aload_0
     875: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
     878: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
     881: getstatic     #570                // Field scala/Predef$.MODULE$:Lscala/Predef$;
     884: iconst_1
     885: anewarray     #219                // class scala/reflect/internal/Trees$pendingSuperCall$
     888: dup
     889: iconst_0
     890: aload         21
     892: aastore
     893: checkcast     #1089               // class "[Ljava/lang/Object;"
     896: invokevirtual #1093               // Method scala/Predef$.wrapRefArray:([Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
     899: invokevirtual #1096               // Method scala/collection/immutable/List$.apply:(Lscala/collection/Seq;)Lscala/collection/immutable/List;
     902: aload         18
     904: invokevirtual #1293               // Method scala/collection/immutable/List.$colon$colon$colon:(Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
     907: aload_0
     908: invokevirtual #1077               // Method mkLiteralUnit:()Lscala/reflect/internal/Trees$Literal;
     911: invokespecial #1099               // Method scala/reflect/internal/Trees$Block."<init>":(Lscala/reflect/internal/SymbolTable;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$Tree;)V
     914: invokespecial #1264               // Method scala/reflect/internal/Trees$DefDef."<init>":(Lscala/reflect/internal/SymbolTable;Lscala/reflect/internal/Trees$Modifiers;Lscala/reflect/internal/Names$TermName;Lscala/collection/immutable/List;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$Tree;Lscala/reflect/internal/Trees$Tree;)V
     917: invokevirtual #696                // Method scala/reflect/internal/SymbolTable.atPos:(Lscala/reflect/internal/util/Position;Lscala/reflect/internal/Trees$Tree;)Lscala/reflect/internal/Trees$Tree;
     920: invokespecial #647                // Method scala/Some."<init>":(Ljava/lang/Object;)V
     923: astore        19
     925: aload         19
     927: ifnonnull     932
     930: aconst_null
     931: athrow
     932: aload         19
     934: invokevirtual #656                // Method scala/Option.isEmpty:()Z
     937: ifne          959
     940: aload         19
     942: invokevirtual #663                // Method scala/Option.get:()Ljava/lang/Object;
     945: checkcast     #159                // class scala/reflect/internal/Trees$DefDef
     948: astore        56
     950: aload_0
     951: aload_1
     952: aload         17
     954: aload         56
     956: invokestatic  #1300               // Method $anonfun$mkTemplate$6:(Lscala/reflect/internal/TreeGen;Lscala/collection/immutable/List;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$DefDef;)V
     959: aload         4
     961: getstatic     #570                // Field scala/Predef$.MODULE$:Lscala/Predef$;
     964: invokevirtual #1286               // Method scala/Predef$.$conforms:()Lscala/Predef$$less$colon$less;
     967: invokevirtual #1290               // Method scala/collection/immutable/List.flatten:(Lscala/Function1;)Lscala/collection/GenTraversable;
     970: checkcast     #398                // class scala/collection/immutable/List
     973: aload_0
     974: invokedynamic #1305,  0           // InvokeDynamic #5:apply:(Lscala/reflect/internal/TreeGen;)Lscala/Function1;
     979: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
     982: invokevirtual #423                // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
     985: astore        37
     987: astore        36
     989: dup
     990: ifnonnull     995
     993: aconst_null
     994: athrow
     995: astore        35
     997: aload         37
     999: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
    1002: invokevirtual #883                // Method scala/collection/immutable/List$.ReusableCBF:()Lscala/collection/generic/GenTraversableFactory$GenericCanBuildFrom;
    1005: if_acmpne     1133
    1008: aload         35
    1010: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
    1013: if_acmpne     1024
    1016: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
    1019: astore        42
    1021: goto          1144
    1024: new           #468                // class scala/collection/immutable/$colon$colon
    1027: dup
    1028: aload         35
    1030: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
    1033: checkcast     #216                // class scala/reflect/internal/Trees$ValDef
    1036: astore        57
    1038: aload_0
    1039: aload         57
    1041: invokestatic  #1303               // Method $anonfun$mkTemplate$7:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$ValDef;)Lscala/reflect/internal/Trees$ValDef;
    1044: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
    1047: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
    1050: astore        38
    1052: aload         38
    1054: astore        39
    1056: aload         35
    1058: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
    1061: checkcast     #398                // class scala/collection/immutable/List
    1064: astore        40
    1066: aload         40
    1068: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
    1071: if_acmpeq     1126
    1074: new           #468                // class scala/collection/immutable/$colon$colon
    1077: dup
    1078: aload         40
    1080: invokevirtual #472                // Method scala/collection/immutable/List.head:()Ljava/lang/Object;
    1083: checkcast     #216                // class scala/reflect/internal/Trees$ValDef
    1086: astore        57
    1088: aload_0
    1089: aload         57
    1091: invokestatic  #1303               // Method $anonfun$mkTemplate$7:(Lscala/reflect/internal/TreeGen;Lscala/reflect/internal/Trees$ValDef;)Lscala/reflect/internal/Trees$ValDef;
    1094: getstatic     #455                // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
    1097: invokespecial #479                // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
    1100: astore        41
    1102: aload         39
    1104: aload         41
    1106: invokevirtual #486                // Method scala/collection/immutable/$colon$colon.tl_$eq:(Lscala/collection/immutable/List;)V
    1109: aload         41
    1111: astore        39
    1113: aload         40
    1115: invokevirtual #482                // Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
    1118: checkcast     #398                // class scala/collection/immutable/List
    1121: astore        40
    1123: goto          1066
    1126: aload         38
    1128: astore        42
    1130: goto          1144
    1133: aload         35
    1135: aload         36
    1137: aload         37
    1139: invokestatic  #889                // InterfaceMethod scala/collection/TraversableLike.map$:(Lscala/collection/TraversableLike;Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
    1142: astore        42
    1144: aload         42
    1146: checkcast     #398                // class scala/collection/immutable/List
    1149: astore        22
    1151: new           #195                // class scala/reflect/internal/Trees$Template
    1154: dup
    1155: aload_0
    1156: invokevirtual #333                // Method global:()Lscala/reflect/internal/SymbolTable;
    1159: aload_1
    1160: aload_2
    1161: aload         16
    1163: getstatic     #1310               // Field scala/Option$.MODULE$:Lscala/Option$;
    1166: aload         19
    1168: invokevirtual #1314               // Method scala/Option$.option2Iterable:(Lscala/Option;)Lscala/collection/Iterable;
    1171: getstatic     #419                // Field scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
    1174: invokevirtual #423                // Method scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
    1177: invokevirtual #1318               // Method scala/collection/immutable/List.$plus$plus$colon:(Lscala/collection/Traversable;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
    1180: checkcast     #398                // class scala/collection/immutable/List
    1183: astore        23
    1185: aload         11
    1187: aload         23
    1189: invokevirtual #1293               // Method scala/collection/immutable/List.$colon$colon$colon:(Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
    1192: aload         22
    1194: invokevirtual #1293               // Method scala/collection/immutable/List.$colon$colon$colon:(Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
    1197: aload         17
    1199: invokevirtual #1293               // Method scala/collection/immutable/List.$colon$colon$colon:(Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
    1202: invokespecial #1321               // Method scala/reflect/internal/Trees$Template."<init>":(Lscala/reflect/internal/SymbolTable;Lscala/collection/immutable/List;Lscala/reflect/internal/Trees$ValDef;Lscala/collection/immutable/List;)V
    1205: areturn
vjovanov commented 6 years ago

I use -XX:+PrintNMethodStatistics for seeing the total amount of generated code. To get assembly and size for an individual method I use -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,<qualified-class>.<method>

lrytz commented 6 years ago

On HotSpot, the Scala optimizer improved the Scala compiler performance around 5% last time I checked. It would be great if the benefit of the Scala optimizer was zero (or even negative) on Graal.