From 6f05acaa43d8aa036e26f68937e71dbae60bb5b4 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 9 Feb 2014 18:41:16 +0100 Subject: Optimization: use AnyRef map for Namer -> Typer tree handoff And uses a map per-compilation unit, rather than one per Typer. One small change required: we now need to clear this map in the the interactive compiler which reuses compilation units, rather than in the call to `Typer#reset`. --- src/compiler/scala/tools/nsc/CompilationUnits.scala | 5 +++++ src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Namers.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 7 ++++--- 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index df5952a4cf..c2caed70a0 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -98,6 +98,11 @@ trait CompilationUnits { global: Global => override def toString = map.toString } + // namer calls typer.computeType(rhs) on DefDef / ValDef when tpt is empty. the result + // is cached here and re-used in typedDefDef / typedValDef + // Also used to cache imports type-checked by namer. + val transformed = new mutable.AnyRefMap[Tree, Tree] + /** things to check at end of compilation unit */ val toCheck = new ListBuffer[() => Unit] diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index ec2b7d49f5..ba183fe3e6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -427,7 +427,7 @@ trait MethodSynthesis { override def derivedSym = basisSym.lazyAccessor override def derivedTree: DefDef = { val ValDef(_, _, tpt0, rhs0) = tree - val rhs1 = transformed.getOrElse(rhs0, rhs0) + val rhs1 = context.unit.transformed.getOrElse(rhs0, rhs0) val body = ( if (tree.symbol.owner.isTrait || hasUnitType(basisSym)) rhs1 else gen.mkAssignAndReturn(basisSym, rhs1) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 645f267a21..2f2ecb90fa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1413,7 +1413,7 @@ trait Namers extends MethodSynthesis { val newImport = treeCopy.Import(imp, expr1, selectors).asInstanceOf[Import] checkSelectors(newImport) - transformed(imp) = newImport + context.unit.transformed(imp) = newImport // copy symbol and type attributes back into old expression // so that the structure builder will find it. expr setSymbol expr1.symbol setType expr1.tpe diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 101e1526fe..074f8df303 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -13,7 +13,7 @@ package scala package tools.nsc package typechecker -import scala.collection.{ mutable, immutable } +import scala.collection.{mutable, immutable} import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance } import mutable.ListBuffer import symtab.Flags._ @@ -39,7 +39,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // namer calls typer.computeType(rhs) on DefDef / ValDef when tpt is empty. the result // is cached here and re-used in typedDefDef / typedValDef // Also used to cache imports type-checked by namer. - val transformed = new mutable.HashMap[Tree, Tree] + val transformed = new mutable.AnyRefMap[Tree, Tree] final val shortenImports = false @@ -52,7 +52,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper //println("resetTyper called") resetContexts() resetImplicits() - transformed.clear() resetDocComments() } @@ -108,6 +107,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val runDefinitions = currentRun.runDefinitions import runDefinitions._ + private val transformed: mutable.Map[Tree, Tree] = unit.transformed + val infer = new Inferencer(context0) { // See SI-3281 re undoLog override def isCoercible(tp: Type, pt: Type) = undoLog undo viewExists(tp, pt) -- cgit v1.2.3 From 7957f63caa7c50593e428a46e991708c6465f354 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 9 Feb 2014 19:01:35 +0100 Subject: Optimation: use AnyRefMap in GenASM javaName caches These are a hotspot in the backend. --- src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 4 ++-- src/reflect/scala/reflect/internal/SymbolTable.scala | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index eb40e1dbde..b03519ce7d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -171,10 +171,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { var pickledBytes = 0 // statistics - val javaNameCache = perRunCaches.newMap[Symbol, Name]() + val javaNameCache = perRunCaches.newAnyRefMap[Symbol, Name]() // unlike javaNameCache, reverseJavaName contains entries only for class symbols and their internal names. - val reverseJavaName = perRunCaches.newMap[String, Symbol]() + val reverseJavaName = perRunCaches.newAnyRefMap[String, Symbol]() private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _) private def hasPublicBitSet(flags: Int) = (flags & asm.Opcodes.ACC_PUBLIC) != 0 diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 571c4cfa5d..802bd18a4e 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -371,6 +371,8 @@ abstract class SymbolTable extends macros.Universe def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) def newSet[K]() = recordCache(mutable.HashSet[K]()) def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]()) + + def newAnyRefMap[K <: AnyRef, V]() = recordCache(mutable.AnyRefMap[K, V]()) def newGeneric[T](f: => T): () => T = { val NoCached: T = null.asInstanceOf[T] var cached: T = NoCached -- cgit v1.2.3