diff options
author | odersky <odersky@gmail.com> | 2016-04-16 13:43:06 +0200 |
---|---|---|
committer | odersky <odersky@gmail.com> | 2016-04-16 13:43:06 +0200 |
commit | b98e6bfe13fbb7383fd1860df349bfa67ee96c91 (patch) | |
tree | 3b9637f7e1e5d45abb5be5a3b856f81810615d4c /src | |
parent | 3ef41153463fbc89a3dda3a648ae0320aef95555 (diff) | |
parent | 27e5c212de05f10177b9ca4375638a2e46929543 (diff) | |
download | dotty-b98e6bfe13fbb7383fd1860df349bfa67ee96c91.tar.gz dotty-b98e6bfe13fbb7383fd1860df349bfa67ee96c91.tar.bz2 dotty-b98e6bfe13fbb7383fd1860df349bfa67ee96c91.zip |
Merge pull request #1200 from dotty-staging/docs-denotations
Docs and polishing for denotation insertions
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 218fb8561..6e7eed3bc 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -655,8 +655,7 @@ object Denotations { next.resetFlag(Frozen) case _ => } - next.nextInRun = cur.nextInRun - cur.nextInRun = next + next.insertAfter(cur) cur = next } cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId) @@ -672,6 +671,10 @@ object Denotations { while (!(cur.validFor contains currentPeriod)) { //println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}") cur = cur.nextInRun + // Note: One might be tempted to add a `prev` field to get to the new denotation + // more directly here. I tried that, but it degrades rather than improves + // performance: Test setup: Compile everything in dotc and immediate subdirectories + // 10 times. Best out of 10: 18154ms with `prev` field, 17777ms without. cnt += 1 if (cnt > MaxPossiblePhaseId) return NotDefinedHereDenotation } @@ -708,12 +711,10 @@ object Denotations { // printPeriods(current) this.validFor = Period(ctx.runId, targetId, current.validFor.lastPhaseId) if (current.validFor.firstPhaseId >= targetId) - replaceDenotation(current) + insertInsteadOf(current) else { - // insert this denotation after current current.validFor = Period(ctx.runId, current.validFor.firstPhaseId, targetId - 1) - this.nextInRun = current.nextInRun - current.nextInRun = this + insertAfter(current) } // printPeriods(this) } @@ -731,19 +732,35 @@ object Denotations { val current1: SingleDenotation = f(current.asSymDenotation) if (current1 ne current) { current1.validFor = current.validFor - current1.replaceDenotation(current) + current1.insertInsteadOf(current) } hasNext = current1.nextInRun.validFor.code > current1.validFor.code current = current1.nextInRun } } - private def replaceDenotation(current: SingleDenotation): Unit = { - var prev = current - while (prev.nextInRun ne current) prev = prev.nextInRun + /** Insert this denotation so that it follows `prev`. */ + private def insertAfter(prev: SingleDenotation) = { + this.nextInRun = prev.nextInRun prev.nextInRun = this - this.nextInRun = current.nextInRun - current.validFor = Nowhere + } + + /** Insert this denotation instead of `old`. + * Also ensure that `old` refers with `nextInRun` to this denotation + * and set its `validFor` field to `NoWhere`. This is necessary so that + * references to the old denotation can be brought forward via `current` + * to a valid denotation. + * + * The code to achieve this is subtle in that it works correctly + * whether the replaced denotation is the only one in its cycle or not. + */ + private def insertInsteadOf(old: SingleDenotation): Unit = { + var prev = old + while (prev.nextInRun ne old) prev = prev.nextInRun + // order of next two assignments is important! + prev.nextInRun = this + this.nextInRun = old.nextInRun + old.validFor = Nowhere } def staleSymbolError(implicit ctx: Context) = { |