diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-01-12 13:24:13 -0800 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2014-01-12 13:24:13 -0800 |
commit | 40df7c7b337dc475e5aa3df23c992b648dd37ef6 (patch) | |
tree | 794a7c50af0655569f47544e0b6334ef356f283b /src | |
parent | c0ff1700e060b23eddd75712686d93255c8be1ca (diff) | |
parent | 00e11ffdd45a7be544b1566bf21cd4396381750e (diff) | |
download | scala-40df7c7b337dc475e5aa3df23c992b648dd37ef6.tar.gz scala-40df7c7b337dc475e5aa3df23c992b648dd37ef6.tar.bz2 scala-40df7c7b337dc475e5aa3df23c992b648dd37ef6.zip |
Merge pull request #3346 from retronym/ticket/8129
SI-8129 Plug a leak in perRunCaches
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/internal/SymbolTable.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 7 |
2 files changed, 12 insertions, 7 deletions
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index c46a559d6d..bed8310767 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -356,16 +356,18 @@ abstract class SymbolTable extends macros.Universe // Weak references so the garbage collector will take care of // letting us know when a cache is really out of commission. - private val caches = WeakHashSet[Clearable]() + import java.lang.ref.WeakReference + private var caches = List[WeakReference[Clearable]]() def recordCache[T <: Clearable](cache: T): T = { - caches += cache + caches ::= new WeakReference(cache) cache } def clearAll() = { debuglog("Clearing " + caches.size + " caches.") - caches foreach (_.clear) + caches foreach (ref => Option(ref.get).foreach(_.clear)) + caches = caches.filterNot(_.get == null) } def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) @@ -376,9 +378,9 @@ abstract class SymbolTable extends macros.Universe val NoCached: T = null.asInstanceOf[T] var cached: T = NoCached var cachedRunId = NoRunId - caches += new Clearable { + recordCache(new Clearable { def clear(): Unit = cached = NoCached - } + }) () => { if (currentRunId != cachedRunId || cached == NoCached) { cached = f diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 99e6ae633f..d8bbd981b9 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -8,7 +8,6 @@ package reflect package internal import scala.collection.{ mutable, immutable, generic } -import generic.Clearable import scala.ref.WeakReference import mutable.ListBuffer import Flags._ @@ -3660,7 +3659,11 @@ trait Types if (Statistics.canEnable) Statistics.incCounter(rawTypeCount) if (uniqueRunId != currentRunId) { uniques = util.WeakHashSet[Type](initialUniquesCapacity) - perRunCaches.recordCache(uniques) + // JZ: We used to register this as a perRunCache so it would be cleared eagerly at + // the end of the compilation run. But, that facility didn't actually clear this map (SI-8129)! + // When i fixed that bug, run/tpeCache-tyconCache.scala started failing. Why was that? + // I've removed the registration for now. I don't think its particularly harmful anymore + // as a) this is now a weak set, and b) it is discarded completely before the next run. uniqueRunId = currentRunId } (uniques findEntryOrUpdate tp).asInstanceOf[T] |