The way UnCurry lowers closures, lexical capture results in bytecode performing chains of "heap-hops", e.g. to reach out to C's field from a closure class nested in another:
class C {
var cfield = 0
def pqr(args: List[Int]) {
for (i <- 1 to 10; j <- 11 to 20) {
cfield = i + j + args.size
}
}
}
The innermost appply() receives just one stack-argument, the rest is reached via dot navigation:
def apply$mcVI$sp(v1: Int): Unit =
C$$anonfun$pqr$1$$anonfun$apply$mcVI$sp$1.this.$outer.C$$anonfun$$$outer().cfield_=(
C$$anonfun$pqr$1$$anonfun$apply$mcVI$sp$1.this.v1$1 +
v1 +
C$$anonfun$pqr$1$$anonfun$apply$mcVI$sp$1.this.$outer.args$2.size()
);
An alternative approachUnCurry could instead lower as shown below, forcing the invoker to perform navigation (once), such that the callee need access only local vars in "closure methods", much like a MethodHandle would allow:
class C {
var cfield = 0
def abc(args: List[Int]) {
def closuA(i: Int) {
def closuB(j: Int) { cfield = i + j + args.size }
(11 to 20) foreach { j => closuB(j) }
}
(1 to 10) foreach { i => closuA(i) }
}
}
In this case, the innermost apply() receives "flattend" (scalarified) all the arguments it needs:
final def C$$closuB$1(j: Int, args$1: List, i$1: Int): Unit = C.this.cfield_=(i$1.+(j).+(args$1.size()));
Should run faster.
It's true that, until Closure Elimination kicks in, the anon-closure-classes still remain as middlemen. The invoker of the method above is hosted in one such middleman, and thus needs to perform "heap-access" as shown below. However, it's on THIS only, and thus should be on the cache already:
<specialized> def apply$mcVI$sp(v1: Int): Unit =
C$$anonfun$C$$closuA$1$1.this.$outer.C$$closuB$1(v1, C$$anonfun$C$$closuA$1$1.this.args$1, C$$anonfun$C$$closuA$1$1.this.i$1);
I don't see any disadvantages, and moreover this lowering would give the JIT compiler an easier time (a) kicking in earlier (if only because of smaller code size); and (b) optimization opportunities (local-vars accesses are easier to optimize than heap-navigation).
Miguel
http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/