summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Vigdorchik <eugene.vigdorchik@gmail.com>2013-04-04 15:37:16 +0400
committerEugene Vigdorchik <eugene.vigdorchik@gmail.com>2013-04-04 15:41:21 +0400
commit0affa9423bf190137fadaf6513db0e0a515343af (patch)
tree84aa58411ce9c2482fb795f053fabe1ebaaa17c6
parent7e1b88609935aceae36097a9f9ec95e5f7025ff7 (diff)
downloadscala-0affa9423bf190137fadaf6513db0e0a515343af.tar.gz
scala-0affa9423bf190137fadaf6513db0e0a515343af.tar.bz2
scala-0affa9423bf190137fadaf6513db0e0a515343af.zip
SI-7321 Memory leak in specialize on multiple compiler runs.
Currently the map is declared LinkedHashMap, which doesn't align with other caching maps that are cleared on every run. Linkedness is only needed to ensure deterministic order on the generated specialized classes. The same can be accomplished by sorting generated classes a-posteriori.
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala28
1 files changed, 12 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 232148676c..a71920f787 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -78,7 +78,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
/** For a given class and concrete type arguments, give its specialized class */
- val specializedClass: mutable.Map[(Symbol, TypeEnv), Symbol] = new mutable.LinkedHashMap
+ val specializedClass = perRunCaches.newMap[(Symbol, TypeEnv), Symbol]
/** Map a method symbol to a list of its specialized overloads in the same class. */
private val overloads = perRunCaches.newMap[Symbol, List[Overload]]() withDefaultValue Nil
@@ -1776,21 +1776,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Create specialized class definitions */
def implSpecClasses(trees: List[Tree]): List[Tree] = {
- val buf = new mutable.ListBuffer[Tree]
- for (tree <- trees)
- tree match {
- case ClassDef(_, _, _, impl) =>
- tree.symbol.info // force specialization
- for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) {
- val parents = specCls.info.parents.map(TypeTree)
- buf +=
- ClassDef(specCls, atPos(impl.pos)(Template(parents, emptyValDef, List()))
- .setSymbol(specCls.newLocalDummy(sym1.pos))) setPos tree.pos
- debuglog("created synthetic class: " + specCls + " of " + sym1 + " in " + pp(env))
- }
- case _ =>
- }
- buf.toList
+ trees flatMap {
+ case tree @ ClassDef(_, _, _, impl) =>
+ tree.symbol.info // force specialization
+ for (((sym1, env), specCls) <- specializedClass if sym1 == tree.symbol) yield {
+ debuglog("created synthetic class: " + specCls + " of " + sym1 + " in " + pp(env))
+ val parents = specCls.info.parents.map(TypeTree)
+ ClassDef(specCls, atPos(impl.pos)(Template(parents, emptyValDef, List()))
+ .setSymbol(specCls.newLocalDummy(sym1.pos))) setPos tree.pos
+ }
+ case _ => Nil
+ } sortBy (_.name.decoded)
}
}