Skip to content

Commit 2acc7b3

Browse files
Merge pull request #3122 from dotty-staging/homogenize-symbol-maps
Homogenize mutable symbol maps
2 parents 9a0c822 + 9ce9ea3 commit 2acc7b3

22 files changed

+127
-63
lines changed

compiler/sjs/backend/sjs/JSPrimitives.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class JSPrimitives(ctx: Context) extends DottyPrimitives(ctx) {
5959
/** Initialize the primitive map */
6060
private def initJSPrimitives(implicit ctx: Context): Map[Symbol, Int] = {
6161

62-
val primitives = new mutable.HashMap[Symbol, Int]()
62+
val primitives = newMutableSymbolMap[Int]
6363

6464
// !!! Code duplicate with DottyPrimitives
6565
/** Add a primitive operation to the map */

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ class GenBCode extends Phase {
4343
private val entryPoints = new mutable.HashSet[Symbol]()
4444
def registerEntryPoint(sym: Symbol) = entryPoints += sym
4545

46-
private val superCallsMap = new mutable.HashMap[Symbol, Set[ClassSymbol]]()
46+
private val superCallsMap = newMutableSymbolMap[Set[ClassSymbol]]
4747
def registerSuperCall(sym: Symbol, calls: ClassSymbol) = {
4848
val old = superCallsMap.getOrElse(sym, Set.empty)
49-
superCallsMap.put(sym, old + calls)
49+
superCallsMap.update(sym, old + calls)
5050
}
5151

5252
private[this] var myOutput: AbstractFile = _

compiler/src/dotty/tools/backend/jvm/LabelDefs.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class LabelDefs extends MiniPhase {
7676
case t: DefDef =>
7777
assert(t.symbol is Label)
7878
EmptyTree
79-
case _ => if (labelDefs.nonEmpty) super.transform(tree) else tree
79+
case _ => if (!labelDefs.isEmpty) super.transform(tree) else tree
8080
}
8181
}
8282
}
@@ -86,9 +86,9 @@ class LabelDefs extends MiniPhase {
8686
}
8787
}
8888

