diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Caches.scala | 103 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/SymbolTable.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 16 |
3 files changed, 33 insertions, 106 deletions
diff --git a/src/compiler/scala/reflect/internal/Caches.scala b/src/compiler/scala/reflect/internal/Caches.scala deleted file mode 100644 index 46e290c796..0000000000 --- a/src/compiler/scala/reflect/internal/Caches.scala +++ /dev/null @@ -1,103 +0,0 @@ -/* NSC -- new scala compiler - * Copyright 2005-2011 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.reflect -package internal - -import scala.collection.{ mutable, immutable } - -/** A cache for some entity whose validity depends on a monotonically - * increasing sequence number. - */ -abstract class SequencedCache[T >: Null] { - def zero: Int - def sequenceId: Int - def calculate(): T - - /** If sequence numbers differ, this condition is consulted before - * updating the cached value. - */ - def isCacheValid: Boolean - - /** Public so accesses can be inlined. */ - @inline var cachedId: Int = 0 - @inline var cachedValue: T = _ - - /** Puts cache back in uninitialized state. */ - @inline final def clear() = { - cachedId = zero - cachedValue = null - } - /** Resets the sequence id without touching the cached value. */ - @inline final def reset() = { - cachedId = zero - } - - final def get(): T = { - if (cachedValue == null) { - cachedValue = calculate() - cachedId = sequenceId - } - else if (cachedId != sequenceId) { - if (!isCacheValid) - cachedValue = calculate() - - cachedId = sequenceId - } - cachedValue - } -} - -trait Caches { - self: SymbolTable => - - final def isValid(period: Period): Boolean = - period != 0 && runId(period) == currentRunId && { - val pid = phaseId(period) - if (phase.id > pid) infoTransformers.nextFrom(pid).pid >= phase.id - else infoTransformers.nextFrom(phase.id).pid >= pid - } - - final def isValidForBaseClasses(period: Period): Boolean = { - def noChangeInBaseClasses(it: InfoTransformer, limit: Phase#Id): Boolean = ( - it.pid >= limit || - !it.changesBaseClasses && noChangeInBaseClasses(it.next, limit) - ); - period != 0 && runId(period) == currentRunId && { - val pid = phaseId(period) - if (phase.id > pid) noChangeInBaseClasses(infoTransformers.nextFrom(pid), phase.id) - else noChangeInBaseClasses(infoTransformers.nextFrom(phase.id), pid) - } - } - - abstract class PeriodCache[T >: Null] extends SequencedCache[T] { - final val zero = NoPeriod - @inline final def sequenceId = currentPeriod - } - - abstract class ListOfTypesCache extends PeriodCache[List[Type]] { - @inline final def isCacheValid = isValidForBaseClasses(cachedId) - } - abstract class ListOfSymbolsCache extends PeriodCache[List[Symbol]] { - @inline final def isCacheValid = isValidForBaseClasses(cachedId) - } - abstract class BaseTypeSeqCache extends PeriodCache[BaseTypeSeq] { - @inline final def isCacheValid = isValidForBaseClasses(cachedId) - } - abstract class TypeCache extends PeriodCache[Type] { - @inline final def isCacheValid = isValid(cachedId) - } - abstract class TypeCacheForRunId extends SequencedCache[Type] { - final val zero = NoRunId - @inline final def sequenceId = currentRunId - @inline final override def isCacheValid = false - } - object TypeCache { - def apply(body: => Type): TypeCache = new TypeCache { - @inline final def calculate() = body - } - } -} - diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 18fdcfbc51..0687a50e2a 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -13,7 +13,6 @@ abstract class SymbolTable extends /*reflect.generic.Universe with Symbols with Types with Scopes - with Caches with Definitions with Constants with BaseTypeSeqs @@ -95,6 +94,25 @@ abstract class SymbolTable extends /*reflect.generic.Universe final def afterPhase[T](ph: Phase)(op: => T): T = atPhase(ph.next)(op) + final def isValid(period: Period): Boolean = + period != 0 && runId(period) == currentRunId && { + val pid = phaseId(period) + if (phase.id > pid) infoTransformers.nextFrom(pid).pid >= phase.id + else infoTransformers.nextFrom(phase.id).pid >= pid + } + + final def isValidForBaseClasses(period: Period): Boolean = { + def noChangeInBaseClasses(it: InfoTransformer, limit: Phase#Id): Boolean = ( + it.pid >= limit || + !it.changesBaseClasses && noChangeInBaseClasses(it.next, limit) + ); + period != 0 && runId(period) == currentRunId && { + val pid = phaseId(period) + if (phase.id > pid) noChangeInBaseClasses(infoTransformers.nextFrom(pid), phase.id) + else noChangeInBaseClasses(infoTransformers.nextFrom(phase.id), pid) + } + } + /** Break into repl debugger if assertion is true */ // def breakIf(assertion: => Boolean, args: Any*): Unit = // if (assertion) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 8930ff86cd..572cb8d3a4 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1679,7 +1679,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable => // assert(args.isEmpty || !sym.info.typeParams.isEmpty, this) // assert(args.isEmpty || ((sym ne AnyClass) && (sym ne NothingClass)) - private val parentsCache = new ListOfTypesCache(thisInfo.parents map transform) + private var parentsCache: List[Type] = _ + private var parentsPeriod = NoPeriod private var baseTypeSeqCache: BaseTypeSeq = _ private var baseTypeSeqPeriod = NoPeriod @@ -1759,7 +1760,18 @@ A type's typeSymbol should never be inspected directly. if (sym.isAbstractType) thisInfo.bounds // transform(thisInfo.bounds).asInstanceOf[TypeBounds] // ??? seems to be doing asSeenFrom twice else super.bounds - override def parents: List[Type] = parentsCache.get() + override def parents: List[Type] = { + val period = parentsPeriod + if (period != currentPeriod) { + parentsPeriod = currentPeriod + if (!isValidForBaseClasses(period)) { + parentsCache = thisInfo.parents map transform + } else if (parentsCache == null) { // seems this can happen if things are currupted enough, see #2641 + parentsCache = List(AnyClass.tpe) + } + } + parentsCache + } override def typeOfThis = transform(sym.typeOfThis) /* |