Skip to content

Use util Collections more widely #9680

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Sep 3, 2020
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ddc849b
Rename HashTable -> IdentityHashMap
odersky Aug 29, 2020
cf671f8
Generalize HashMap
odersky Aug 29, 2020
c48898f
Remove wrong comment
odersky Aug 29, 2020
0e534d8
Break out dual maps in Names#derived into its own LinearMap data type.
odersky Aug 29, 2020
228aee7
Rename Empty -> empty in SimpleIdentityMap
odersky Aug 29, 2020
97cd989
Polish map and set API in dotc.util
odersky Aug 29, 2020
5cd4505
Drop TypeHashSet
odersky Aug 29, 2020
3d469cc
Optimize LinearMap
odersky Aug 29, 2020
660a058
Make util.Set and util.HashSet more usable
odersky Aug 29, 2020
8107048
Use LinearSet instead of mutable.HashSet in TailRec
odersky Aug 29, 2020
9ffbc81
Use HashSet to record seen items
odersky Aug 29, 2020
5470757
Avoid postfixops
odersky Aug 29, 2020
64746d5
Collection tweaks
odersky Aug 30, 2020
f09a336
Increase loadFactor
odersky Aug 30, 2020
c5de2b2
Fix HashMap/Set remove operation
odersky Aug 30, 2020
435820a
Tuning of HashMap operations
odersky Aug 30, 2020
7cf9998
Implement NameTable in terms of HashSet
odersky Aug 30, 2020
0918782
Correct comment
odersky Aug 30, 2020
c8e13d2
Avoid use @volatile in toTypeName
odersky Aug 31, 2020
799c088
Use IdentityHashMaps in pickler
odersky Sep 1, 2020
712cb06
Cache staticRef
odersky Sep 1, 2020
8a5cb06
Drop bounds on HashMap Value type
odersky Sep 2, 2020
abeb4e3
Drop bounds on HashMap Key type
odersky Sep 2, 2020
c75a555
Drop bounds on HashSet entry type
odersky Sep 2, 2020
fa7698e
Drop MutableSymbolMap as a separate class
odersky Sep 2, 2020
b13f68e
Rename IdentityHashMap -> EqHashMap
odersky Sep 2, 2020
8a5d9a2
Use a util.EqHashMap for BaseTypeCache
odersky Sep 2, 2020
30f03e8
Add ReadOnlySet
odersky Sep 3, 2020
785a31b
Convert more sets to util.HashSet
odersky Sep 3, 2020
eebdcba
Fix HashSet.-=
odersky Sep 3, 2020
29ddc17
Convert sets in TreeChecker to util.HashSet
odersky Sep 3, 2020
57c0a43
Convert some mutable.HashMaps to util.HashMaps
odersky Sep 3, 2020
5e2d801
Convert more mutable.HashMaps to util.HashMaps (1)
odersky Sep 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Symbols._
import Phases._

import dotty.tools.dotc.util
import dotty.tools.dotc.util.Spans
import dotty.tools.dotc.util.{Spans, ReadOnlyMap}
import dotty.tools.dotc.report

import Decorators._
Expand All @@ -36,7 +36,7 @@ import Names.TermName
import Annotations.Annotation
import Names.Name

