Skip to content

Commit 4c99388

Browse files
authored
Merge pull request #9658 from dotty-staging/opt-tweaks
Some smaller tweaks
2 parents 5274c48 + 5cadcbe commit 4c99388

File tree

5 files changed

+56
-40
lines changed

5 files changed

+56
-40
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,9 @@ object Contexts {
841841
def uniquesSizes: Map[String, (Int, Int, Int)] =
842842
uniqueSets.transform((_, s) => (s.size, s.accesses, s.misses))
843843

844+
var emptyTypeBounds: TypeBounds = null
845+
var emptyWildcardBounds: WildcardType = null
846+
844847
/** Number of findMember calls on stack */
845848
private[core] var findMemberCount: Int = 0
846849

@@ -894,6 +897,8 @@ object Contexts {
894897

895898
def reset(): Unit = {
896899
for ((_, set) <- uniqueSets) set.clear()
900+
emptyTypeBounds = null
901+
emptyWildcardBounds = null
897902
errorTypeMsg.clear()
898903
sources.clear()
899904
sourceNamed.clear()

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

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -229,23 +229,32 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
229229
* and to handle them separately is for efficiency, so that type expressions
230230
* used as bounds become smaller.
231231
*
232+
* TODO: try to do without stripping? It would mean it is more efficient
233+
* to pull out full bounds from a constraint.
234+
*
232235
* @param isUpper If true, `bound` is an upper bound, else a lower bound.
233236
*/
234-
private def stripParams(tp: Type, paramBuf: mutable.ListBuffer[TypeParamRef],
237+
private def stripParams(
238+
tp: Type,
239+
todos: mutable.ListBuffer[(OrderingConstraint, TypeParamRef) => OrderingConstraint],
235240
isUpper: Boolean)(using Context): Type = tp match {
236241
case param: TypeParamRef if contains(param) =>
237-
if (!paramBuf.contains(param)) paramBuf += param
242+
todos += (if isUpper then order(_, _, param) else order(_, param, _))
238243
NoType
244+
case tp: TypeBounds =>
245+
val lo1 = stripParams(tp.lo, todos, !isUpper).orElse(defn.NothingType)
246+
val hi1 = stripParams(tp.hi, todos, isUpper).orElse(defn.AnyKindType)
247+
tp.derivedTypeBounds(lo1, hi1)
239248
case tp: AndType if isUpper =>
240-
val tp1 = stripParams(tp.tp1, paramBuf, isUpper)
241-
val tp2 = stripParams(tp.tp2, paramBuf, isUpper)
249+
val tp1 = stripParams(tp.tp1, todos, isUpper)
250+
val tp2 = stripParams(tp.tp2, todos, isUpper)
242251
if (tp1.exists)
243252
if (tp2.exists) tp.derivedAndType(tp1, tp2)
244253
else tp1
245254
else tp2
246255
case tp: OrType if !isUpper =>
247-
val tp1 = stripParams(tp.tp1, paramBuf, isUpper)
248-
val tp2 = stripParams(tp.tp2, paramBuf, isUpper)
256+
val tp1 = stripParams(tp.tp1, todos, isUpper)
257+
val tp2 = stripParams(tp.tp2, todos, isUpper)
249258
if (tp1.exists)
250259
if (tp2.exists) tp.derivedOrType(tp1, tp2)
251260
else tp1
@@ -254,17 +263,6 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
254263
tp
255264
}
256265

257-
/** The bound type `tp` without clearly dependent parameters.
258-
* A top or bottom type if type consists only of dependent parameters.
259-
* TODO: try to do without normalization? It would mean it is more efficient
260-
* to pull out full bounds from a constraint.
261-
* @param isUpper If true, `bound` is an upper bound, else a lower bound.
262-
*/
263-
private def normalizedType(tp: Type, paramBuf: mutable.ListBuffer[TypeParamRef],
264-
isUpper: Boolean)(using Context): Type =
265-
stripParams(tp, paramBuf, isUpper)
266-
.orElse(if (isUpper) defn.AnyKindType else defn.NothingType)
267-
268266
def add(poly: TypeLambda, tvars: List[TypeVar])(using Context): This = {
269267
assert(!contains(poly))
270268
val nparams = poly.paramNames.length
@@ -280,18 +278,15 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
280278
*/
281279
private def init(poly: TypeLambda)(using Context): This = {
282280
var current = this
283-
val loBuf, hiBuf = new mutable.ListBuffer[TypeParamRef]
281+
val todos = new mutable.ListBuffer[(OrderingConstraint, TypeParamRef) => OrderingConstraint]
284282
var i = 0
285283
while (i < poly.paramNames.length) {
286284
val param = poly.paramRefs(i)
287-
val bounds = nonParamBounds(param)
288-
val lo = normalizedType(bounds.lo, loBuf, isUpper = false)
289-
val hi = normalizedType(bounds.hi, hiBuf, isUpper = true)
290-
current = updateEntry(current, param, bounds.derivedTypeBounds(lo, hi))
291-
current = loBuf.foldLeft(current)(order(_, _, param))
292-
current = hiBuf.foldLeft(current)(order(_, param, _))
293-
loBuf.clear()
294-
hiBuf.clear()
285+
val stripped = stripParams(nonParamBounds(param), todos, isUpper = true)
286+
current = updateEntry(current, param, stripped)
287+
while todos.nonEmpty do
288+
current = todos.head(current, param)
289+
todos.dropInPlace(1)
295290
i += 1
296291
}
297292
current.checkNonCyclic()

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,15 @@ object Types {
263263

264264
/** Is this type exactly Nothing (no vars, aliases, refinements etc allowed)? */
265265
def isBottomType(using Context): Boolean = this match {
266-
case tp: TypeRef => tp.symbol eq defn.NothingClass
266+
case tp: TypeRef =>
267+
tp.name == tpnme.Nothing && (tp.symbol eq defn.NothingClass)
267268
case _ => false
268269
}
269270

270271
/** Is this type exactly Any (no vars, aliases, refinements etc allowed)? */
271272
def isTopType(using Context): Boolean = this match {
272-
case tp: TypeRef => tp.symbol eq defn.AnyClass
273+
case tp: TypeRef =>
274+
tp.name == tpnme.Any && (tp.symbol eq defn.AnyClass)
273275
case _ => false
274276
}
275277

@@ -4647,7 +4649,13 @@ object Types {
46474649
object TypeBounds {
46484650
def apply(lo: Type, hi: Type)(using Context): TypeBounds =
46494651
unique(new RealTypeBounds(lo, hi))
4650-
def empty(using Context): TypeBounds = apply(defn.NothingType, defn.AnyType)
4652+
def empty(using Context): TypeBounds =
4653+
val result = ctx.base.emptyTypeBounds
4654+
if result == null then
4655+
ctx.base.emptyTypeBounds = apply(defn.NothingType, defn.AnyType)
4656+
empty
4657+
else
4658+
result
46514659
def emptyPolyKind(using Context): TypeBounds = apply(defn.NothingType, defn.AnyKindType)
46524660
def upper(hi: Type)(using Context): TypeBounds = apply(defn.NothingType, hi)
46534661
def lower(lo: Type)(using Context): TypeBounds = apply(lo, defn.AnyType)
@@ -4790,7 +4798,15 @@ object Types {
47904798
final class CachedWildcardType(optBounds: Type) extends WildcardType(optBounds)
47914799

47924800
@sharable object WildcardType extends WildcardType(NoType) {
4793-
def apply(bounds: TypeBounds)(using Context): WildcardType = unique(new CachedWildcardType(bounds))
4801+
def apply(bounds: TypeBounds)(using Context): WildcardType =
4802+
if bounds eq TypeBounds.empty then
4803+
val result = ctx.base.emptyWildcardBounds
4804+
if result == null then
4805+
ctx.base.emptyWildcardBounds = unique(CachedWildcardType(bounds))
4806+
apply(bounds)
4807+
else
4808+
result
4809+
else unique(CachedWildcardType(bounds))
47944810
}
47954811

47964812
/** An extractor for single abstract method types.

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import NameKinds._
2121
import NamerOps._
2222
import ContextOps._
2323
import Variances.Invariant
24+
import TastyUnpickler.NameTable
2425
import typer.ConstFold
2526
import typer.Checking.checkNonCyclic
2627
import util.Spans._
@@ -51,7 +52,7 @@ import scala.annotation.internal.sharable
5152
* @param commentUnpicklerOpt the unpickler for comments, if it exists
5253
*/
5354
class TreeUnpickler(reader: TastyReader,
54-
nameAtRef: NameRef => TermName,
55+
nameAtRef: NameTable,
5556
posUnpicklerOpt: Option[PositionUnpickler],
5657
commentUnpicklerOpt: Option[CommentUnpickler]) {
5758
import TreeUnpickler._
@@ -557,7 +558,7 @@ class TreeUnpickler(reader: TastyReader,
557558
val rhsStart = currentAddr
558559
val rhsIsEmpty = nothingButMods(end)
559560
if (!rhsIsEmpty) skipTree()
560-
val (givenFlags, annotFns, privateWithin) = readModifiers(end, readTypedAnnot, readTypedWithin, NoSymbol)
561+
val (givenFlags, annotFns, privateWithin) = readModifiers(end)
561562
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
562563
val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
563564
def adjustIfModule(completer: LazyType) =
@@ -608,12 +609,10 @@ class TreeUnpickler(reader: TastyReader,
608609
/** Read modifier list into triplet of flags, annotations and a privateWithin
609610
* boundary symbol.
610611
*/
611-
def readModifiers[WithinType, AnnotType]
612-
(end: Addr, readAnnot: Context ?=> Symbol => AnnotType, readWithin: Context ?=> WithinType, defaultWithin: WithinType)
613-
(using Context): (FlagSet, List[Symbol => AnnotType], WithinType) = {
612+
def readModifiers(end: Addr)(using Context): (FlagSet, List[Symbol => Annotation], Symbol) = {
614613
var flags: FlagSet = EmptyFlags
615-
var annotFns: List[Symbol => AnnotType] = Nil
616-
var privateWithin = defaultWithin
614+
var annotFns: List[Symbol => Annotation] = Nil
615+
var privateWithin: Symbol = NoSymbol
617616
while (currentAddr.index != end.index) {
618617
def addFlag(flag: FlagSet) = {
619618
flags |= flag
@@ -676,9 +675,9 @@ class TreeUnpickler(reader: TastyReader,
676675
(flags, annotFns.reverse, privateWithin)
677676
}
678677

679-
private val readTypedWithin: Context ?=> Symbol = readType().typeSymbol
678+
private def readWithin(using Context): Symbol = readType().typeSymbol
680679

681-
private val readTypedAnnot: Context ?=> Symbol => Annotation =
680+
private def readAnnot(using Context): Symbol => Annotation =
682681
readByte()
683682
val end = readEnd()
684683
val tp = readType()

compiler/src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ abstract class Reporter extends interfaces.ReporterResult {
202202

203203
/** Issue all error messages in this reporter to next outer one, or make sure they are written. */
204204
def flush()(using Context): Unit =
205-
removeBufferedMessages.foreach(ctx.reporter.report)
205+
val msgs = removeBufferedMessages
206+
if msgs.nonEmpty then msgs.foreach(ctx.reporter.report)
206207

207208
/** If this reporter buffers messages, all buffered messages, otherwise Nil */
208209
def pendingMessages(using Context): List[Diagnostic] = Nil

0 commit comments

Comments
 (0)