diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-09-23 18:58:50 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-09-24 14:28:58 +0200 |
commit | 291d1f033a790e97298210de29f09a9796406ae3 (patch) | |
tree | 4e3e6d564f1e3c7877fa512d867389eddc2fab16 /src/reflect | |
parent | 6ba05fdf09e8ff81dda1b946d9f89b2bba9ad33b (diff) | |
download | scala-291d1f033a790e97298210de29f09a9796406ae3.tar.gz scala-291d1f033a790e97298210de29f09a9796406ae3.tar.bz2 scala-291d1f033a790e97298210de29f09a9796406ae3.zip |
SI-6412 fixes leaks in Types.uniques
This is the most blatant leak in reflection. There are others, but their impact
is much smaller, therefore we'll fix them later, after 2.10.0-final.
For more information, see https://issues.scala-lang.org/browse/SI-6412 and
http://groups.google.com/group/scala-internals/browse_thread/thread/eabcf3d406dab8b2
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/runtime/SynchronizedTypes.scala | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala index de029ca658..b9b140a2fd 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala @@ -1,6 +1,9 @@ package scala.reflect package runtime +import scala.collection.mutable.WeakHashMap +import java.lang.ref.WeakReference + /** This trait overrides methods in reflect.internal, bracketing * them in synchronized { ... } to make them thread-safe */ @@ -11,7 +14,26 @@ trait SynchronizedTypes extends internal.Types { self: SymbolTable => private object uniqueLock - override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { super.unique(tp) } + private val uniques = WeakHashMap[Type, WeakReference[Type]]() + override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { + // we need to have weak uniques for runtime reflection + // because unlike the normal compiler universe, reflective universe isn't organized in runs + // therefore perRunCaches can grow infinitely large + // + // despite that toolbox universes are decorated, toolboxes are compilers, + // i.e. they have their caches cleaned up automatically on per-run basis, + // therefore they should use vanilla uniques, which are faster + if (!isCompilerUniverse) { + val result = if (uniques contains tp) uniques(tp).get else null + if (result ne null) result.asInstanceOf[T] + else { + uniques(tp) = new WeakReference(tp) + tp + } + } else { + super.unique(tp) + } + } class SynchronizedUndoLog extends UndoLog { private val actualLock = new java.util.concurrent.locks.ReentrantLock |