Skip to content

Commit 14d9fc2

Browse files
committed
Homogenize mutable symbol maps
Use IdentityHashMap instead of mutable.HashMap to make fast equality check
1 parent ed2feb2 commit 14d9fc2

22 files changed

+117
-53
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class GenBCode extends Phase {
4040
private val entryPoints = new mutable.HashSet[Symbol]()
4141
def registerEntryPoint(sym: Symbol) = entryPoints += sym
4242

43-
private val superCallsMap = new mutable.HashMap[Symbol, Set[ClassSymbol]]()
43+
private val superCallsMap = newMutableSymbolMap[Set[ClassSymbol]]
4444
def registerSuperCall(sym: Symbol, calls: ClassSymbol) = {
4545
val old = superCallsMap.getOrElse(sym, Set.empty)
4646
superCallsMap.put(sym, old + calls)

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.put(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
@@ -678,4 +678,70 @@ object Symbols {
678678
def currentClass(implicit ctx: Context): ClassSymbol = ctx.owner.enclosingClass.asClass
679679

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

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)