Skip to content

Commit 318db7d

Browse files
committed
Memoizing Context#withPhase
withPhase operations in contexts are now memoized. Conflicts: src/dotty/tools/dotc/core/Contexts.scala
1 parent d173cc0 commit 318db7d

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

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

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,30 @@ object Contexts {
181181
protected def searchHistory_= (searchHistory: SearchHistory) = _searchHistory = searchHistory
182182
def searchHistory: SearchHistory = _searchHistory
183183

184+
private var phasedCtx: Context = _
185+
private var phasedCtxs: Array[Context] = _
186+
187+
188+
/** This context at given phase.
189+
* This method will always return a phase period equal to phaseId, thus will never return squashed phases
190+
*/
191+
final def withPhase(phaseId: PhaseId): Context = {
192+
if (this.phaseId == phaseId) this
193+
else if (phasedCtx.phaseId == phaseId) phasedCtx
194+
else if (phasedCtxs != null && phasedCtxs(phaseId) != null) phasedCtxs(phaseId)
195+
else {
196+
val ctx1 = fresh.setPhase(phaseId)
197+
if (phasedCtx eq this) phasedCtx = ctx1
198+
else {
199+
if (phasedCtxs == null) phasedCtxs = new Array[Context](base.phases.length)
200+
phasedCtxs(phaseId) = ctx1
201+
}
202+
ctx1
203+
}
204+
}
205+
206+
final def withPhase(phase: Phase): Context =
207+
withPhase(phase.id)
184208
/** If -Ydebug is on, the top of the stack trace where this context
185209
* was created, otherwise `null`.
186210
*/
@@ -266,32 +290,23 @@ object Contexts {
266290
}
267291
*/
268292

269-
/** A fresh clone of this context. */
270-
def fresh: FreshContext = {
271-
val newctx: Context = super.clone.asInstanceOf[FreshContext]
272-
newctx.outer = this
273-
newctx.implicitsCache = null
274-
newctx.setCreationTrace()
275-
// Dotty deviation: Scala2x allows access to private members implicitCache and setCreationTrace
276-
// even from a subclass prefix. Dotty (and Java) do not. It's confirmed as a bug in Scala2x.
277-
newctx.asInstanceOf[FreshContext]
293+
protected def init(outer: Context): this.type = {
294+
this.outer = outer
295+
this.implicitsCache = null
296+
this.phasedCtx = this
297+
this.phasedCtxs = null
298+
setCreationTrace()
299+
this
278300
}
301+
/** A fresh clone of this context. */
302+
def fresh: FreshContext = clone.asInstanceOf[FreshContext].init(this)
279303

280304
final def withOwner(owner: Symbol): Context =
281305
if (owner ne this.owner) fresh.setOwner(owner) else this
282306

283307
final def withMode(mode: Mode): Context =
284308
if (mode != this.mode) fresh.setMode(mode) else this
285309

286-
/**
287-
* This method will always return a phase period equal to phaseId, thus will never return squashed phases
288-
*/
289-
final def withPhase(phaseId: PhaseId): Context =
290-
if (this.phaseId == phaseId) this else fresh.setPhase(phaseId)
291-
final def withPhase(phase: Phase): Context =
292-
if (this.period == phase.period) this else fresh.setPhase(phase)
293-
294-
295310
final def addMode(mode: Mode): Context = withMode(this.mode | mode)
296311
final def maskMode(mode: Mode): Context = withMode(this.mode & mode)
297312
final def retractMode(mode: Mode): Context = withMode(this.mode &~ mode)

0 commit comments

Comments
 (0)