summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/runtime/JavaMirrors.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-03-01 09:33:55 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-01 09:33:55 -0800
commit0420b2d056f6a69f5d944482ba83d4fbee72cfab (patch)
tree8061c752f86485c5efb3106e8c346b35d5485451 /src/reflect/scala/reflect/runtime/JavaMirrors.scala
parent51a1eedab8d018a7c9da5663ed3945451dc6447c (diff)
downloadscala-0420b2d056f6a69f5d944482ba83d4fbee72cfab.tar.gz
scala-0420b2d056f6a69f5d944482ba83d4fbee72cfab.tar.bz2
scala-0420b2d056f6a69f5d944482ba83d4fbee72cfab.zip
Revert SI-6240 synchronization for runtime reflection
This commit reverts #2083: - 387b2590db runtime reflection: death from thousand threads - 73d079fb38 removes the assertion in missingHook - f4dd56ca5d synchronizes names - dd148de5a8 synchronizes pendingVolatiles - 4cbb9357c5 synchronizes toolboxes - 07bcb6176a SI-7045 reflection now auto-initializes selfType - bebd62d566 optimizes Scala reflection GIL - 735634f1d6 initializes lazy vals and inner objects in advance - 5b37cfb19a introduces GIL to Scala reflection - 981da8edfc cleans up initialization of runtime reflection - b2c2493b22 reflection no longer uses atPhase and friends - a9dca512d8 synchronizes symbols - 0262941b3c removes the crazy extraneous log - 21d5d3820b moves Symbol#SymbolKind to Symbols
Diffstat (limited to 'src/reflect/scala/reflect/runtime/JavaMirrors.scala')
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala68
1 files changed, 33 insertions, 35 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 58ade961a7..778c826dc0 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -24,9 +24,9 @@ import scala.language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
import scala.reflect.internal.util.Collections._
-private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
+private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUniverse: SymbolTable =>
- lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()
+ private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()
private def createMirror(owner: Symbol, cl: ClassLoader): Mirror = {
val jm = new JavaMirror(owner, cl)
@@ -46,11 +46,19 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
trait JavaClassCompleter extends FlagAssigningCompleter
- def runtimeMirror(cl: ClassLoader): Mirror = gilSynchronized {
- mirrors get cl match {
- case Some(WeakReference(m)) => m
- case _ => createMirror(rootMirror.RootClass, cl)
- }
+ def init() = {
+ definitions.AnyValClass // force it.
+
+ // establish root association to avoid cyclic dependency errors later
+ rootMirror.classToScala(classOf[java.lang.Object]).initialize
+
+ // println("initializing definitions")
+ definitions.init()
+ }
+
+ def runtimeMirror(cl: ClassLoader): Mirror = mirrors get cl match {
+ case Some(WeakReference(m)) => m
+ case _ => createMirror(rootMirror.RootClass, cl)
}
/** The API of a mirror for a reflective universe */
@@ -63,23 +71,6 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
import definitions._
- override lazy val RootPackage = new RootPackage with SynchronizedTermSymbol
- override lazy val RootClass = new RootClass with SynchronizedModuleClassSymbol
- override lazy val EmptyPackage = new EmptyPackage with SynchronizedTermSymbol
- override lazy val EmptyPackageClass = new EmptyPackageClass with SynchronizedModuleClassSymbol
-
- override def init() = {
- super.init()
-
- // see an explanation of this in JavaUniverse.init()
- RootPackage
- RootClass
- EmptyPackage
- EmptyPackageClass
- unpickler
- rootLoader
- }
-
/** The lazy type for root.
*/
override lazy val rootLoader = new LazyType with FlagAgnosticCompleter {
@@ -676,7 +667,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
completeRest()
}
- def completeRest(): Unit = gilSynchronized {
+ def completeRest(): Unit = thisUniverse.synchronized {
val tparams = clazz.rawInfo.typeParams
val parents = try {
@@ -892,7 +883,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
* The Scala package with given fully qualified name. Unlike `packageNameToScala`,
* this one bypasses the cache.
*/
- private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = gilSynchronized {
+ private[JavaMirrors] def makeScalaPackage(fullname: String): ModuleSymbol = {
val split = fullname lastIndexOf '.'
val ownerModule: ModuleSymbol =
if (split > 0) packageNameToScala(fullname take split) else this.RootPackage
@@ -1255,6 +1246,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
case _ => abort(s"${sym}.enclosingRootClass = ${sym.enclosingRootClass}, which is not a RootSymbol")
}
+ private lazy val syntheticCoreClasses: Map[(String, Name), Symbol] = {
+ def mapEntry(sym: Symbol): ((String, Name), Symbol) = (sym.owner.fullName, sym.name) -> sym
+ Map() ++ (definitions.syntheticCoreClasses map mapEntry)
+ }
+
/** 1. If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
* <owner>.<name>, otherwise return NoSymbol.
* Exception: If owner is root and a java class with given name exists, create symbol in empty package instead
@@ -1264,20 +1260,22 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
override def missingHook(owner: Symbol, name: Name): Symbol = {
if (owner.hasPackageFlag) {
val mirror = mirrorThatLoaded(owner)
+ // todo. this makes toolbox tests pass, but it's a mere workaround for SI-5865
+// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name")
if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined)
return mirror.EmptyPackageClass.info decl name
if (name.isTermName && !owner.isEmptyPackageClass)
return mirror.makeScalaPackage(
if (owner.isRootSymbol) name.toString else owner.fullName+"."+name)
- if (name == tpnme.AnyRef && owner.owner.isRoot && owner.name == tpnme.scala_)
- // when we synthesize the scala.AnyRef symbol, we need to add it to the scope of the scala package
- // the problem is that adding to the scope implies doing something like `owner.info.decls enter anyRef`
- // which entails running a completer for the scala package
- // which will try to unpickle the stuff in scala/package.class
- // which will transitively load scala.AnyRef
- // which doesn't exist yet, because it hasn't been added to the scope yet
- // this missing hook ties the knot without introducing synchronization problems like before
- return definitions.AnyRefClass
+ syntheticCoreClasses get (owner.fullName, name) match {
+ case Some(tsym) =>
+ // synthetic core classes are only present in root mirrors
+ // because Definitions.scala, which initializes and enters them, only affects rootMirror
+ // therefore we need to enter them manually for non-root mirrors
+ if (mirror ne thisUniverse.rootMirror) owner.info.decls enter tsym
+ return tsym
+ case None =>
+ }
}
info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
super.missingHook(owner, name)