From 0420b2d056f6a69f5d944482ba83d4fbee72cfab Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 1 Mar 2013 09:33:55 -0800 Subject: 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 --- .../scala/reflect/runtime/JavaMirrors.scala | 68 +++++++++++----------- 1 file changed, 33 insertions(+), 35 deletions(-) (limited to 'src/reflect/scala/reflect/runtime/JavaMirrors.scala') 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 * ., 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) -- cgit v1.2.3