diff options
author | Eugene Vigdorchik <eugene.vigdorchik@gmail.com> | 2013-04-04 15:37:16 +0400 |
---|---|---|
committer | Eugene Vigdorchik <eugene.vigdorchik@gmail.com> | 2013-04-04 15:41:21 +0400 |
commit | 0affa9423bf190137fadaf6513db0e0a515343af (patch) | |
tree | 84aa58411ce9c2482fb795f053fabe1ebaaa17c6 /src/compiler | |
parent | 7e1b88609935aceae36097a9f9ec95e5f7025ff7 (diff) | |
download | scala-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.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 28 |
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) } } |