Skip to content

Commit ece7c45

Browse files
committed
Add Store to Concept
... and provide a way to initialize contexts when phases are linked.
1 parent 1b9577a commit ece7c45

File tree

4 files changed

+70
-34
lines changed

4 files changed

+70
-34
lines changed

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,30 @@ class Run(comp: Compiler, ictx: Context) {
115115
val phases = ctx.squashPhases(ctx.phasePlan,
116116
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
117117
ctx.usePhases(phases)
118-
var lastPrintedTree: PrintedTree = NoPrintedTree
119-
for (phase <- ctx.allPhases)
120-
if (phase.isRunnable)
121-
Stats.trackTime(s"$phase ms ") {
122-
val start = System.currentTimeMillis
123-
units = phase.runOn(units)
124-
if (ctx.settings.Xprint.value.containsPhase(phase)) {
125-
for (unit <- units) {
126-
lastPrintedTree =
127-
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
118+
119+
def runPhases(implicit ctx: Context) = {
120+
var lastPrintedTree: PrintedTree = NoPrintedTree
121+
for (phase <- ctx.allPhases)
122+
if (phase.isRunnable)
123+
Stats.trackTime(s"$phase ms ") {
124+
val start = System.currentTimeMillis
125+
units = phase.runOn(units)
126+
if (ctx.settings.Xprint.value.containsPhase(phase)) {
127+
for (unit <- units) {
128+
lastPrintedTree =
129+
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
130+
}
128131
}
132+
ctx.informTime(s"$phase ", start)
133+
Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
134+
for (unit <- units)
135+
Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize)
129136
}
130-
ctx.informTime(s"$phase ", start)
131-
Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
132-
for (unit <- units)
133-
Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize)
134-
}
137+
}
138+
139+
val runCtx = ctx.fresh
140+
ctx.phases.foreach(_.initContext(runCtx))
141+
runPhases(runCtx)
135142
if (!ctx.reporter.hasErrors) Rewrites.writeBack()
136143
}
137144

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

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import config.{Settings, ScalaSettings, Platform, JavaPlatform}
3131
import language.implicitConversions
3232
import DenotTransformers.DenotTransformer
3333
import util.Property.Key
34+
import util.Store
3435
import xsbti.AnalysisCallback
3536

3637
object Contexts {
@@ -157,13 +158,6 @@ object Contexts {
157158
protected def runInfo_=(runInfo: RunInfo) = _runInfo = runInfo
158159
def runInfo: RunInfo = _runInfo
159160

160-
/** An optional diagostics buffer than is used by some checking code
161-
* to provide more information in the buffer if it exists.
162-
*/
163-
private[this] var _diagnostics: Option[StringBuilder] = _
164-
protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
165-
def diagnostics: Option[StringBuilder] = _diagnostics
166-
167161
/** The current bounds in force for type parameters appearing in a GADT */
168162
private[this] var _gadt: GADTMap = _
169163
protected def gadt_=(gadt: GADTMap) = _gadt = gadt
@@ -174,6 +168,11 @@ object Contexts {
174168
protected def freshNames_=(freshNames: FreshNameCreator) = _freshNames = freshNames
175169
def freshNames: FreshNameCreator = _freshNames
176170

171+
/** A store that can be used by sub-components */
172+
private var _store: Store = _
173+
protected def store_=(store: Store) = _store = store
174+
def store: Store = _store
175+
177176
/** A map in which more contextual properties can be stored */
178177
private[this] var _moreProperties: Map[Key[Any], Any] = _
179178
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties
@@ -300,13 +299,6 @@ object Contexts {
300299
def isNonEmptyScopeContext: Boolean =
301300
(this.scope ne outer.scope) && !this.scope.isEmpty
302301

303-
/** Leave message in diagnostics buffer if it exists */
304-
def diagnose(str: => String) =
305-
for (sb <- diagnostics) {
306-
sb.setLength(0)
307-
sb.append(str)
308-
}
309-
310302
/** The next outer context whose tree is a template or package definition
311303
* Note: Currently unused
312304
def enclTemplate: Context = {
@@ -406,7 +398,6 @@ object Contexts {
406398
.withSettings(sstate)
407399
// tree is not preserved in condensed
408400
.withRunInfo(runInfo)
409-
.withDiagnostics(diagnostics)
410401
.withMoreProperties(moreProperties)
411402
_condensed
412403
}
@@ -474,12 +465,12 @@ object Contexts {
474465
def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
475466
def setImplicits(implicits: ContextualImplicits): this.type = { this.implicitsCache = implicits; this }
476467
def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
477-
def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
478468
def setGadt(gadt: GADTMap): this.type = { this.gadt = gadt; this }
479469
def setFreshGADTBounds: this.type = setGadt(new GADTMap(gadt.bounds))
480470
def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
481471
def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
482472
def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this }
473+
def setStore(store: Store): this.type = { this.store = store; this }
483474
def setMoreProperties(moreProperties: Map[Key[Any], Any]): this.type = { this.moreProperties = moreProperties; this }
484475

485476
def setProperty[T](key: Key[T], value: T): this.type =
@@ -488,13 +479,21 @@ object Contexts {
488479
def dropProperty(key: Key[_]): this.type =
489480
setMoreProperties(moreProperties - key)
490481

482+
def addLocation[T](initial: T): Store.Location[T] = {
483+
val (loc, store1) = store.newLocation(initial)
484+
setStore(store1)
485+
loc
486+
}
487+
488+
def updateStore[T](loc: Store.Location[T], value: T): this.type =
489+
setStore(store.updated(loc, value))
490+
491491
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
492492
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
493493

494494
def setSetting[T](setting: Setting[T], value: T): this.type =
495495
setSettings(setting.updateIn(sstate, value))
496496

497-
498497
def setDebug = setSetting(base.settings.debug, true)
499498
}
500499

@@ -527,9 +526,9 @@ object Contexts {
527526
tree = untpd.EmptyTree
528527
typeAssigner = TypeAssigner
529528
runInfo = new RunInfo(this)
530-
diagnostics = None
531529
freshNames = new FreshNameCreator.Default
532530
moreProperties = Map.empty
531+
store = Store.empty
533532
typeComparer = new TypeComparer(this)
534533
searchHistory = new SearchHistory(0, Map())
535534
gadt = EmptyGADTMap
@@ -643,7 +642,7 @@ object Contexts {
643642
private[core] var phasesPlan: List[List[Phase]] = _
644643

645644
/** Phases by id */
646-
private[core] var phases: Array[Phase] = _
645+
private[dotc] var phases: Array[Phase] = _
647646

648647
/** Phases with consecutive Transforms grouped into a single phase, Empty array if squashing is disabled */
649648
private[core] var squashedPhases: Array[Phase] = Array.empty[Phase]

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ object Phases {
310310

311311
def exists: Boolean = true
312312

313+
def initContext(ctx: FreshContext): Unit = ()
314+
313315
private[this] var myPeriod: Period = Periods.InvalidPeriod
314316
private[this] var myBase: ContextBase = null
315317
private[this] var myErasedTypes = false
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dotty.tools.dotc.util
2+
3+
object Store {
4+
5+
class Location[T](private[Store] val idx: Int) extends AnyVal
6+
7+
val empty: Store = new Store(Array())
8+
}
9+
10+
class Store(private val elems: Array[AnyRef]) extends AnyVal {
11+
import Store._
12+
13+
def newLocation[T](initial: T): (Location[T], Store) = {
14+
val elems1 = new Array[AnyRef](elems.length + 1)
15+
System.arraycopy(elems, 0, elems1, 0, elems.length)
16+
elems1(elems.length) = initial.asInstanceOf[AnyRef]
17+
(new Location(elems.length), new Store(elems1))
18+
}
19+
20+
def updated[T](loc: Location[T], value: T): Store = {
21+
val elems1 = elems.clone
22+
elems1(loc.idx) = value.asInstanceOf[AnyRef]
23+
new Store(elems1)
24+
}
25+
26+
def apply[T](loc: Location[T]): T =
27+
elems(loc.idx).asInstanceOf[T]
28+
}

0 commit comments

Comments
 (0)