Skip to content

Commit d50bd76

Browse files
authored
Merge pull request #9605 from dotty-staging/various-ops-1
Various small optimizations
2 parents 7815b6a + 41aba4b commit d50bd76

File tree

8 files changed

+45
-40
lines changed

8 files changed

+45
-40
lines changed

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ object Contexts {
4949
private val (profilerLoc, store7) = store6.newLocation[Profiler]()
5050
private val (notNullInfosLoc, store8) = store7.newLocation[List[NotNullInfo]]()
5151
private val (importInfoLoc, store9) = store8.newLocation[ImportInfo]()
52+
private val (typeAssignerLoc, store10) = store9.newLocation[TypeAssigner](TypeAssigner)
5253

53-
private val initialStore = store9
54+
private val initialStore = store10
5455

5556
/** The current context */
5657
inline def ctx(using ctx: Context): Context = ctx
@@ -157,11 +158,6 @@ object Contexts {
157158
protected def typerState_=(typerState: TyperState): Unit = _typerState = typerState
158159
final def typerState: TyperState = _typerState
159160

160-
/** The current type assigner or typer */
161-
private var _typeAssigner: TypeAssigner = _
162-
protected def typeAssigner_=(typeAssigner: TypeAssigner): Unit = _typeAssigner = typeAssigner
163-
final def typeAssigner: TypeAssigner = _typeAssigner
164-
165161
/** The current bounds in force for type parameters appearing in a GADT */
166162
private var _gadt: GadtConstraint = _
167163
protected def gadt_=(gadt: GadtConstraint): Unit = _gadt = gadt
@@ -228,6 +224,9 @@ object Contexts {
228224
/** The currently active import info */
229225
def importInfo = store(importInfoLoc)
230226

227+
/** The current type assigner or typer */
228+
def typeAssigner: TypeAssigner = store(typeAssignerLoc)
229+
231230
/** The new implicit references that are introduced by this scope */
232231
protected var implicitsCache: ContextualImplicits = null
233232
def implicits: ContextualImplicits = {
@@ -483,7 +482,6 @@ object Contexts {
483482
_owner = origin.owner
484483
_tree = origin.tree
485484
_scope = origin.scope
486-
_typeAssigner = origin.typeAssigner
487485
_gadt = origin.gadt
488486
_searchHistory = origin.searchHistory
489487
_source = origin.source
@@ -574,10 +572,6 @@ object Contexts {
574572
def setNewTyperState(): this.type = setTyperState(typerState.fresh().setCommittable(true))
575573
def setExploreTyperState(): this.type = setTyperState(typerState.fresh().setCommittable(false))
576574
def setReporter(reporter: Reporter): this.type = setTyperState(typerState.fresh().setReporter(reporter))
577-
def setTypeAssigner(typeAssigner: TypeAssigner): this.type =
578-
util.Stats.record("Context.setTypeAssigner")
579-
this.typeAssigner = typeAssigner
580-
this
581575
def setTyper(typer: Typer): this.type = { this.scope = typer.scope; setTypeAssigner(typer) }
582576
def setGadt(gadt: GadtConstraint): this.type =
583577
util.Stats.record("Context.setGadt")
@@ -615,6 +609,7 @@ object Contexts {
615609
def setProfiler(profiler: Profiler): this.type = updateStore(profilerLoc, profiler)
616610
def setNotNullInfos(notNullInfos: List[NotNullInfo]): this.type = updateStore(notNullInfosLoc, notNullInfos)
617611
def setImportInfo(importInfo: ImportInfo): this.type = updateStore(importInfoLoc, importInfo)
612+
def setTypeAssigner(typeAssigner: TypeAssigner): this.type = updateStore(typeAssignerLoc, typeAssigner)
618613

619614
def setProperty[T](key: Key[T], value: T): this.type =
620615
setMoreProperties(moreProperties.updated(key, value))
@@ -742,7 +737,6 @@ object Contexts {
742737
typerState = TyperState.initialState()
743738
owner = NoSymbol
744739
tree = untpd.EmptyTree
745-
typeAssigner = TypeAssigner
746740
moreProperties = Map(MessageLimiter -> DefaultMessageLimiter())
747741
source = NoSource
748742
store = initialStore

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,11 +1050,15 @@ class Definitions {
10501050
def scalaClassName(ref: Type)(using Context): TypeName = scalaClassName(ref.classSymbol)
10511051

10521052
private def isVarArityClass(cls: Symbol, prefix: String) =
1053-
cls.isClass && cls.owner.eq(ScalaPackageClass) &&
1054-
cls.name.testSimple(name =>
1055-
name.startsWith(prefix) &&
1056-
name.length > prefix.length &&
1057-
name.drop(prefix.length).forall(_.isDigit))
1053+
cls.isClass
1054+
&& cls.owner.eq(ScalaPackageClass)
1055+
&& cls.name.testSimple(name =>
1056+
name.startsWith(prefix)
1057+
&& name.length > prefix.length
1058+
&& digitsOnlyAfter(name, prefix.length))
1059+
1060+
private def digitsOnlyAfter(name: SimpleName, idx: Int): Boolean =
1061+
idx == name.length || name(idx).isDigit && digitsOnlyAfter(name, idx + 1)
10581062

10591063
def isBottomClass(cls: Symbol): Boolean =
10601064
if (ctx.explicitNulls && !ctx.phase.erasedTypes) cls == NothingClass

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
567567

568568
def foreachTypeVar(op: TypeVar => Unit): Unit =
569569
boundsMap.foreachBinding { (poly, entries) =>
570-
for (i <- 0 until paramCount(entries))
571-
typeVar(entries, i) match {
570+
var i = 0
571+
val limit = paramCount(entries)
572+
while i < limit do
573+
typeVar(entries, i) match
572574
case tv: TypeVar if !tv.inst.exists => op(tv)
573575
case _ =>
574-
}
576+
i += 1
575577
}
576578

577579
private var myUninstVars: mutable.ArrayBuffer[TypeVar] = _

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ object Scopes {
138138
def next(): Symbol = { val r = e.sym; e = lookupNextEntry(e); r }
139139
}
140140

141+
/** Does this scope contain a reference to `sym` when looking up `name`? */
142+
final def contains(name: Name, sym: Symbol)(using Context): Boolean =
143+
var e = lookupEntry(name)
144+
while e != null && e.sym != sym do e = lookupNextEntry(e)
145+
e != null
146+
141147
/** The denotation set of all the symbols with given name in this scope
142148
* Symbols occur in the result in reverse order relative to their occurrence
143149
* in `this.toList`.

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,19 +2361,17 @@ object SymDenotations {
23612361
stillValidInOwner(denot)
23622362
}
23632363

2364-
private[SymDenotations] def stillValidInOwner(denot: SymDenotation)(using Context): Boolean = try {
2364+
private[SymDenotations] def stillValidInOwner(denot: SymDenotation)(using Context): Boolean = try
23652365
val owner = denot.owner.denot
2366-
stillValid(owner) && (
2366+
stillValid(owner)
2367+
&& (
23672368
!owner.isClass
23682369
|| owner.isRefinementClass
23692370
|| owner.is(Scala2x)
2370-
|| (owner.unforcedDecls.lookupAll(denot.name) contains denot.symbol)
2371+
|| owner.unforcedDecls.contains(denot.name, denot.symbol)
23712372
|| denot.isSelfSym
23722373
|| denot.isLocalDummy)
2373-
}
2374-
catch {
2375-
case ex: StaleSymbol => false
2376-
}
2374+
catch case ex: StaleSymbol => false
23772375

23782376
/** Explain why symbol is invalid; used for debugging only */
23792377
def traceInvalid(denot: Denotation)(using Context): Boolean = {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Instrumentation extends MiniPhase { thisPhase =>
2929
ctx.settings.YinstrumentAllocations.value
3030

3131
private val namesOfInterest = List(
32-
"::", "+=", "toString", "newArray", "box",
32+
"::", "+=", "toString", "newArray", "box", "toCharArray",
3333
"map", "flatMap", "filter", "withFilter", "collect", "foldLeft", "foldRight", "take",
3434
"reverse", "mapConserve", "mapconserve", "filterConserve", "zip")
3535
private var namesToRecord: Set[Name] = _

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,7 +2599,7 @@ class Typer extends Namer
25992599

26002600
def typedStats(stats: List[untpd.Tree], exprOwner: Symbol)(using Context): (List[Tree], Context) = {
26012601
val buf = new mutable.ListBuffer[Tree]
2602-
val enumContexts = new mutable.HashMap[Symbol, Context]
2602+
var enumContexts: SimpleIdentityMap[Symbol, Context] = SimpleIdentityMap.Empty
26032603
val initialNotNullInfos = ctx.notNullInfos
26042604
// A map from `enum` symbols to the contexts enclosing their definitions
26052605
@tailrec def traverse(stats: List[untpd.Tree])(using Context): (List[Tree], Context) = stats match {
@@ -2621,7 +2621,7 @@ class Typer extends Namer
26212621
// replace body with expansion, because it will be used as inlined body
26222622
// from separately compiled files - the original BodyAnnotation is not kept.
26232623
case mdef1: TypeDef if mdef1.symbol.is(Enum, butNot = Case) =>
2624-
enumContexts(mdef1.symbol) = ctx
2624+
enumContexts = enumContexts.updated(mdef1.symbol, ctx)
26252625
buf += mdef1
26262626
case EmptyTree =>
26272627
// clashing synthetic case methods are converted to empty trees, drop them here
@@ -2653,7 +2653,8 @@ class Typer extends Namer
26532653
}
26542654
def finalize(stat: Tree)(using Context): Tree = stat match {
26552655
case stat: TypeDef if stat.symbol.is(Module) =>
2656-
for (enumContext <- enumContexts.get(stat.symbol.linkedClass))
2656+
val enumContext = enumContexts(stat.symbol.linkedClass)
2657+
if enumContext != null then
26572658
checkEnumCaseRefsLegal(stat, enumContext)
26582659
stat.removeAttachment(Deriver) match {
26592660
case Some(deriver) => deriver.finalize(stat)

compiler/src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,18 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
103103
def positionInUltimateSource(position: SourcePosition): SourcePosition =
104104
SourcePosition(underlying, position.span shift start)
105105

106-
private def isLineBreak(idx: Int) =
107-
if (idx >= length) false else {
108-
val ch = content()(idx)
109-
// don't identify the CR in CR LF as a line break, since LF will do.
110-
if (ch == CR) (idx + 1 == length) || (content()(idx + 1) != LF)
111-
else isLineBreakChar(ch)
112-
}
113-
114106
private def calculateLineIndices(cs: Array[Char]) = {
115107
val buf = new ArrayBuffer[Int]
116108
buf += 0
117-
for (i <- 0 until cs.length) if (isLineBreak(i)) buf += i + 1
109+
var i = 0
110+
while i < cs.length do
111+
val isLineBreak =
112+
val ch = cs(i)
113+
// don't identify the CR in CR LF as a line break, since LF will do.
114+
if ch == CR then i + 1 == cs.length || cs(i + 1) != LF
115+
else isLineBreakChar(ch)
116+
if isLineBreak then buf += i + 1
117+
i += 1
118118
buf += cs.length // sentinel, so that findLine below works smoother
119119
buf.toArray
120120
}

0 commit comments

Comments
 (0)