Skip to content

Avoid some hot closure creations #9593

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 6 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import reporting.trace
import dotty.tools.dotc.transform.SymUtils._
import Decorators._
import Constants.Constant
import scala.collection.mutable

import scala.annotation.tailrec

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

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

/** If `tree` is a DefTree, the symbol defined by it, otherwise NoSymbol */
def definedSym(tree: Tree)(using Context): Symbol =
Expand Down
13 changes: 11 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,11 @@ object Trees {
override def isEmpty: Boolean = trees.isEmpty
override def toList: List[Tree[T]] = flatten(trees)
override def toString: String = if (isEmpty) "EmptyTree" else "Thicket(" + trees.mkString(", ") + ")"
override def span: Span = trees.foldLeft(NoSpan) ((span, t) => span union t.span)
override def span: Span =
def combine(s: Span, ts: List[Tree[T]]): Span = ts match
case t :: ts1 => combine(s.union(t.span), ts1)
case nil => s
combine(NoSpan, trees)

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

def apply(x: X, trees: Traversable[Tree])(using Context): X = trees.foldLeft(x)(apply)
def apply(x: X, trees: List[Tree])(using Context): X = trees match
case tree :: rest =>
apply(apply(x, tree), rest)
case Nil =>
x

def foldOver(x: X, tree: Tree)(using Context): X =
if (tree.source != ctx.source && tree.source.exists)
foldOver(x, tree)(using ctx.withSource(tree.source))
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ object Feature:

def sourceVersion(using Context): SourceVersion =
if ctx.compilationUnit == null then sourceVersionSetting
else ctx.compilationUnit.sourceVersion.getOrElse(sourceVersionSetting)
else ctx.compilationUnit.sourceVersion match
case Some(v) => v
case none => sourceVersionSetting

def migrateTo3(using Context): Boolean =
sourceVersion == `3.0-migration` || enabledBySetting(nme.Scala2Compat)
Expand Down
24 changes: 12 additions & 12 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -680,11 +680,8 @@ object Contexts {
final def retractMode(mode: Mode): c.type = c.setMode(c.mode &~ mode)
}

/** Test `op` in a fresh context with a typerstate that is not committable.
* The passed context may not survive the operation.
*/
def explore[T](op: Context ?=> T)(using Context): T =
util.Stats.record("Context.test")
private def exploreCtx(using Context): Context =
util.Stats.record("explore")
val base = ctx.base
import base._
val nestedCtx =
Expand All @@ -700,13 +697,15 @@ object Contexts {
exploresInUse += 1
val nestedTS = nestedCtx.typerState
nestedTS.init(ctx.typerState, ctx.typerState.constraint)
val result =
try op(using nestedCtx)
finally
nestedTS.reporter.asInstanceOf[ExploringReporter].reset()
exploresInUse -= 1
result
end explore
nestedCtx

private def wrapUpExplore(ectx: Context) =
ectx.reporter.asInstanceOf[ExploringReporter].reset()
ectx.base.exploresInUse -= 1

inline def explore[T](inline op: Context ?=> T)(using Context): T =
val ectx = exploreCtx
try op(using ectx) finally wrapUpExplore(ectx)

/** The type comparer of the kind created by `maker` to be used.
* This is the currently active type comparer CMP if
Expand All @@ -716,6 +715,7 @@ object Contexts {
* In other words: tracking or explaining is a sticky property in the same context.
*/
private def comparer(using Context): TypeComparer =
util.Stats.record("comparing")
val base = ctx.base
if base.comparersInUse > 0
&& (base.comparers(base.comparersInUse - 1).comparerContext eq ctx)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ object Denotations {
* single-denotations that do not satisfy the predicate are left alone
* (whereas suchThat would map them to NoDenotation).
*/
def disambiguate(p: Symbol => Boolean)(using Context): SingleDenotation = this match {
inline def disambiguate(inline p: Symbol => Boolean)(using Context): SingleDenotation = this match {
case sdenot: SingleDenotation => sdenot
case mdenot => suchThat(p) orElse NoQualifyingRef(alternatives)
}
Expand Down