Skip to content

improve push-pop to eliminate non-scala-function closures #162

Closed
@lrytz

Description

@lrytz

Example from https://issues.scala-lang.org/browse/SI-9515

class C {
  @inline final def foreachSAM[E <: AnyRef, U] (array: Array[E])(op: java.util.function.Consumer[E]) {
    var ii = 0 ; val max = array.length; while (ii < max) {
      op.accept(array(ii))
      ii += 1
    }
  }

  def testSAM (array: Array[String], prefix: String) {
    foreachSAM(array) { key =>
      println(prefix + key)
    }
  }
}

Things are optimized fine, but the closure is still allocated (and then immediately discarded)

  public testSAM([Ljava/lang/String;Ljava/lang/String;)V
...
    INVOKEDYNAMIC accept(Ljava/lang/String;)Ljava/util/function/Consumer; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)V, 
      // handle kind 0x6 : INVOKESTATIC
      C.$anonfun$testSAM$1(Ljava/lang/String;Ljava/lang/String;)V, 
      (Ljava/lang/String;)V, 
      3, 
      1, 
      Lscala/Serializable;.class, 
      0
    ]
    POP

ALSO: add some more test coverage for closure optimizations with non-scala-function sam types.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions