summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala12
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala13
2 files changed, 12 insertions, 13 deletions
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index bde7f7ac51..4836db5db0 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -10,10 +10,15 @@ package internal
import Flags._
trait Mirrors extends api.Mirrors {
- self: SymbolTable =>
+ thisUniverse: SymbolTable =>
override type Mirror >: Null <: RootsBase
+ // root symbols hold a strong reference to the enclosing mirror
+ // this prevents the mirror from being collected
+ // if there are any symbols created by that mirror
+ trait RootSymbol extends Symbol { def mirror: Mirror }
+
abstract class RootsBase(rootOwner: Symbol) extends MirrorOf[Mirrors.this.type] { thisMirror =>
protected[scala] def rootLoader: LazyType
@@ -70,7 +75,7 @@ trait Mirrors extends api.Mirrors {
protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = NoSymbol
- protected def universeMissingHook(owner: Symbol, name: Name): Symbol = self.missingHook(owner, name)
+ protected def universeMissingHook(owner: Symbol, name: Name): Symbol = thisUniverse.missingHook(owner, name)
private[scala] def missingHook(owner: Symbol, name: Name): Symbol = mirrorMissingHook(owner, name) orElse universeMissingHook(owner, name)
@@ -251,10 +256,11 @@ trait Mirrors extends api.Mirrors {
}
// Features common to RootClass and RootPackage, the roots of all
// type and term symbols respectively.
- sealed trait RootSymbol extends WellKnownSymbol {
+ sealed trait RootSymbol extends WellKnownSymbol with thisUniverse.RootSymbol {
final override def isRootSymbol = true
override def owner = rootOwner
override def typeOfThis = thisSym.tpe
+ def mirror = thisMirror.asInstanceOf[Mirror]
}
// This is the package _root_. The actual root cannot be referenced at
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 0d9e90d3a6..2f12ba59a2 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -1236,16 +1236,9 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive
override def scopeTransform(owner: Symbol)(op: => Scope): Scope =
if (owner.isPackageClass) owner.info.decls else op
- private lazy val rootToLoader = new WeakHashMap[Symbol, ClassLoader]
-
- override def mirrorThatLoaded(sym: Symbol): Mirror = {
- val root = sym.enclosingRootClass
- def findLoader = {
- val loaders = (mirrors collect { case (cl, ref) if ref.get.get.RootClass == root => cl })
- assert(loaders.nonEmpty, sym)
- loaders.head
- }
- mirrors(rootToLoader getOrElseUpdate(root, findLoader)).get.get
+ override def mirrorThatLoaded(sym: Symbol): Mirror = sym.enclosingRootClass match {
+ case root: RootSymbol => root.mirror
+ case _ => abort(s"${sym}.enclosingRootClass = ${sym.enclosingRootClass}, which is not a RootSymbol")
}
private lazy val syntheticCoreClasses: Map[(String, Name), Symbol] = {