diff options
author | Paul Phillips <paulp@improving.org> | 2011-09-28 17:59:44 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-09-28 17:59:44 +0000 |
commit | 08845f2ce3959b6da4beb619cd045e60b655ce3f (patch) | |
tree | c048a58e6dd186559d92b0fc745d2c631a85dde3 /src | |
parent | f7a4cdd56ffa204b514c3ab1c2b9218ac3679178 (diff) | |
download | scala-08845f2ce3959b6da4beb619cd045e60b655ce3f.tar.gz scala-08845f2ce3959b6da4beb619cd045e60b655ce3f.tar.bz2 scala-08845f2ce3959b6da4beb619cd045e60b655ce3f.zip |
More consistent usage of atPhase.
Some improvables I noticed while working on a fingerprint phase. This
eliminates fifty classes from the compiler. My new hobby is reading the
whole bytecode diff anytime I'm touching something like unsafeTypeParams
where I know someone is liable to start praying for my network access
to fail, so I hope knowing that fills you with new confidence. Anyway,
review by moors.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Phase.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/SymbolTable.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 44 |
3 files changed, 27 insertions, 28 deletions
diff --git a/src/compiler/scala/reflect/internal/Phase.scala b/src/compiler/scala/reflect/internal/Phase.scala index 5637a86de3..acd3360c4f 100644 --- a/src/compiler/scala/reflect/internal/Phase.scala +++ b/src/compiler/scala/reflect/internal/Phase.scala @@ -35,6 +35,10 @@ abstract class Phase(val prev: Phase) { def erasedTypes: Boolean = false def flatClasses: Boolean = false def refChecked: Boolean = false + + /** This is used only in unsafeTypeParams, and at this writing is + * overridden to false in namer, typer, and erasure. (And NoPhase.) + */ def keepsTypeParams = true def run(): Unit @@ -48,6 +52,7 @@ abstract class Phase(val prev: Phase) { object NoPhase extends Phase(null) { def name = "<no phase>" + override def keepsTypeParams = false def run() { throw new Error("NoPhase.run") } } diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index b92a1bb5d7..873821e790 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -97,17 +97,17 @@ abstract class SymbolTable extends api.Universe (currentRunId << 8) + pid /** Perform given operation at given phase. */ - final def atPhase[T](ph: Phase)(op: => T): T = { + @inline final def atPhase[T](ph: Phase)(op: => T): T = { val current = phase phase = ph try op finally phase = current } - final def afterPhase[T](ph: Phase)(op: => T): T = + @inline final def afterPhase[T](ph: Phase)(op: => T): T = atPhase(ph.next)(op) - final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = + @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = if (target != null && phase.id > target.id) atPhase(target)(op) else op final def isValid(period: Period): Boolean = diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 84b54167ec..160fbf7f77 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -999,7 +999,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => protected def doCookJavaRawInfo(): Unit - /** The type constructor of a symbol is: * For a type symbol, the type corresponding to the symbol itself, * excluding parameters. @@ -1008,42 +1007,37 @@ trait Symbols extends api.Symbols { self: SymbolTable => def typeConstructor: Type = abort("typeConstructor inapplicable for " + this) + /** The logic approximately boils down to finding the phase following + * the most recent of namer, typer, or erasure. + */ + private def unsafeTypeParamPhase = { + var ph = phase + while (ph.prev.keepsTypeParams) + ph = ph.prev + if (ph ne phase) { // Can anyone comment as to what this condition accomplishes? + ph = ph.next + debuglog("checking unsafeTypeParams(" + this + ") at: " + phase + " reading at: " + ph) + } + ph + } /** The type parameters of this symbol, without ensuring type completion. * assumption: if a type starts out as monomorphic, it will not acquire * type parameters later. */ def unsafeTypeParams: List[Symbol] = - if (isMonomorphicType) List() - else { - val current = phase - try { - while ((phase.prev ne NoPhase) && phase.prev.keepsTypeParams) phase = phase.prev - if (phase ne current) phase = phase.next - if (settings.debug.value && settings.verbose.value && (phase ne current)) - log("checking unsafeTypeParams(" + this + ") at: " + current + " reading at: " + phase) - rawInfo.typeParams - } finally { - phase = current - } - } + if (isMonomorphicType) Nil + else atPhase(unsafeTypeParamPhase)(rawInfo.typeParams) /** The type parameters of this symbol. * assumption: if a type starts out as monomorphic, it will not acquire * type parameters later. */ def typeParams: List[Symbol] = - if (isMonomorphicType) - List() + if (isMonomorphicType) Nil else { - if (validTo == NoPeriod) { - val current = phase - try { - phase = phaseOf(infos.validFrom) - rawInfo.load(this) - } finally { - phase = current - } - } + if (validTo == NoPeriod) + atPhase(phaseOf(infos.validFrom))(rawInfo load this) + rawInfo.typeParams } |