diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-16 14:17:46 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-07-23 15:02:25 +0200 |
commit | 8946d60bd27a021591818defb6b4f82ab014d4d0 (patch) | |
tree | 9b6d21876c7fe5e0d01d5b91d2c22570981708d4 | |
parent | 3b6b2bfe9fdd7995bf9f90a5fafc30613a101179 (diff) | |
download | scala-8946d60bd27a021591818defb6b4f82ab014d4d0.tar.gz scala-8946d60bd27a021591818defb6b4f82ab014d4d0.tar.bz2 scala-8946d60bd27a021591818defb6b4f82ab014d4d0.zip |
[backport] Fix bytecode stability when running the closure optimizer
Fixes the stability regression introduced by #4619.
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index 58f0813bd8..92b9b34006 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -70,10 +70,10 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { } } - // Group the closure instantiations by method allows running the ProdConsAnalyzer only once per method. - // Also sort the instantiations: If there are multiple closure instantiations in a method, closure - // invocations need to be re-written in a consistent order for bytecode stability. The local variable - // slots for storing captured values depends on the order of rewriting. + // Grouping the closure instantiations by method allows running the ProdConsAnalyzer only once per + // method. Also sort the instantiations: If there are multiple closure instantiations in a method, + // closure invocations need to be re-written in a consistent order for bytecode stability. The local + // variable slots for storing captured values depends on the order of rewriting. val closureInstantiationsByMethod: Map[MethodNode, immutable.TreeSet[ClosureInstantiation]] = { closureInstantiations.values.groupBy(_.ownerMethod).mapValues(immutable.TreeSet.empty ++ _) } @@ -81,13 +81,13 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { // For each closure instantiation, a list of callsites of the closure that can be re-written // If a callsite cannot be rewritten, for example because the lambda body method is not accessible, // a warning is returned instead. - val callsitesToRewrite: Map[ClosureInstantiation, List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]]] = { - closureInstantiationsByMethod flatMap { + val callsitesToRewrite: List[(ClosureInstantiation, List[Either[RewriteClosureApplyToClosureBodyFailed, (MethodInsnNode, Int)]])] = { + closureInstantiationsByMethod.iterator.flatMap({ case (methodNode, closureInits) => // A lazy val to ensure the analysis only runs if necessary (the value is passed by name to `closureCallsites`) lazy val prodCons = new ProdConsAnalyzer(methodNode, closureInits.head.ownerClass.internalName) - closureInits.map(init => (init, closureCallsites(init, prodCons))) - } + closureInits.iterator.map(init => (init, closureCallsites(init, prodCons))) + }).toList // mapping to a list (not a map) to keep the sorting of closureInstantiationsByMethod } // Rewrite all closure callsites (or issue inliner warnings for those that cannot be rewritten) |