Skip to content

Commit 7cdab7f

Browse files
authored
Merge pull request #9593 from dotty-staging/optimze-reduce-closures
Avoid some hot closure creations
2 parents 2240b29 + 0fc0c0c commit 7cdab7f

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import reporting.trace
1010
import dotty.tools.dotc.transform.SymUtils._
1111
import Decorators._
1212
import Constants.Constant
13+
import scala.collection.mutable
1314

1415
import scala.annotation.tailrec
1516

@@ -698,7 +699,10 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
698699

699700
/** The symbols defined locally in a statement list */
700701
def localSyms(stats: List[Tree])(using Context): List[Symbol] =
701-
for (stat <- stats if stat.isDef && stat.symbol.exists) yield stat.symbol
702+
val locals = new mutable.ListBuffer[Symbol]
703+
for stat <- stats do
704+
if stat.isDef && stat.symbol.exists then locals += stat.symbol
705+
locals.toList
702706

703707
/** If `tree` is a DefTree, the symbol defined by it, otherwise NoSymbol */
704708
def definedSym(tree: Tree)(using Context): Symbol =

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,11 @@ object Trees {
846846
override def isEmpty: Boolean = trees.isEmpty
847847
override def toList: List[Tree[T]] = flatten(trees)
848848
override def toString: String = if (isEmpty) "EmptyTree" else "Thicket(" + trees.mkString(", ") + ")"
849-
override def span: Span = trees.foldLeft(NoSpan) ((span, t) => span union t.span)
849+
override def span: Span =
850+
def combine(s: Span, ts: List[Tree[T]]): Span = ts match
851+
case t :: ts1 => combine(s.union(t.span), ts1)
852+
case nil => s
853+
combine(NoSpan, trees)
850854

851855
override def withSpan(span: Span): this.type =
852856
mapElems(_.withSpan(span)).asInstanceOf[this.type]
@@ -1375,7 +1379,12 @@ object Trees {
13751379
// Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node.
13761380
def apply(x: X, tree: Tree)(using Context): X
13771381

1378-
def apply(x: X, trees: Traversable[Tree])(using Context): X = trees.foldLeft(x)(apply)
1382+
def apply(x: X, trees: List[Tree])(using Context): X = trees match
1383+
case tree :: rest =>
1384+
apply(apply(x, tree), rest)
1385+
case Nil =>
1386+
x
1387+
13791388
def foldOver(x: X, tree: Tree)(using Context): X =
13801389
if (tree.source != ctx.source && tree.source.exists)
13811390
foldOver(x, tree)(using ctx.withSource(tree.source))

compiler/src/dotty/tools/dotc/config/Feature.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ object Feature:
6868

6969
def sourceVersion(using Context): SourceVersion =
7070
if ctx.compilationUnit == null then sourceVersionSetting
71-
else ctx.compilationUnit.sourceVersion.getOrElse(sourceVersionSetting)
71+
else ctx.compilationUnit.sourceVersion match
72+
case Some(v) => v
73+
case none => sourceVersionSetting
7274

7375
def migrateTo3(using Context): Boolean =
7476
sourceVersion == `3.0-migration` || enabledBySetting(nme.Scala2Compat)

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,8 @@ object Contexts {
680680
final def retractMode(mode: Mode): c.type = c.setMode(c.mode &~ mode)
681681
}
682682

683-
/** Test `op` in a fresh context with a typerstate that is not committable.
684-
* The passed context may not survive the operation.
685-
*/
686-
def explore[T](op: Context ?=> T)(using Context): T =
687-
util.Stats.record("Context.test")
683+
private def exploreCtx(using Context): Context =
684+
util.Stats.record("explore")
688685
val base = ctx.base
689686
import base._
690687
val nestedCtx =
@@ -700,13 +697,15 @@ object Contexts {
700697
exploresInUse += 1
701698
val nestedTS = nestedCtx.typerState
702699
nestedTS.init(ctx.typerState, ctx.typerState.constraint)
703-
val result =
704-
try op(using nestedCtx)
705-
finally
706-
nestedTS.reporter.asInstanceOf[ExploringReporter].reset()
707-
exploresInUse -= 1
708-
result
709-
end explore
700+
nestedCtx
701+
702+
private def wrapUpExplore(ectx: Context) =
703+
ectx.reporter.asInstanceOf[ExploringReporter].reset()
704+
ectx.base.exploresInUse -= 1
705+
706+
inline def explore[T](inline op: Context ?=> T)(using Context): T =
707+
val ectx = exploreCtx
708+
try op(using ectx) finally wrapUpExplore(ectx)
710709

711710
/** The type comparer of the kind created by `maker` to be used.
712711
* This is the currently active type comparer CMP if
@@ -716,6 +715,7 @@ object Contexts {
716715
* In other words: tracking or explaining is a sticky property in the same context.
717716
*/
718717
private def comparer(using Context): TypeComparer =
718+
util.Stats.record("comparing")
719719
val base = ctx.base
720720
if base.comparersInUse > 0
721721
&& (base.comparers(base.comparersInUse - 1).comparerContext eq ctx)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ object Denotations {
277277
* single-denotations that do not satisfy the predicate are left alone
278278
* (whereas suchThat would map them to NoDenotation).
279279
*/
280-
def disambiguate(p: Symbol => Boolean)(using Context): SingleDenotation = this match {
280+
inline def disambiguate(inline p: Symbol => Boolean)(using Context): SingleDenotation = this match {
281281
case sdenot: SingleDenotation => sdenot
282282
case mdenot => suchThat(p) orElse NoQualifyingRef(alternatives)
283283
}

0 commit comments

Comments
 (0)