Skip to content

Commit 8946d60

Browse files
committed
[backport] Fix bytecode stability when running the closure optimizer
Fixes the stability regression introduced by scala#4619.
1 parent 3b6b2bf commit 8946d60

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,24 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
7070
}
7171
}
7272

73-
// Group the closure instantiations by method allows running the ProdConsAnalyzer only once per method.
74-
// Also sort the instantiations: If there are multiple closure instantiations in a method, closure
75-
// invocations need to be re-written in a consistent order for bytecode stability. The local variable
76-
// slots for storing captured values depends on the order of rewriting.
73+
// Grouping the closure instantiations by method allows running the ProdConsAnalyzer only once per
74+
// method. Also sort the instantiations: If there are multiple closure instantiations in a method,
75+
// closure invocations need to be re-written in a consistent order for bytecode stability. The local
76+
// variable slots for storing captured values depends on the order of rewriting.
7777
val closureInstantiationsByMethod: Map[MethodNode, immutable.TreeSet[ClosureInstantiation]] = {
7878
closureInstantiations.values.groupBy(_.ownerMethod).mapValues(immutable.TreeSet.empty ++ _)
7979
}
8080

8181
// For each closure instantiation, a list of callsites of the closure that can be re-written
8282
// If a callsite cannot be rewritten, for example because the lambda body method is not accessible,
8383
// a warning is returned instead.
84-
val callsitesToRewrite: Map[ClosureInstantiation, List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]]] = {
85-
closureInstantiationsByMethod flatMap {
84+
val callsitesToRewrite: List[(ClosureInstantiation, List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]])] = {
85+
closureInstantiationsByMethod.iterator.flatMap({
8686
case (methodNode, closureInits) =>
8787
// A lazy val to ensure the analysis only runs if necessary (the value is passed by name to `closureCallsites`)
8888
lazy val prodCons = new ProdConsAnalyzer(methodNode, closureInits.head.ownerClass.internalName)
89-
closureInits.map(init => (init, closureCallsites(init, prodCons)))
90-
}
89+
closureInits.iterator.map(init => (init, closureCallsites(init, prodCons)))
90+
}).toList // mapping to a list (not a map) to keep the sorting of closureInstantiationsByMethod
9191
}
9292

9393
// Rewrite all closure callsites (or issue inliner warnings for those that cannot be rewritten)

0 commit comments

Comments
 (0)