89-
private def collectLabelDefs(tree: Tree)(implicit ctx: Context): mutable.HashMap[Symbol, DefDef] = {
89+
private def collectLabelDefs(tree: Tree)(implicit ctx: Context): MutableSymbolMap[DefDef] = {
9090
// labelSymbol -> Defining tree
91-
val labelDefs = new mutable.HashMap[Symbol, DefDef]()
91+
val labelDefs = newMutableSymbolMap[DefDef]
9292
new TreeTraverser {
9393
override def traverse(tree: Tree)(implicit ctx: Context): Unit = tree match {
9494
case t: DefDef =>

compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class DottyPrimitives(ctx: Context) {
128128
implicit val ctx = this.ctx
129129

130130
import core.Symbols.defn
131-
val primitives = new mutable.HashMap[Symbol, Int]()
131+
val primitives = core.Symbols.newMutableSymbolMap[Int]
132132

133133
/** Add a primitive operation to the map */
134134
def addPrimitive(s: Symbol, code: Int): Unit = {

compiler/src/dotty/tools/dotc/core/Comments.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ object Comments {
2323
* docstrings via `Symbol` and expanding templates
2424
*/
2525
class ContextDocstrings {
26-
import scala.collection.mutable
2726

28-
private[this] val _docstrings: mutable.Map[Symbol, Comment] =
29-
mutable.Map.empty
27+
private[this] val _docstrings: MutableSymbolMap[Comment] = newMutableSymbolMap
3028

3129
val templateExpander = new CommentExpander
3230

@@ -35,7 +33,7 @@ object Comments {
3533
def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym)
3634

3735
def addDocstring(sym: Symbol, doc: Option[Comment]): Unit =
38-
doc.map(d => _docstrings += (sym -> d))
36+
doc.map(d => _docstrings.update(sym, d))
3937
}
4038

4139
/** A `Comment` contains the unformatted docstring as well as a position
@@ -182,7 +180,7 @@ object Comments {
182180
protected def superComment(sym: Symbol)(implicit ctx: Context): Option[String] =
183181
allInheritedOverriddenSymbols(sym).iterator map (x => cookedDocComment(x)) find (_ != "")
184182

185-
private val cookedDocComments = mutable.HashMap[Symbol, String]()
183+
private val cookedDocComments = newMutableSymbolMap[String]
186184

187185
/** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by
188186
* missing sections of an inherited doc comment.

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,4 +679,70 @@ object Symbols {
679679
def currentClass(implicit ctx: Context): ClassSymbol = ctx.owner.enclosingClass.asClass
680680

681681
@sharable var stubs: List[Symbol] = Nil // diagnostic only
682+
683+
/* Mutable map from symbols any T */
684+
class MutableSymbolMap[T](private[Symbols] val value: java.util.IdentityHashMap[Symbol, T]) extends AnyVal {
685+
686+
def apply(sym: Symbol): T = value.get(sym)
687+
688+
def get(sym: Symbol): Option[T] = Option(value.get(sym))
689+
690+
def getOrElse[U >: T](sym: Symbol, default: => U): U = {
691+
val v = value.get(sym)
692+
if (v != null) v else default
693+
}
694+
695+
def getOrElseUpdate(sym: Symbol, op: => T): T = {
696+
val v = value.get(sym)
697+
if (v != null) v
698+
else {
699+
val v = op
700+
assert(v != null)
701+
value.put(sym, v)
702+
v
703+
}
704+
}
705+
706+
def update(sym: Symbol, x: T): Unit = {
707+
assert(x != null)
708+
value.put(sym, x)
709+
}
710+
def put(sym: Symbol, x: T): T = {
711+
assert(x != null)
712+
value.put(sym, x)
713+
}
714+
715+
def -=(sym: Symbol): Unit = value.remove(sym)
716+
def remove(sym: Symbol): Option[T] = Option(value.remove(sym))
717+
718+
def contains(sym: Symbol): Boolean = value.containsKey(sym)
719+
720+
def isEmpty: Boolean = value.isEmpty
721+
722+
def clear(): Unit = value.clear()
723+
724+
def filter(p: ((Symbol, T)) => Boolean): Map[Symbol, T] = {
725+
import scala.collection.JavaConversions._
726+
value.toMap.filter(p)
727+
}
728+
729+
def iterator: Iterator[(Symbol, T)] = {
730+
import scala.collection.JavaConversions._
731+
value.iterator
732+
}
733+
734+
def keysIterator: Iterator[Symbol] = {
735+
import scala.collection.JavaConversions._
736+
value.keySet().iterator
737+
}
738+
739+
def toMap: Map[Symbol, T] = {
740+
import scala.collection.JavaConversions._
741+
value.toMap
742+
}
743+
}
744+
745+
@inline def newMutableSymbolMap[T]: MutableSymbolMap[T] =
746+
new MutableSymbolMap(new java.util.IdentityHashMap[Symbol, T]())
747+
682748
}

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class TreePickler(pickler: TastyPickler) {
2323
import pickler.nameBuffer.nameIndex
2424
import ast.tpd._
2525

26-
private val symRefs = new mutable.HashMap[Symbol, Addr]
27-
private val forwardSymRefs = new mutable.HashMap[Symbol, List[Addr]]
26+
private val symRefs = Symbols.newMutableSymbolMap[Addr]
27+
private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]]
2828
private val pickledTypes = new java.util.IdentityHashMap[Type, Any] // Value type is really Addr, but that's not compatible with null
2929

3030
private def withLength(op: => Unit) = {
@@ -586,15 +586,15 @@ class TreePickler(pickler: TastyPickler) {
586586

587587
def pickle(trees: List[Tree])(implicit ctx: Context) = {
588588
trees.foreach(tree => if (!tree.isEmpty) pickleTree(tree))
589-
def missing = forwardSymRefs.keySet.toList.map(_.showLocated)
589+
def missing = forwardSymRefs.keysIterator.map(_.showLocated).toList
590590
assert(forwardSymRefs.isEmpty, i"unresolved symbols: $missing%, % when pickling ${ctx.source}")
591591
}
592592

593593
def compactify() = {
594594
buf.compactify()
595595

596-
def updateMapWithDeltas[T](mp: collection.mutable.Map[T, Addr]) =
597-
for (key <- mp.keysIterator.toBuffer[T]) mp(key) = adjusted(mp(key))
596+
def updateMapWithDeltas(mp: MutableSymbolMap[Addr]) =
597+
for (key <- mp.keysIterator.toBuffer[Symbol]) mp(key) = adjusted(mp(key))
598598

599599
updateMapWithDeltas(symRefs)
600600
}

compiler/src/dotty/tools/dotc/transform/Bridges.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
3333
private[this] var toBeRemoved = immutable.Set[Symbol]()
3434
private val bridges = mutable.ListBuffer[Tree]()
3535
private val bridgesScope = newScope
36-
private val bridgeTarget = mutable.HashMap[Symbol, Symbol]()
36+
private val bridgeTarget = newMutableSymbolMap[Symbol]
3737

3838
/** Add a bridge between `member` and `other`, where `member` overrides `other`
3939
* before erasure, if the following conditions are satisfied.

compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete
139139
extensionMeth
140140
}
141141

142-
private val extensionDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]()
142+
private val extensionDefs = newMutableSymbolMap[mutable.ListBuffer[Tree]]
143143
// TODO: this is state and should be per-run
144144
// todo: check that when transformation finished map is empty
145145

compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class NonLocalReturns extends MiniPhase {
3333
defn.NonLocalReturnControlType.appliedTo(argtype)
3434

3535
/** A hashmap from method symbols to non-local return keys */
36-
private val nonLocalReturnKeys = mutable.Map[Symbol, TermSymbol]()
36+
private val nonLocalReturnKeys = newMutableSymbolMap[TermSymbol]
3737

3838
/** Return non-local return key for given method */
3939
private def nonLocalReturnKey(meth: Symbol)(implicit ctx: Context) =

0 commit comments

Comments
 (0)