diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-14 01:27:04 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-14 01:27:04 +0000 |
commit | 733669230a470b60c2ecc92c666f0871cecf22ef (patch) | |
tree | 70ee5f0e49e348e317bfd9db5d2230b433dada31 /src/compiler/scala | |
parent | 5e49b4181976f20d28625008a775223dbf8e7f6e (diff) | |
download | scala-733669230a470b60c2ecc92c666f0871cecf22ef.tar.gz scala-733669230a470b60c2ecc92c666f0871cecf22ef.tar.bz2 scala-733669230a470b60c2ecc92c666f0871cecf22ef.zip |
Adding some Sets/Maps to perRunCaches, and elim...
Adding some Sets/Maps to perRunCaches, and eliminating ambiguously named
imports.
Did a tour of the compiler adding a few longer-lived mutable structures
to the per-run cache clearing mechanism. Some of these were not a big
threat, but there is (almost) literally no cost to tracking them and the
fewer mutable structures which are created "lone wolf style" the easier
it is to spot the one playing by his own rules.
While I was at it I followed through on long held ambition to eliminate
the importing of highly ambiguous names like "Map" and "HashSet" from
the mutable and immutable packages. I didn't quite manage elimination
but it's pretty close. Something potentially as pernicious which I
didn't do much about is this import:
import scala.collection._
Imagine coming across that one on lines 407 and 474 of a 1271 file.
That's not cool. Some poor future programmer will be on line 1100 and
use "Map[A, B]" in some function and only after the product has shipped
will it be discovered that the signature is wrong and the rocket will
now be crashing into the mountainside straightaway. No review.
Diffstat (limited to 'src/compiler/scala')
51 files changed, 169 insertions, 190 deletions
diff --git a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala index bb342cf0e1..38277b5a09 100644 --- a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala +++ b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala @@ -6,7 +6,7 @@ package scala.reflect package internal // todo implement in terms of BitSet -import scala.collection.mutable.{ListBuffer, BitSet} +import scala.collection.{ mutable, immutable } import math.max import util.Statistics._ @@ -41,7 +41,7 @@ trait BaseTypeSeqs { // (while NoType is in there to indicate a cycle in this BTS, during the execution of // the mergePrefixAndArgs below, the elems get copied without the pending map, // so that NoType's are seen instead of the original type --> spurious compile error) - val pending = new BitSet(length) + val pending = new mutable.BitSet(length) /** The type at i'th position in this sequence; lazy types are returned evaluated. */ def apply(i: Int): Type = @@ -187,7 +187,7 @@ trait BaseTypeSeqs { val tsym = tp.typeSymbol val parents = tp.parents // Console.println("computing baseTypeSeq of " + tsym.tpe + " " + parents)//DEBUG - val buf = new ListBuffer[Type] + val buf = new mutable.ListBuffer[Type] buf += tsym.tpe var btsSize = 1 if (parents.nonEmpty) { diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 71eb471992..500a5cb428 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -7,7 +7,6 @@ package scala.reflect package internal import scala.collection.{ mutable, immutable } -import scala.collection.mutable.{ HashMap } import Flags._ import PartialFunction._ @@ -503,7 +502,7 @@ trait Definitions extends reflect.api.StandardDefinitions { var Delegate_scalaCallers: List[Symbol] = List() // Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType) // var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _ - lazy val Delegate_scalaCallerTargets: HashMap[Symbol, Symbol] = new HashMap() + lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap() def isCorrespondingDelegate(delegateType: Type, functionType: Type): Boolean = { isSubType(delegateType, DelegateClass.tpe) && diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index ca2b5867ce..32fa88ac15 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -116,6 +116,9 @@ abstract class SymbolTable extends api.Universe object perRunCaches { import java.lang.ref.WeakReference + import scala.tools.util.Signallable + import scala.runtime.ScalaRunTime.stringOf + // We can allow ourselves a structural type, these methods // amount to a few calls per run at most. This does suggest @@ -128,6 +131,25 @@ abstract class SymbolTable extends api.Universe // letting us know when a cache is really out of commission. private val caches = mutable.HashSet[WeakReference[Clearable]]() + private def dumpCaches() { + println(caches.size + " structures are in perRunCaches.") + caches.zipWithIndex foreach { case (ref, index) => + val cache = ref.get() + println("(" + index + ")" + ( + if (cache == null) " has been collected." + else " has " + cache.size + " entries:\n" + stringOf(cache) + )) + } + } + if (settings.debug.value) { + println(Signallable("dump compiler caches")(dumpCaches())) + } + + def recordCache[T <: Clearable](cache: T): T = { + caches += new WeakReference(cache) + cache + } + def clearAll() = { if (settings.debug.value) { val size = caches flatMap (ref => Option(ref.get)) map (_.size) sum; @@ -142,8 +164,9 @@ abstract class SymbolTable extends api.Universe } } - def newMap[K, V]() = { val m = mutable.HashMap[K, V]() ; caches += new WeakReference(m) ; m } - def newSet[K]() = { val s = mutable.HashSet[K]() ; caches += new WeakReference(s) ; s } + def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) + def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) + def newSet[K]() = recordCache(mutable.HashSet[K]()) } /** Break into repl debugger if assertion is true. */ diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala index abbe8390a6..afb56d9999 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -7,7 +7,6 @@ package scala.reflect package internal import Flags._ -import util.HashSet /** This class ... * diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index 70d28d8402..ef80b5d479 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -6,13 +6,10 @@ package scala.reflect package internal -import java.io.{PrintWriter, StringWriter} -import scala.collection.mutable.ListBuffer +import java.io.{ PrintWriter, StringWriter } import Flags._ import api.Modifier -//import scala.tools.nsc.util.{ FreshNameCreator, HashSet, SourceFile } - trait Trees extends api.Trees { self: SymbolTable => // --- modifiers implementation --------------------------------------- diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index bb5608917b..34150069ad 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -9,8 +9,6 @@ package internal import scala.collection.{ mutable, immutable } import scala.ref.WeakReference import mutable.ListBuffer -//import ast.TreeGen -//import util.{ Position, NoPosition } import Flags._ import scala.util.control.ControlThrowable import scala.annotation.tailrec @@ -105,6 +103,9 @@ trait Types extends api.Types { self: SymbolTable => private type UndoLog = List[(TypeVar, TypeConstraint)] private[scala] var log: UndoLog = List() + // register with the auto-clearing cache manager + perRunCaches.recordCache(this) + /** Undo all changes to constraints to type variables upto `limit`. */ private def undoTo(limit: UndoLog) { while ((log ne limit) && log.nonEmpty) { @@ -123,6 +124,7 @@ trait Types extends api.Types { self: SymbolTable => log = Nil } + def size = log.size // `block` should not affect constraints on typevars def undo[T](block: => T): T = { @@ -149,7 +151,7 @@ trait Types extends api.Types { self: SymbolTable => * It makes use of the fact that these two operations depend only on the parents, * not on the refinement. */ - val intersectionWitness = new mutable.WeakHashMap[List[Type], WeakReference[Type]] + val intersectionWitness = perRunCaches.newWeakMap[List[Type], WeakReference[Type]]() //private object gen extends { // val global : Types.this.type = Types.this diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index 1f54edbdc5..6d0b22ac05 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -13,7 +13,8 @@ import java.lang.Double.longBitsToDouble import Flags._ import PickleFormat._ -import collection.mutable.{HashMap, ListBuffer} +import scala.collection.{ mutable, immutable } +import collection.mutable.ListBuffer import annotation.switch /** @author Martin Odersky @@ -57,7 +58,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { private val entries = new Array[AnyRef](index.length) /** A map from symbols to their associated `decls` scopes */ - private val symScopes = new HashMap[Symbol, Scope] + private val symScopes = mutable.HashMap[Symbol, Scope]() //println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug diff --git a/src/compiler/scala/reflect/runtime/JavaConversions.scala b/src/compiler/scala/reflect/runtime/JavaConversions.scala index 8860c18845..b724292836 100644 --- a/src/compiler/scala/reflect/runtime/JavaConversions.scala +++ b/src/compiler/scala/reflect/runtime/JavaConversions.scala @@ -8,7 +8,7 @@ import java.lang.reflect.{ import internal.ByteCodecs import internal.ClassfileConstants._ import internal.pickling.UnPickler -import collection.mutable.HashMap +import scala.collection.{ mutable, immutable } trait JavaConversions { self: Universe => @@ -17,8 +17,8 @@ trait JavaConversions { self: Universe => } class TwoWayCache[J, S] { - val toScalaMap = new HashMap[J, S] - val toJavaMap = new HashMap[S, J] + val toScalaMap = mutable.HashMap[J, S]() + val toJavaMap = mutable.HashMap[S, J]() def toScala(key: J)(body: => S) = toScalaMap.getOrElseUpdate(key, body) def toJava(key: S)(body: => J) = toJavaMap.getOrElseUpdate(key, body) diff --git a/src/compiler/scala/tools/ant/ScalaBazaar.scala b/src/compiler/scala/tools/ant/ScalaBazaar.scala index f25e4d6a25..af2b5e1a12 100644 --- a/src/compiler/scala/tools/ant/ScalaBazaar.scala +++ b/src/compiler/scala/tools/ant/ScalaBazaar.scala @@ -11,7 +11,7 @@ package scala.tools.ant { import scala.collection.DefaultMap - import scala.collection.mutable.HashMap + import scala.collection.{ mutable, immutable } import java.io.{File, FileInputStream, FileOutputStream, FileWriter, StringReader} import java.net.URL @@ -78,7 +78,7 @@ package scala.tools.ant { /** The sets of files to include in the package */ private object fileSetsMap extends DefaultMap[String, List[FileSet]] { - private var content = new HashMap[String, List[FileSet]]() + private var content = new mutable.HashMap[String, List[FileSet]]() def get(key: String): Option[List[FileSet]] = content.get(key) override def size: Int = content.size def update(key: String, value: FileSet) { diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index e5ee0b214a..aba17ca290 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -6,7 +6,8 @@ package scala.tools.nsc import util.{ FreshNameCreator,Position,NoPosition,SourceFile } -import scala.collection.mutable.{ LinkedHashSet, HashSet, HashMap, ListBuffer } +import scala.collection.mutable +import scala.collection.mutable.{ LinkedHashSet, ListBuffer } trait CompilationUnits { self: Global => @@ -37,15 +38,15 @@ trait CompilationUnits { self: Global => /** Note: depends now contains toplevel classes. * To get their sourcefiles, you need to dereference with .sourcefile */ - val depends = new HashSet[Symbol] + val depends = mutable.HashSet[Symbol]() /** so we can relink */ - val defined = new HashSet[Symbol] + val defined = mutable.HashSet[Symbol]() /** Synthetic definitions generated by namer, eliminated by typer. */ - val synthetics = new HashMap[Symbol, Tree] + val synthetics = mutable.HashMap[Symbol, Tree]() /** things to check at end of compilation unit */ val toCheck = new ListBuffer[() => Unit] @@ -92,8 +93,8 @@ trait CompilationUnits { self: Global => def clear() { fresh = null body = null - depends.clear - defined.clear + depends.clear() + defined.clear() } } } diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 1148b4de28..9c598bca41 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -11,7 +11,7 @@ import reporters.Reporter import util.{Position, NoPosition} import util.DocStrings._ import scala.reflect.internal.Chars._ -import scala.collection.mutable.{HashMap, ListBuffer, StringBuilder} +import scala.collection.mutable /* * @author Martin Odersky @@ -22,7 +22,7 @@ trait DocComments { self: Global => def reporter: Reporter /** The raw doc comment map */ - val docComments = new HashMap[Symbol, DocComment] + val docComments = mutable.HashMap[Symbol, DocComment]() /** Associate comment with symbol `sym` at position `pos`. */ def docComment(sym: Symbol, docStr: String, pos: Position = NoPosition) = @@ -204,9 +204,7 @@ trait DocComments { self: Global => /** Maps symbols to the variable -> replacement maps that are defined * in their doc comments */ - private val defs = new HashMap[Symbol, Map[String, String]] { - override def default(key: Symbol) = Map() - } + private val defs = mutable.HashMap[Symbol, Map[String, String]]() withDefaultValue Map() /** Lookup definition of variable. * diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index bc8ec07ebc..b16b3c89a0 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -8,7 +8,6 @@ package ast import reflect.internal.Flags._ import symtab._ -import util.HashSet /** This class ... * diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 42a4698793..346cc10393 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -14,8 +14,6 @@ import scala.reflect.internal.Flags.PARAMACCESSOR import scala.reflect.internal.Flags.PRESUPER import scala.reflect.internal.Flags.TRAIT -import util.HashSet - trait Trees extends reflect.internal.Trees { self: Global => // --- additional cases -------------------------------------------------------- @@ -267,7 +265,7 @@ trait Trees extends reflect.internal.Trees { self: Global => } private class ResetLocalAttrsTraverser extends ResetAttrsTraverser { - private val erasedSyms = HashSet[Symbol](8) + private val erasedSyms = util.HashSet[Symbol](8) override protected def isLocal(sym: Symbol) = erasedSyms(sym) override protected def resetDef(tree: Tree) { erasedSyms addEntry tree.symbol diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 2cc2b598d3..ff10268591 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -7,7 +7,7 @@ package scala.tools.nsc package ast.parser import scala.collection.mutable -import mutable.{ Buffer, ArrayBuffer, ListBuffer, HashMap } +import mutable.{ Buffer, ArrayBuffer, ListBuffer } import scala.util.control.ControlThrowable import scala.tools.nsc.util.{SourceFile,CharArrayReader} import scala.xml.{ Text, TextBuffer } @@ -113,7 +113,7 @@ trait MarkupParsers { * | `{` scalablock `}` */ def xAttributes = { - val aMap = new HashMap[String, Tree]() + val aMap = mutable.HashMap[String, Tree]() while (isNameStart(ch)) { val start = curOffset diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index e58f81b3c5..2c10df1c05 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -1796,7 +1796,7 @@ abstract class GenICode extends SubComponent { * to delay it any more: they will be used at some point. */ class DuplicateLabels(boundLabels: Set[Symbol]) extends Transformer { - val labels: mutable.Map[Symbol, Symbol] = new mutable.HashMap + val labels = perRunCaches.newMap[Symbol, Symbol]() var method: Symbol = _ var ctx: Context = _ @@ -1873,7 +1873,7 @@ abstract class GenICode extends SubComponent { var bb: BasicBlock = _ /** Map from label symbols to label objects. */ - var labels = mutable.HashMap[Symbol, Label]() + var labels = perRunCaches.newMap[Symbol, Label]() /** Current method definition. */ var defdef: DefDef = _ @@ -1977,7 +1977,7 @@ abstract class GenICode extends SubComponent { */ def enterMethod(m: IMethod, d: DefDef): Context = { val ctx1 = new Context(this) setMethod(m) - ctx1.labels = new mutable.HashMap() + ctx1.labels = mutable.HashMap() ctx1.method.code = new Code(m) ctx1.bb = ctx1.method.code.startBlock ctx1.defdef = d @@ -1991,7 +1991,7 @@ abstract class GenICode extends SubComponent { val block = method.code.newBlock handlers foreach (_ addCoveredBlock block) currentExceptionHandlers foreach (_ addBlock block) - block.varsInScope = new mutable.HashSet() ++= scope.varsInScope + block.varsInScope = mutable.HashSet() ++= scope.varsInScope new Context(this) setBasicBlock block } diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala index 3d3097e497..2b635e032a 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodeCheckers.scala @@ -60,8 +60,8 @@ abstract class ICodeCheckers { var method: IMethod = _ var code: Code = _ - val in: mutable.Map[BasicBlock, TypeStack] = new mutable.HashMap() - val out: mutable.Map[BasicBlock, TypeStack] = new mutable.HashMap() + val in: mutable.Map[BasicBlock, TypeStack] = perRunCaches.newMap() + val out: mutable.Map[BasicBlock, TypeStack] = perRunCaches.newMap() val emptyStack = new TypeStack() { override def toString = "<empty>" } diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 2bcce6527e..47da7c2e31 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -10,7 +10,6 @@ package icode import java.io.PrintWriter import scala.collection.{ mutable, immutable } -import mutable.{ HashMap, ListBuffer } import symtab.Flags.{ DEFERRED } trait ReferenceEquality { @@ -29,7 +28,7 @@ trait Members { self: ICodes => def this(method: IMethod) = this(method.symbol.simpleName.toString, method) /** The set of all blocks */ - val blocks: ListBuffer[BasicBlock] = new ListBuffer + val blocks = mutable.ListBuffer[BasicBlock]() /** The start block of the method */ var startBlock: BasicBlock = null diff --git a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala index 02302bec89..290979d205 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala @@ -18,7 +18,7 @@ trait Repository { import global._ import icodes._ - val loaded: mutable.Map[Symbol, IClass] = new mutable.HashMap + val loaded: mutable.Map[Symbol, IClass] = perRunCaches.newMap() /** Is the given class available as icode? */ def available(sym: Symbol) = classes.contains(sym) || loaded.contains(sym) diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index e1e9360e43..63ea572e2f 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -3,11 +3,10 @@ * @author Martin Odersky */ - package scala.tools.nsc package backend.icode.analysis -import scala.collection.mutable.{ Map, HashMap } +import scala.collection.{ mutable, immutable } /** A modified copy-propagation like analysis. It * is augmented with a record-like value which is used @@ -30,7 +29,7 @@ abstract class CopyPropagation { abstract class Value { def isRecord = false } - case class Record(cls: Symbol, bindings: Map[Symbol, Value]) extends Value { + case class Record(cls: Symbol, bindings: mutable.Map[Symbol, Value]) extends Value { override def isRecord = true } /** The value of some location in memory. */ @@ -46,13 +45,13 @@ abstract class CopyPropagation { case object Unknown extends Value /** The bottom record. */ - object AllRecords extends Record(NoSymbol, new HashMap[Symbol, Value]) + object AllRecords extends Record(NoSymbol, mutable.HashMap[Symbol, Value]()) /** The lattice for this analysis. */ object copyLattice extends SemiLattice { - type Bindings = Map[Location, Value] + type Bindings = mutable.Map[Location, Value] - def emptyBinding = new HashMap[Location, Value]() + def emptyBinding = mutable.HashMap[Location, Value]() class State(val bindings: Bindings, var stack: List[Value]) { @@ -141,7 +140,7 @@ abstract class CopyPropagation { "\nBindings: " + bindings + "\nStack: " + stack; def dup: State = { - val b: Bindings = new HashMap() + val b: Bindings = mutable.HashMap() b ++= bindings new State(b, stack) } @@ -176,7 +175,7 @@ abstract class CopyPropagation { if (v1 == v2) v1 else Unknown } */ - val resBindings = new HashMap[Location, Value] + val resBindings = mutable.HashMap[Location, Value]() for ((k, v) <- a.bindings if b.bindings.isDefinedAt(k) && v == b.bindings(k)) resBindings += (k -> v); @@ -226,7 +225,7 @@ abstract class CopyPropagation { import opcodes._ - private def retain[A, B](map: Map[A, B])(p: (A, B) => Boolean) = { + private def retain[A, B](map: mutable.Map[A, B])(p: (A, B) => Boolean) = { for ((k, v) <- map ; if !p(k, v)) map -= k map } @@ -370,7 +369,7 @@ abstract class CopyPropagation { case NEW(kind) => val v1 = kind match { - case REFERENCE(cls) => Record(cls, new HashMap[Symbol, Value]) + case REFERENCE(cls) => Record(cls, mutable.HashMap[Symbol, Value]()) case _ => Unknown } out.stack = v1 :: out.stack @@ -525,10 +524,10 @@ abstract class CopyPropagation { * method has to find the correct mapping from fields to the order in which * they are passed on the stack. It works for primary constructors. */ - private def getBindingsForPrimaryCtor(in: copyLattice.State, ctor: Symbol): Map[Symbol, Value] = { + private def getBindingsForPrimaryCtor(in: copyLattice.State, ctor: Symbol): mutable.Map[Symbol, Value] = { val paramAccessors = ctor.owner.constrParamAccessors; var values = in.stack.take(1 + ctor.info.paramTypes.length).reverse.drop(1); - val bindings = new HashMap[Symbol, Value]; + val bindings = mutable.HashMap[Symbol, Value]() if (settings.debug.value) log("getBindings for: " + ctor + " acc: " + paramAccessors) diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala index e5eeff0d1c..97da13abfc 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala @@ -37,8 +37,8 @@ abstract class Liveness { var method: IMethod = _ - val gen: mutable.Map[BasicBlock, Set[Local]] = new mutable.HashMap() - val kill: mutable.Map[BasicBlock, Set[Local]] = new mutable.HashMap() + val gen: mutable.Map[BasicBlock, Set[Local]] = perRunCaches.newMap() + val kill: mutable.Map[BasicBlock, Set[Local]] = perRunCaches.newMap() def init(m: IMethod) { this.method = m diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala index 418dbea9e1..9697477543 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala @@ -3,12 +3,10 @@ * @author Iulian Dragos */ - package scala.tools.nsc package backend.jvm import scala.collection.{ mutable, immutable } - import ch.epfl.lamp.fjbg._ trait GenJVMUtil { @@ -34,16 +32,13 @@ trait GenJVMUtil { DOUBLE -> new JObjectType("java.lang.Double") ) - private val javaNameCache = { - val map = new mutable.WeakHashMap[Symbol, String]() - map ++= List( - NothingClass -> RuntimeNothingClass.fullName('/'), - RuntimeNothingClass -> RuntimeNothingClass.fullName('/'), - NullClass -> RuntimeNullClass.fullName('/'), - RuntimeNullClass -> RuntimeNullClass.fullName('/') - ) - map - } + // Don't put this in per run caches. + private val javaNameCache = new mutable.WeakHashMap[Symbol, String]() ++= List( + NothingClass -> RuntimeNothingClass.fullName('/'), + RuntimeNothingClass -> RuntimeNothingClass.fullName('/'), + NullClass -> RuntimeNullClass.fullName('/'), + RuntimeNullClass -> RuntimeNullClass.fullName('/') + ) /** This trait may be used by tools who need access to * utility methods like javaName and javaType. (for instance, diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 5a4d192eff..ae2082ec8b 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -9,8 +9,7 @@ package backend.msil import java.io.{File, IOException} import java.nio.{ByteBuffer, ByteOrder} - -import scala.collection.mutable.{Map, HashMap, HashSet, Stack, ListBuffer} +import scala.collection.{ mutable, immutable } import scala.tools.nsc.symtab._ import ch.epfl.lamp.compiler.msil.{Type => MsilType, _} @@ -132,7 +131,7 @@ abstract class GenMSIL extends SubComponent { // java instance methods that are mapped to static methods in .net // these will need to be called with OpCodes.Call (not Callvirt) - val dynToStatMapped: HashSet[Symbol] = new HashSet() + val dynToStatMapped = mutable.HashSet[Symbol]() initMappings() @@ -563,7 +562,7 @@ abstract class GenMSIL extends SubComponent { */ val msilLinearizer = new MSILLinearizer() - val labels: HashMap[BasicBlock, Label] = new HashMap() + val labels = mutable.HashMap[BasicBlock, Label]() /* when emitting .line, it's enough to include the full filename just once per method, thus reducing filesize. * this scheme relies on the fact that the entry block is emitted first. */ @@ -619,11 +618,11 @@ abstract class GenMSIL extends SubComponent { } // the try blocks starting at a certain BasicBlock - val beginExBlock = new HashMap[BasicBlock, List[ExceptionHandler]]() + val beginExBlock = mutable.HashMap[BasicBlock, List[ExceptionHandler]]() // the catch blocks starting / endling at a certain BasicBlock - val beginCatchBlock = new HashMap[BasicBlock, ExceptionHandler]() - val endExBlock = new HashMap[BasicBlock, List[ExceptionHandler]]() + val beginCatchBlock = mutable.HashMap[BasicBlock, ExceptionHandler]() + val endExBlock = mutable.HashMap[BasicBlock, List[ExceptionHandler]]() /** When emitting the code (genBlock), the number of currently active try / catch * blocks. When seeing a `RETURN` inside a try / catch, we need to @@ -631,7 +630,7 @@ abstract class GenMSIL extends SubComponent { * - emit `Leave handlerReturnLabel` instead of the Return * - emit code at the end: load the local and return its value */ - var currentHandlers = new Stack[ExceptionHandler] + var currentHandlers = new mutable.Stack[ExceptionHandler] // The IMethod the Local/Label/Kind below belong to var handlerReturnMethod: IMethod = _ // Stores the result when returning inside an exception block @@ -658,11 +657,11 @@ abstract class GenMSIL extends SubComponent { * So for every finalizer, we have a label which marks the place of the `endfinally`, * nested try/catch blocks will leave there. */ - val endFinallyLabels = new HashMap[ExceptionHandler, Label]() + val endFinallyLabels = mutable.HashMap[ExceptionHandler, Label]() /** Computes which blocks are the beginning / end of a try or catch block */ private def computeExceptionMaps(blocks: List[BasicBlock], m: IMethod): List[BasicBlock] = { - val visitedBlocks = new HashSet[BasicBlock]() + val visitedBlocks = new mutable.HashSet[BasicBlock]() // handlers which have not been introduced so far var openHandlers = m.exh @@ -689,11 +688,11 @@ abstract class GenMSIL extends SubComponent { // Stack of nested try blocks. Each bloc has a List of ExceptionHandler (multiple // catch statements). Example *1*: Stack(List(h2, h3), List(h1)) - val currentTryHandlers = new Stack[List[ExceptionHandler]]() + val currentTryHandlers = new mutable.Stack[List[ExceptionHandler]]() // Stack of nested catch blocks. The head of the list is the current catch block. The // tail is all following catch blocks. Example *2*: Stack(List(h3), List(h4, h5)) - val currentCatchHandlers = new Stack[List[ExceptionHandler]]() + val currentCatchHandlers = new mutable.Stack[List[ExceptionHandler]]() for (b <- blocks) { @@ -752,7 +751,7 @@ abstract class GenMSIL extends SubComponent { // (checked by the assertions below) val sizes = newHandlersBySize.keys.toList.sortWith(_ > _) - val beginHandlers = new ListBuffer[ExceptionHandler] + val beginHandlers = new mutable.ListBuffer[ExceptionHandler] for (s <- sizes) { val sHandlers = newHandlersBySize(s) for (h <- sHandlers) { @@ -1724,13 +1723,13 @@ abstract class GenMSIL extends SubComponent { var entryPoint: Symbol = _ - val notInitializedModules: HashSet[Symbol] = new HashSet() + val notInitializedModules = mutable.HashSet[Symbol]() // TODO: create fields also in def createType, and not in genClass, // add a getField method (it only works as it is because fields never // accessed from outside a class) - val localBuilders: HashMap[Local, LocalBuilder] = new HashMap() + val localBuilders = mutable.HashMap[Local, LocalBuilder]() private[GenMSIL] def findEntryPoint(cls: IClass) { diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index cd38a2a4a7..d5194346c9 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -3,11 +3,9 @@ * @author Iulian Dragos */ - package scala.tools.nsc package backend.opt -import scala.collection.mutable.{Map, HashMap} import scala.tools.nsc.backend.icode.analysis.LubException import scala.tools.nsc.symtab._ diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index d176ef43e3..c591fee502 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -59,7 +59,7 @@ abstract class DeadCodeElimination extends SubComponent { val worklist: mutable.Set[(BasicBlock, Int)] = new mutable.LinkedHashSet /** what instructions have been marked as useful? */ - val useful: mutable.Map[BasicBlock, mutable.BitSet] = new mutable.HashMap + val useful: mutable.Map[BasicBlock, mutable.BitSet] = perRunCaches.newMap() /** what local variables have been accessed at least once? */ var accessedLocals: List[Local] = Nil @@ -68,7 +68,7 @@ abstract class DeadCodeElimination extends SubComponent { var method: IMethod = _ /** Map instructions who have a drop on some control path, to that DROP instruction. */ - val dropOf: mutable.Map[(BasicBlock, Int), (BasicBlock, Int)] = new mutable.HashMap() + val dropOf: mutable.Map[(BasicBlock, Int), (BasicBlock, Int)] = perRunCaches.newMap() def dieCodeDie(m: IMethod) { if (m.code ne null) { diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 07115e28ca..cf9bf3cdeb 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -78,12 +78,12 @@ abstract class Inliners extends SubComponent { val Private, Protected, Public = Value /** Cache whether a method calls private members. */ - val usesNonPublics: mutable.Map[IMethod, Value] = new mutable.HashMap + val usesNonPublics: mutable.Map[IMethod, Value] = perRunCaches.newMap() } import NonPublicRefs._ /* fresh name counter */ - val fresh = new mutable.HashMap[String, Int] withDefaultValue 0 + val fresh = perRunCaches.newMap[String, Int]() withDefaultValue 0 def freshName(s: String) = { fresh(s) += 1 s + fresh(s) @@ -108,9 +108,7 @@ abstract class Inliners extends SubComponent { tfa.stat = global.opt.printStats // how many times have we already inlined this method here? - private val inlinedMethodCount: mutable.Map[Symbol, Int] = new mutable.HashMap[Symbol, Int] { - override def default(k: Symbol) = 0 - } + private val inlinedMethodCount = perRunCaches.newMap[Symbol, Int]() withDefaultValue 0 def analyzeMethod(m: IMethod): Unit = { var sizeBeforeInlining = if (m.code ne null) m.code.blockCount else 0 @@ -367,7 +365,7 @@ abstract class Inliners extends SubComponent { case x => newLocal("$retVal", x) } - val inlinedLocals: mutable.Map[Local, Local] = new mutable.HashMap + val inlinedLocals = perRunCaches.newMap[Local, Local]() /** Add a new block in the current context. */ def newBlock() = { diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index f89001c1fe..a093c875b8 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -6,10 +6,9 @@ package scala.tools.nsc package interactive import java.io.{ PrintWriter, StringWriter, FileReader, FileWriter } -import collection.mutable.{ArrayBuffer, ListBuffer, SynchronizedBuffer, HashMap} - import scala.collection.mutable -import mutable.{LinkedHashMap, SynchronizedMap,LinkedHashSet, SynchronizedSet} +import collection.mutable.{ ArrayBuffer, ListBuffer, SynchronizedBuffer } +import mutable.{LinkedHashMap, SynchronizedMap, SynchronizedSet} import scala.concurrent.SyncVar import scala.util.control.ControlThrowable import scala.tools.nsc.io.{ AbstractFile, LogReplay, Logger, NullLogger, Replayer } diff --git a/src/compiler/scala/tools/nsc/interpreter/Phased.scala b/src/compiler/scala/tools/nsc/interpreter/Phased.scala index b3d33325e4..d164d1cbb0 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Phased.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Phased.scala @@ -7,7 +7,6 @@ package scala.tools.nsc package interpreter import scala.collection.{ mutable, immutable } -import immutable.SortedMap /** Mix this into an object and use it as a phasing * swiss army knife. @@ -66,8 +65,7 @@ trait Phased { try parseInternal(str) catch { case _: Exception => NoPhaseName } - def apply[T](body: => T): SortedMap[PhaseName, T] = - SortedMap[PhaseName, T](atMap(PhaseName.all)(body): _*) + def apply[T](body: => T) = immutable.SortedMap[PhaseName, T](atMap(PhaseName.all)(body): _*) def atCurrent[T](body: => T): T = atPhase(get)(body) def multi[T](body: => T): Seq[T] = multi map (ph => at(ph)(body)) diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 65e570f133..91626313ee 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -8,12 +8,11 @@ package scala.tools.nsc package matching import PartialFunction._ -import scala.collection.{ mutable, immutable } +import scala.collection.{ mutable } import util.Position import transform.ExplicitOuter import symtab.Flags import mutable.ListBuffer -import immutable.IntMap import annotation.elidable trait ParallelMatching extends ast.TreeDSL @@ -43,7 +42,7 @@ trait ParallelMatching extends ast.TreeDSL lazy val (rows, targets) = expand(roots, cases).unzip lazy val expansion: Rep = make(roots, rows) - private val shortCuts = mutable.HashMap[Int, Symbol]() + private val shortCuts = perRunCaches.newMap[Int, Symbol]() final def createShortCut(theLabel: Symbol): Int = { val key = shortCuts.size + 1 diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala index 3d3698d425..5dd7d8f3ee 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala @@ -7,7 +7,6 @@ package scala.tools.nsc package matching import transform.ExplicitOuter -import collection.immutable.TreeMap import PartialFunction._ trait PatternBindings extends ast.TreeDSL diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala index 3c629e5504..b25bf2d649 100644 --- a/src/compiler/scala/tools/nsc/matching/Patterns.scala +++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala @@ -271,8 +271,7 @@ trait Patterns extends ast.TreeDSL { object Pattern { // a small tree -> pattern cache - private val cache = new collection.mutable.HashMap[Tree, Pattern] - def clear() = cache.clear() + private val cache = perRunCaches.newMap[Tree, Pattern]() def apply(tree: Tree): Pattern = { if (cache contains tree) diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index 5127c2eb19..cad69deb7b 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package reporters -import scala.collection.mutable.HashMap +import scala.collection.mutable import scala.tools.nsc.Settings import scala.tools.nsc.util.Position @@ -18,7 +18,7 @@ abstract class AbstractReporter extends Reporter { def display(pos: Position, msg: String, severity: Severity): Unit def displayPrompt(): Unit - private val positions = new HashMap[Position, Severity] + private val positions = new mutable.HashMap[Position, Severity] override def reset() { super.reset diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 03e6e508f6..838dd7404f 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -10,7 +10,7 @@ package settings import annotation.elidable import scala.tools.util.PathResolver.Defaults -import scala.collection.mutable.HashSet +import scala.collection.mutable trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings @@ -20,7 +20,7 @@ trait ScalaSettings extends AbsScalaSettings import Defaults.scalaUserClassPath /** Set of settings */ - protected lazy val allSettings = HashSet[Setting]() + protected lazy val allSettings = mutable.HashSet[Setting]() /** Disable a setting */ def disable(s: Setting) = allSettings -= s diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index b11c6f00ee..0d42fa503d 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -7,10 +7,6 @@ package scala.tools package nsc package settings -import annotation.elidable -import scala.tools.util.PathResolver.Defaults -import scala.collection.mutable.HashSet - /** Settings influencing the printing of warnings. */ trait Warnings { diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index a5db788260..3c98d0adcc 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -664,8 +664,8 @@ abstract class ICodeReader extends ClassfileParser { class LinearCode { var instrs: ListBuffer[(Int, Instruction)] = new ListBuffer - var jmpTargets: mutable.Set[Int] = new mutable.HashSet[Int] - var locals: mutable.Map[Int, List[(Local, TypeKind)]] = new mutable.HashMap() + var jmpTargets: mutable.Set[Int] = perRunCaches.newSet[Int]() + var locals: mutable.Map[Int, List[(Local, TypeKind)]] = perRunCaches.newMap() var containsDUPX = false var containsNEW = false diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala index cf1f7f1db3..7be0fcb146 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala @@ -10,10 +10,8 @@ package clr import java.io.File import java.util.{Comparator, StringTokenizer} import scala.util.Sorting - import ch.epfl.lamp.compiler.msil._ - -import scala.collection.mutable.{ListBuffer, Map, HashMap, Set, HashSet} +import scala.collection.{ mutable, immutable } import scala.tools.nsc.util.{Position, NoPosition} /** @@ -56,13 +54,13 @@ abstract class CLRTypes { var DELEGATE_COMBINE: MethodInfo = _ var DELEGATE_REMOVE: MethodInfo = _ - val types: Map[Symbol,Type] = new HashMap - val constructors: Map[Symbol,ConstructorInfo] = new HashMap - val methods: Map[Symbol,MethodInfo] = new HashMap - val fields: Map[Symbol, FieldInfo] = new HashMap - val sym2type: Map[Type,Symbol] = new HashMap - val addressOfViews: HashSet[Symbol] = new HashSet[Symbol] - val mdgptrcls4clssym: Map[ /*cls*/ Symbol, /*cls*/ Symbol] = new HashMap + val types: mutable.Map[Symbol,Type] = new mutable.HashMap + val constructors: mutable.Map[Symbol,ConstructorInfo] = new mutable.HashMap + val methods: mutable.Map[Symbol,MethodInfo] = new mutable.HashMap + val fields: mutable.Map[Symbol, FieldInfo] = new mutable.HashMap + val sym2type: mutable.Map[Type,Symbol] = new mutable.HashMap + val addressOfViews = new mutable.HashSet[Symbol] + val mdgptrcls4clssym: mutable.Map[ /*cls*/ Symbol, /*cls*/ Symbol] = new mutable.HashMap def isAddressOf(msym : Symbol) = addressOfViews.contains(msym) diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala index efa2a18d5a..154ea89a0d 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala @@ -2,16 +2,13 @@ * Copyright 2004-2011 LAMP/EPFL */ - package scala.tools.nsc package symtab package clr import java.io.IOException - import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _} - -import scala.collection.mutable.{HashMap, HashSet} +import scala.collection.{ mutable, immutable } import scala.reflect.internal.pickling.UnPickler import ch.epfl.lamp.compiler.msil.Type.TMVarUsage @@ -295,7 +292,7 @@ abstract class TypeParser { createMethod(constr); // initially also contains getters and setters of properties. - val methodsSet = new HashSet[MethodInfo](); + val methodsSet = new mutable.HashSet[MethodInfo](); methodsSet ++= typ.getMethods(); for (prop <- typ.getProperties) { diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index c3fb79a47f..dde229fa7f 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -39,13 +39,13 @@ abstract class AddInterfaces extends InfoTransform { /** A lazily constructed map that associates every non-interface trait with * its implementation class. */ - private val implClassMap = new mutable.HashMap[Symbol, Symbol] + private val implClassMap = perRunCaches.newMap[Symbol, Symbol]() /** A lazily constructed map that associates every concrete method in a non-interface * trait that's currently compiled with its corresponding method in the trait's * implementation class. */ - private val implMethodMap = new mutable.HashMap[Symbol, Symbol] + private val implMethodMap = perRunCaches.newMap[Symbol, Symbol]() override def newPhase(prev: scala.tools.nsc.Phase): StdPhase = { implClassMap.clear() diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index ca53663cc6..f2e4495783 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -529,9 +529,5 @@ abstract class ExplicitOuter extends InfoTransform class Phase(prev: scala.tools.nsc.Phase) extends super.Phase(prev) { override val checkable = false - override def run() { - super.run - Pattern.clear() // clear the cache - } } } diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala index 1710e8e4c3..1e6d86bb97 100644 --- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala +++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package transform -import collection.mutable.HashMap +import scala.collection.mutable import symtab.Flags._ import util.HashSet import annotation.tailrec @@ -99,7 +99,7 @@ abstract class OverridingPairs { /** A map from baseclasses of <base> to ints, with smaller ints meaning lower in * linearization order. */ - private val index = new HashMap[Symbol, Int] + private val index = new mutable.HashMap[Symbol, Int] // Note: overridingPairs can be called at odd instances by the Eclipse plugin // Soemtimes symbols are not yet defined and we get missing keys. diff --git a/src/compiler/scala/tools/nsc/transform/Reifiers.scala b/src/compiler/scala/tools/nsc/transform/Reifiers.scala index d938a20f2f..b9e558add6 100644 --- a/src/compiler/scala/tools/nsc/transform/Reifiers.scala +++ b/src/compiler/scala/tools/nsc/transform/Reifiers.scala @@ -3,7 +3,7 @@ package transform import scala.tools.nsc.symtab.SymbolTable import scala.reflect -import collection.mutable.HashMap +import collection.mutable /** Functions to reify (and un-reify) symbols, types, and trees. * These can be used with only a symbol table; they do not @@ -184,8 +184,8 @@ trait Reifiers { case class FreeValue(tree: Tree) extends reflect.Tree - class ReifyEnvironment extends HashMap[Symbol, reflect.Symbol] { - var targets = new HashMap[String, Option[reflect.LabelSymbol]]() + class ReifyEnvironment extends mutable.HashMap[Symbol, reflect.Symbol] { + var targets = new mutable.HashMap[String, Option[reflect.LabelSymbol]]() def addTarget(name: String, target: reflect.LabelSymbol): Unit = targets.update(name, Some(target)) def getTarget(name: String): Option[reflect.LabelSymbol] = diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 29ca9f4a70..c0e78d716c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -13,7 +13,7 @@ package typechecker import annotation.tailrec import scala.collection.{ mutable, immutable } -import mutable.{ HashMap, LinkedHashMap, ListBuffer } +import mutable.{ LinkedHashMap, ListBuffer } import scala.util.matching.Regex import symtab.Flags._ import util.Statistics._ @@ -83,7 +83,7 @@ trait Implicits { private type InfoMap = LinkedHashMap[Symbol, List[ImplicitInfo]] // A map from class symbols to their associated implicits private val implicitsCache = new LinkedHashMap[Type, Infoss] private val infoMapCache = new LinkedHashMap[Symbol, InfoMap] - private val improvesCache = new HashMap[(ImplicitInfo, ImplicitInfo), Boolean] + private val improvesCache = perRunCaches.newMap[(ImplicitInfo, ImplicitInfo), Boolean]() def resetImplicits() { implicitsCache.clear() @@ -175,7 +175,7 @@ trait Implicits { /** An extractor for types of the form ? { name: ? } */ object HasMember { - private val hasMemberCache = new mutable.HashMap[Name, Type] + private val hasMemberCache = perRunCaches.newMap[Name, Type]() def apply(name: Name): Type = hasMemberCache.getOrElseUpdate(name, memberWildcardType(name, WildcardType)) def unapply(pt: Type): Option[Name] = pt match { case RefinedType(List(WildcardType), decls) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 1ea41ff928..713c5f607a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -6,9 +6,8 @@ package scala.tools.nsc package typechecker -import scala.collection.mutable.{HashMap, WeakHashMap} +import scala.collection.mutable import scala.ref.WeakReference -import symtab.Flags import symtab.Flags._ import scala.tools.nsc.io.AbstractFile @@ -52,7 +51,7 @@ trait Namers { self: Analyzer => // is stored in this map. The map is cleared lazily, i.e. when the new symbol // is created with the same name, the old one (if present) is wiped out, or the // entry is deleted when it is used and no longer needed. - private val caseClassOfModuleClass = new WeakHashMap[Symbol, WeakReference[ClassDef]] + private val caseClassOfModuleClass = perRunCaches.newWeakMap[Symbol, WeakReference[ClassDef]]() // Default getters of constructors are added to the companion object in the // typeCompleter of the constructor (methodSig). To compute the signature, @@ -60,7 +59,7 @@ trait Namers { self: Analyzer => // object, we need the templateNamer of that module class. // This map is extended during naming of classes, the Namer is added in when // it's available, i.e. in the type completer (templateSig) of the module class. - private[typechecker] val classAndNamerOfModule = new HashMap[Symbol, (ClassDef, Namer)] + private[typechecker] val classAndNamerOfModule = perRunCaches.newMap[Symbol, (ClassDef, Namer)]() def resetNamer() { classAndNamerOfModule.clear @@ -548,7 +547,7 @@ trait Namers { self: Analyzer => // --- Lazy Type Assignment -------------------------------------------------- def typeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym => - if (settings.debug.value) log("defining " + sym + Flags.flagsToString(sym.flags)+sym.locationString) + if (settings.debug.value) log("defining " + sym + flagsToString(sym.flags)+sym.locationString) val tp = typeSig(tree) tp match { case TypeBounds(lo, hi) => @@ -1323,10 +1322,10 @@ trait Namers { self: Analyzer => if (sym.hasFlag(flag1) && sym.hasFlag(flag2)) context.error(sym.pos, if (flag1 == DEFERRED) - "abstract member may not have " + Flags.flagsToString(flag2) + " modifier"; + "abstract member may not have " + flagsToString(flag2) + " modifier"; else "illegal combination of modifiers: " + - Flags.flagsToString(flag1) + " and " + Flags.flagsToString(flag2) + + flagsToString(flag1) + " and " + flagsToString(flag2) + " for: " + sym); } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 18840de28f..a5c5aa5320 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -7,9 +7,7 @@ package scala.tools.nsc package typechecker import symtab.Flags._ - -import scala.collection.mutable.{ListBuffer, WeakHashMap} -import scala.collection.immutable.Set +import scala.collection.mutable /** * @author Lukas Rytz @@ -20,9 +18,8 @@ trait NamesDefaults { self: Analyzer => import global._ import definitions._ - val defaultParametersOfMethod = new WeakHashMap[Symbol, Set[Symbol]] { - override def default(key: Symbol) = Set() - } + val defaultParametersOfMethod = + perRunCaches.newWeakMap[Symbol, Set[Symbol]]() withDefaultValue Set() case class NamedApplyInfo(qual: Option[Tree], targs: List[Tree], vargss: List[List[Tree]], blockTyper: Typer) @@ -45,7 +42,7 @@ trait NamesDefaults { self: Analyzer => /** @param pos maps indicies from new to old (!) */ def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray - val res = new ListBuffer[T] + val res = new mutable.ListBuffer[T] for (i <- 0 until argsArray.length) res += argsArray(pos(i)) res.toList diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 9ca70bbefb..8a05045514 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -862,7 +862,7 @@ abstract class RefChecks extends InfoTransform { } private var currentLevel: LevelInfo = null - private val symIndex = new mutable.HashMap[Symbol, Int] + private val symIndex = perRunCaches.newMap[Symbol, Int]() private def pushLevel() { currentLevel = new LevelInfo(currentLevel) diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index a8c3a13646..c8e2b6fca4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -8,7 +8,7 @@ package typechecker import scala.tools.nsc.symtab.Flags._ import scala.collection.mutable -import mutable.{ HashMap, HashSet, ListBuffer } +import mutable.ListBuffer import util.returning abstract class TreeCheckers extends Analyzer { @@ -33,12 +33,13 @@ abstract class TreeCheckers extends Analyzer { /** This is a work in progress, don't take it too seriously. */ object SymbolTracker extends Traverser { - type PhaseMap = HashMap[Symbol, List[Tree]] - val maps: ListBuffer[(Phase, PhaseMap)] = ListBuffer() + type PhaseMap = mutable.HashMap[Symbol, List[Tree]] + + val maps = ListBuffer[(Phase, PhaseMap)]() def prev = maps.init.last._2 def latest = maps.last._2 - val defSyms = new HashMap[Symbol, List[DefTree]] - val newSyms = new HashSet[Symbol] + val defSyms = mutable.HashMap[Symbol, List[DefTree]]() + val newSyms = mutable.HashSet[Symbol]() val movedMsgs = new ListBuffer[String] def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString) @@ -110,7 +111,7 @@ abstract class TreeCheckers extends Analyzer { } } - lazy val tpeOfTree = new HashMap[Tree, Type] + lazy val tpeOfTree = mutable.HashMap[Tree, Type]() def posstr(p: Position) = try p.source.path + ":" + p.line diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala index fdb03dedaa..1db6c38b4d 100755 --- a/src/compiler/scala/tools/nsc/util/DocStrings.scala +++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala @@ -3,12 +3,10 @@ * @author Martin Odersky */ - package scala.tools.nsc package util import scala.reflect.internal.Chars._ -import scala.collection.mutable.{HashMap, ListBuffer, StringBuilder} /** Utilitity methods for doc comment strings */ diff --git a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala index 998e1694cc..88fc6718a2 100644 --- a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala +++ b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package util -import scala.collection.mutable.HashMap +import scala.collection.mutable trait FreshNameCreator { /** Do not call before after type checking ends. @@ -24,7 +24,7 @@ trait FreshNameCreator { object FreshNameCreator { class Default extends FreshNameCreator { protected var counter = 0 - protected val counters = new HashMap[String, Int] withDefaultValue 0 + protected val counters = mutable.HashMap[String, Int]() withDefaultValue 0 /** * Create a fresh name with the given prefix. It is guaranteed diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala index 13fb3185ab..a1c310859a 100644 --- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala @@ -13,9 +13,8 @@ import java.net.URL import java.util.StringTokenizer import scala.util.Sorting -import scala.collection.mutable.{ ListBuffer, HashSet => MutHashSet } +import scala.collection.mutable import scala.tools.nsc.io.AbstractFile - import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly } import ClassPath.{ ClassPathContext, isTraitImplementation } @@ -54,8 +53,8 @@ object MsilClassPath { private def assembleEntries(ext: String, user: String, source: String, context: MsilContext): List[ClassPath[MSILType]] = { import ClassPath._ - val etr = new ListBuffer[ClassPath[MSILType]] - val names = new MutHashSet[String] + val etr = new mutable.ListBuffer[ClassPath[MSILType]] + val names = new mutable.HashSet[String] // 1. Assemblies from -Xassem-extdirs for (dirName <- expandPath(ext, expandStar = false)) { @@ -127,7 +126,7 @@ class AssemblyClassPath(types: Array[MSILType], namespace: String, val context: } lazy val classes = { - val cls = new ListBuffer[ClassRep] + val cls = new mutable.ListBuffer[ClassRep] var i = first while (i < types.length && types(i).Namespace.startsWith(namespace)) { // CLRTypes used to exclude java.lang.Object and java.lang.String (no idea why..) @@ -139,7 +138,7 @@ class AssemblyClassPath(types: Array[MSILType], namespace: String, val context: } lazy val packages = { - val nsSet = new MutHashSet[String] + val nsSet = new mutable.HashSet[String] var i = first while (i < types.length && types(i).Namespace.startsWith(namespace)) { val subns = types(i).Namespace diff --git a/src/compiler/scala/tools/nsc/util/MultiHashMap.scala b/src/compiler/scala/tools/nsc/util/MultiHashMap.scala index 719d18cd2e..67987c6e52 100644 --- a/src/compiler/scala/tools/nsc/util/MultiHashMap.scala +++ b/src/compiler/scala/tools/nsc/util/MultiHashMap.scala @@ -1,10 +1,9 @@ package scala.tools.nsc.util -import collection.mutable.HashMap -import collection.immutable +import scala.collection.{ mutable, immutable } /** A hashmap with set-valued values, and an empty set as default value */ -class MultiHashMap[K, V] extends HashMap[K, immutable.Set[V]] { +class MultiHashMap[K, V] extends mutable.HashMap[K, immutable.Set[V]] { override def default(key: K): immutable.Set[V] = Set() } diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala index aa1bb734ea..2534e1192d 100644 --- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala +++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala @@ -1,15 +1,15 @@ package scala.tools.nsc package util -import scala.collection.mutable.Queue +import scala.collection.mutable class WorkScheduler { type Action = () => Unit - private var todo = new Queue[Action] - private var throwables = new Queue[Throwable] - private var interruptReqs = new Queue[InterruptReq] + private var todo = new mutable.Queue[Action] + private var throwables = new mutable.Queue[Throwable] + private var interruptReqs = new mutable.Queue[InterruptReq] /** Called from server: block until one of todo list, throwables or interruptReqs is nonempty */ def waitForMoreWork() = synchronized { diff --git a/src/compiler/scala/tools/util/AbstractTimer.scala b/src/compiler/scala/tools/util/AbstractTimer.scala index 219b5d2124..210a1ee53c 100644 --- a/src/compiler/scala/tools/util/AbstractTimer.scala +++ b/src/compiler/scala/tools/util/AbstractTimer.scala @@ -10,7 +10,7 @@ package scala.tools.util import compat.Platform.currentTime -import scala.collection.mutable.Stack +import scala.collection.mutable /** * This abstract class implements the collection of timings. How the @@ -25,7 +25,7 @@ abstract class AbstractTimer { // Private Fields /** A stack for maintaining start times */ - private val starts = new Stack[Long]() + private val starts = new mutable.Stack[Long]() //######################################################################## // Public Methods |