class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: Map[Symbol, Set[ClassSymbol]])(using val ctx: Context) {
class DottyBackendInterface(val outputDirectory: AbstractFile, val superCallsMap: ReadOnlyMap[Symbol, Set[ClassSymbol]])(using val ctx: Context) {

private val desugared = new java.util.IdentityHashMap[Type, tpd.Select]

Expand Down
8 changes: 3 additions & 5 deletions compiler/src/dotty/tools/backend/jvm/GenBCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import dotty.tools.io._
class GenBCode extends Phase {
def phaseName: String = GenBCode.name

private val superCallsMap = newMutableSymbolMap[Set[ClassSymbol]]
private val superCallsMap = new MutableSymbolMap[Set[ClassSymbol]]
def registerSuperCall(sym: Symbol, calls: ClassSymbol): Unit = {
val old = superCallsMap.getOrElse(sym, Set.empty)
superCallsMap.update(sym, old + calls)
Expand All @@ -51,10 +51,8 @@ class GenBCode extends Phase {
}

def run(using Context): Unit =
new GenBCodePipeline(
new DottyBackendInterface(
outputDir, superCallsMap.toMap
)
GenBCodePipeline(
DottyBackendInterface(outputDir, superCallsMap)
).run(ctx.compilationUnit.tpdTree)


Expand Down
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Names.TermName, StdNames._
import Types.{JavaArrayType, UnspecifiedErrorType, Type}
import Symbols.{Symbol, NoSymbol}
import dotc.report
import dotc.util.ReadOnlyMap

import scala.annotation.threadUnsafe
import scala.collection.immutable
Expand All @@ -34,7 +35,7 @@ import scala.collection.immutable
class DottyPrimitives(ictx: Context) {
import dotty.tools.backend.ScalaPrimitivesOps._

@threadUnsafe private lazy val primitives: immutable.Map[Symbol, Int] = init
@threadUnsafe private lazy val primitives: ReadOnlyMap[Symbol, Int] = init

/** Return the code for the given symbol. */
def getPrimitive(sym: Symbol): Int = {
Expand Down Expand Up @@ -118,12 +119,12 @@ class DottyPrimitives(ictx: Context) {
}

/** Initialize the primitive map */
private def init: immutable.Map[Symbol, Int] = {
private def init: ReadOnlyMap[Symbol, Int] = {

given Context = ictx

import Symbols.defn
val primitives = Symbols.newMutableSymbolMap[Int]
val primitives = Symbols.MutableSymbolMap[Int](512)

/** Add a primitive operation to the map */
def addPrimitive(s: Symbol, code: Int): Unit = {
Expand Down Expand Up @@ -394,7 +395,7 @@ class DottyPrimitives(ictx: Context) {
addPrimitives(DoubleClass, nme.UNARY_-, NEG)


primitives.toMap
primitives
}

def isPrimitive(sym: Symbol): Boolean =
Expand Down
9 changes: 5 additions & 4 deletions compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Symbols._
import dotty.tools.dotc.ast.tpd._
import dotty.tools.backend.jvm.DottyPrimitives
import dotty.tools.dotc.report
import dotty.tools.dotc.util.ReadOnlyMap

import scala.collection.mutable

Expand Down Expand Up @@ -55,7 +56,7 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
import JSPrimitives._
import dotty.tools.backend.ScalaPrimitivesOps._

private lazy val jsPrimitives: Map[Symbol, Int] = initJSPrimitives(using ictx)
private lazy val jsPrimitives: ReadOnlyMap[Symbol, Int] = initJSPrimitives(using ictx)

override def getPrimitive(sym: Symbol): Int =
jsPrimitives.getOrElse(sym, super.getPrimitive(sym))
Expand All @@ -70,9 +71,9 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
jsPrimitives.contains(fun.symbol(using ictx)) || super.isPrimitive(fun)

/** Initialize the primitive map */
private def initJSPrimitives(using Context): Map[Symbol, Int] = {
private def initJSPrimitives(using Context): ReadOnlyMap[Symbol, Int] = {

val primitives = newMutableSymbolMap[Int]
val primitives = MutableSymbolMap[Int]()

// !!! Code duplicate with DottyPrimitives
/** Add a primitive operation to the map */
Expand Down Expand Up @@ -120,7 +121,7 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
addPrimitive(jsdefn.ReflectSelectable_selectDynamic, REFLECT_SELECTABLE_SELECTDYN)
addPrimitive(jsdefn.ReflectSelectable_applyDynamic, REFLECT_SELECTABLE_APPLYDYN)

primitives.toMap
primitives
}

}
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Compiler {
List(new Constructors, // Collect initialization code in primary constructors
// Note: constructors changes decls in transformTemplate, no InfoTransformers should be added after it
new FunctionalInterfaces, // Rewrites closures to implement @specialized types of Functions.
new Instrumentation) :: // Count closure allocations under -Yinstrument-closures
new Instrumentation) :: // Count calls and allocations under -Yinstrument
List(new LambdaLift, // Lifts out nested functions to class scope, storing free variables in environments
// Note: in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
new ElimStaticThis, // Replace `this` references to static objects by global identifiers
Expand Down
7 changes: 6 additions & 1 deletion compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import Periods._
import Symbols._
import Types._
import Scopes._
import Names.Name
import Denotations.Denotation
import typer.Typer
import typer.ImportInfo._
import Decorators._
import io.{AbstractFile, PlainFile}
import Phases.unfusedPhases

import scala.io.Codec
import util.{Set => _, _}
import util._
import reporting.Reporter
import rewrites.Rewrites
import java.io.{BufferedWriter, OutputStreamWriter}
Expand Down Expand Up @@ -116,6 +118,9 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
/** The source files of all late entered symbols, as a set */
private var lateFiles = mutable.Set[AbstractFile]()

/** A cache for static references to packages and classes */
val staticRefs = util.EqHashMap[Name, Denotation](initialCapacity = 1024)

/** Actions that need to be performed at the end of the current compilation run */
private var finalizeActions = mutable.ListBuffer[() => Unit]()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package dotc.classpath
import java.net.URL
import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.ArraySeq
import dotc.util

import dotty.tools.io.{ AbstractFile, ClassPath, ClassRepresentation, EfficientClassPath }

Expand Down Expand Up @@ -132,7 +133,7 @@ case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath {
}

private def getDistinctEntries[EntryType <: ClassRepresentation](getEntries: ClassPath => Seq[EntryType]): Seq[EntryType] = {
val seenNames = collection.mutable.HashSet[String]()
val seenNames = util.HashSet[String]()
val entriesBuffer = new ArrayBuffer[EntryType](1024)
for {
cp <- aggregates
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/config/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@ object Config {
/** If set, enables tracing */
inline val tracingEnabled = false

/** Initial capacity of uniques HashMap.
* Note: This MUST BE a power of two to work with util.HashSet
/** Initial capacity of the uniques HashMap.
* Note: This should be a power of two to work with util.HashSet
*/
inline val initialUniquesCapacity = 65536
inline val initialUniquesCapacity = 0x8000

/** How many recursive calls to NamedType#underlying are performed before logging starts. */
inline val LogPendingUnderlyingThreshold = 50
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ class ScalaSettings extends Settings.SettingGroup {

val YnoDecodeStacktraces: Setting[Boolean] = BooleanSetting("-Yno-decode-stacktraces", "Show raw StackOverflow stacktraces, instead of decoding them into triggering operations.")

val YinstrumentClosures: Setting[Boolean] = BooleanSetting("-Yinstrument-closures", "Add instrumentation code that counts closure creations.")
val YinstrumentAllocations: Setting[Boolean] = BooleanSetting("-Yinstrument-allocations", "Add instrumentation code that counts allocations.")
val Yinstrument: Setting[Boolean] = BooleanSetting("-Yinstrument", "Add instrumentation code that counts allocations and closure creations.")

/** Dottydoc specific settings */
val siteRoot: Setting[String] = StringSetting(
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Comments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package core

import ast.{ untpd, tpd }
import Decorators._, Symbols._, Contexts._
import util.SourceFile
import util.{SourceFile, ReadOnlyMap}
import util.Spans._
import util.CommentParsing._
import util.Property.Key
Expand All @@ -23,11 +23,11 @@ object Comments {
*/
class ContextDocstrings {

private val _docstrings: MutableSymbolMap[Comment] = newMutableSymbolMap
private val _docstrings: MutableSymbolMap[Comment] = MutableSymbolMap[Comment](512) // FIXME: 2nd [Comment] needed or "not a class type"

val templateExpander: CommentExpander = new CommentExpander

def docstrings: Map[Symbol, Comment] = _docstrings.toMap
def docstrings: ReadOnlyMap[Symbol, Comment] = _docstrings

def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym)

Expand Down Expand Up @@ -180,7 +180,7 @@ object Comments {
protected def superComment(sym: Symbol)(using Context): Option[String] =
allInheritedOverriddenSymbols(sym).iterator map (x => cookedDocComment(x)) find (_ != "")

private val cookedDocComments = newMutableSymbolMap[String]
private val cookedDocComments = MutableSymbolMap[String]()

/** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by
* missing sections of an inherited doc comment.
Expand Down
37 changes: 13 additions & 24 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Uniques._
import ast.Trees._
import ast.untpd
import Flags.GivenOrImplicit
import util.{NoSource, SimpleIdentityMap, SourceFile}
import util.{NoSource, SimpleIdentityMap, SourceFile, HashSet}
import typer.{Implicits, ImportInfo, Inliner, SearchHistory, SearchRoot, TypeAssigner, Typer, Nullables}
import Nullables.{NotNullInfo, given _}
import Implicits.ContextualImplicits
Expand Down Expand Up @@ -289,7 +289,7 @@ object Contexts {
private def lookup(key: Phase | SourceFile): Context =
util.Stats.record("Context.related.lookup")
if related == null then
related = SimpleIdentityMap.Empty
related = SimpleIdentityMap.empty
null
else
related(key)
Expand Down Expand Up @@ -534,7 +534,7 @@ object Contexts {
def settings: ScalaSettings = base.settings
def definitions: Definitions = base.definitions
def platform: Platform = base.platform
def pendingUnderlying: mutable.HashSet[Type] = base.pendingUnderlying
def pendingUnderlying: util.HashSet[Type] = base.pendingUnderlying
def uniqueNamedTypes: Uniques.NamedTypeUniques = base.uniqueNamedTypes
def uniques: util.HashSet[Type] = base.uniques

Expand Down Expand Up @@ -838,30 +838,18 @@ object Contexts {
def nextSymId: Int = { _nextSymId += 1; _nextSymId }

/** Sources that were loaded */
val sources: mutable.HashMap[AbstractFile, SourceFile] = new mutable.HashMap[AbstractFile, SourceFile]
val sourceNamed: mutable.HashMap[TermName, SourceFile] = new mutable.HashMap[TermName, SourceFile]
val sources: util.HashMap[AbstractFile, SourceFile] = util.HashMap[AbstractFile, SourceFile]()
val sourceNamed: util.HashMap[TermName, SourceFile] = util.HashMap[TermName, SourceFile]()

// Types state
/** A table for hash consing unique types */
private[core] val uniques: util.HashSet[Type] = new util.HashSet[Type](Config.initialUniquesCapacity) {
override def hash(x: Type): Int = x.hash
override def isEqual(x: Type, y: Type) = x.eql(y)
}
private[core] val uniques: Uniques = Uniques()

/** A table for hash consing unique applied types */
private[dotc] val uniqueAppliedTypes: AppliedUniques = new AppliedUniques
private[dotc] val uniqueAppliedTypes: AppliedUniques = AppliedUniques()

/** A table for hash consing unique named types */
private[core] val uniqueNamedTypes: NamedTypeUniques = new NamedTypeUniques

private def uniqueSets = Map(
"uniques" -> uniques,
"uniqueAppliedTypes" -> uniqueAppliedTypes,
"uniqueNamedTypes" -> uniqueNamedTypes)

/** A map that associates label and size of all uniques sets */
def uniquesSizes: Map[String, (Int, Int, Int)] =
uniqueSets.transform((_, s) => (s.size, s.accesses, s.misses))
private[core] val uniqueNamedTypes: NamedTypeUniques = NamedTypeUniques()

var emptyTypeBounds: TypeBounds = null
var emptyWildcardBounds: WildcardType = null
Expand All @@ -881,7 +869,7 @@ object Contexts {

/** The set of named types on which a currently active invocation
* of underlying during a controlled operation exists. */
private[core] val pendingUnderlying: mutable.HashSet[Type] = new mutable.HashSet[Type]
private[core] val pendingUnderlying: util.HashSet[Type] = util.HashSet[Type]()

/** A map from ErrorType to associated message. We use this map
* instead of storing messages directly in ErrorTypes in order
Expand Down Expand Up @@ -925,15 +913,16 @@ object Contexts {
charArray = new Array[Char](charArray.length * 2)
charArray

def reset(): Unit = {
for ((_, set) <- uniqueSets) set.clear()
def reset(): Unit =
uniques.clear()
uniqueAppliedTypes.clear()
uniqueNamedTypes.clear()
emptyTypeBounds = null
emptyWildcardBounds = null
errorTypeMsg.clear()
sources.clear()
sourceNamed.clear()
comparers.clear() // forces re-evaluation of top and bottom classes in TypeComparer
}

// Test that access is single threaded

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1603,7 +1603,7 @@ class Definitions {
valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0

@tu lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] =
SimpleIdentityMap.Empty[Symbol]
SimpleIdentityMap.empty[Symbol]
.updated(AnyClass, ObjectClass)
.updated(AnyValClass, ObjectClass)
.updated(SingletonClass, ObjectClass)
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,8 @@ object Denotations {
}
recurSimple(path.length, wrap)
}
recur(path)
if ctx.run == null then recur(path)
else ctx.run.staticRefs.getOrElseUpdate(path, recur(path))
}


Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/GadtConstraint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ final class ProperGadtConstraint private(
import dotty.tools.dotc.config.Printers.{gadts, gadtsConstr}

def this() = this(
myConstraint = new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
mapping = SimpleIdentityMap.Empty,
reverseMapping = SimpleIdentityMap.Empty
myConstraint = new OrderingConstraint(SimpleIdentityMap.empty, SimpleIdentityMap.empty, SimpleIdentityMap.empty),
mapping = SimpleIdentityMap.empty,
reverseMapping = SimpleIdentityMap.empty
)

/** Exposes ConstraintHandling.subsumes */
Expand Down
17 changes: 8 additions & 9 deletions compiler/src/dotty/tools/dotc/core/NameKinds.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import StdNames._
import NameTags._
import Contexts._
import Decorators._
import collection.mutable

import scala.annotation.internal.sharable

Expand All @@ -18,10 +17,10 @@ object NameKinds {
// These are sharable since all NameKinds are created eagerly at the start of the program
// before any concurrent threads are forked. for this to work, NameKinds should never
// be created lazily or in modules that start running after compilers are forked.
@sharable private val simpleNameKinds = new mutable.HashMap[Int, ClassifiedNameKind]
@sharable private val qualifiedNameKinds = new mutable.HashMap[Int, QualifiedNameKind]
@sharable private val numberedNameKinds = new mutable.HashMap[Int, NumberedNameKind]
@sharable private val uniqueNameKinds = new mutable.HashMap[String, UniqueNameKind]
@sharable private val simpleNameKinds = util.HashMap[Int, ClassifiedNameKind]()
@sharable private val qualifiedNameKinds = util.HashMap[Int, QualifiedNameKind]()
@sharable private val numberedNameKinds = util.HashMap[Int, NumberedNameKind]()
@sharable private val uniqueNameKinds = util.HashMap[String, UniqueNameKind]()

/** A class for the info stored in a derived name */
abstract class NameInfo {
Expand Down Expand Up @@ -393,8 +392,8 @@ object NameKinds {
val Scala2MethodNameKinds: List[NameKind] =
List(DefaultGetterName, ExtMethName, UniqueExtMethName)

def simpleNameKindOfTag : collection.Map[Int, ClassifiedNameKind] = simpleNameKinds
def qualifiedNameKindOfTag : collection.Map[Int, QualifiedNameKind] = qualifiedNameKinds
def numberedNameKindOfTag : collection.Map[Int, NumberedNameKind] = numberedNameKinds
def uniqueNameKindOfSeparator: collection.Map[String, UniqueNameKind] = uniqueNameKinds
def simpleNameKindOfTag : util.ReadOnlyMap[Int, ClassifiedNameKind] = simpleNameKinds
def qualifiedNameKindOfTag : util.ReadOnlyMap[Int, QualifiedNameKind] = qualifiedNameKinds
def numberedNameKindOfTag : util.ReadOnlyMap[Int, NumberedNameKind] = numberedNameKinds
def uniqueNameKindOfSeparator: util.ReadOnlyMap[String, UniqueNameKind] = uniqueNameKinds
}
Loading