summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-09-30 16:46:46 +1000
committerJason Zaugg <jzaugg@gmail.com>2015-09-30 16:46:46 +1000
commit8c9482108d2c4db73a22a6fb3f3660f168a174e9 (patch)
tree781070c922e55e113e0855b6dac0a94017e8c1d3 /src
parentfbdfc83b5f0b3a2d2962c1adad8875a7e58d6497 (diff)
downloadscala-8c9482108d2c4db73a22a6fb3f3660f168a174e9.tar.gz
scala-8c9482108d2c4db73a22a6fb3f3660f168a174e9.tar.bz2
scala-8c9482108d2c4db73a22a6fb3f3660f168a174e9.zip
SI-9498 Centralize and bolster TypeRef cache invalidation
I found another spot where I had previously needed to manually invalidate a TypeRef cache, and modified that to route through the newly added `invalidatedCaches`. `invalidatedCaches` now invalidates all the other caches I could find in our types of types. I opted for a non-OO approach here, as we've got a fairly intricate lattice of traits in place that define caches, and I didn't have the stomach for adding a polymorphic `Type::invalidatedCaches` with the the right sprinkling over overrides and super calls.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala63
2 files changed, 55 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 254cb7111c..ba095c808e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -163,13 +163,9 @@ trait Namers extends MethodSynthesis {
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
debuglog("[overwrite] " + sym)
val newFlags = (sym.flags & LOCKED) | flags
- sym.rawInfo match {
- case tr: TypeRef =>
- // !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
- // over this mutated symbol, and we witness a stale cache for `parents`.
- tr.invalidateCaches()
- case _ =>
- }
+ // !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
+ // over this mutated symbol, and we witness a stale cache for `parents`.
+ invalidateCaches(sym.rawInfo, sym :: sym.moduleClass :: Nil)
sym reset NoType setFlag newFlags setPos pos
sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 1ac772fb70..33592bbd86 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1214,6 +1214,10 @@ trait Types
private[reflect] var underlyingCache: Type = NoType
private[reflect] var underlyingPeriod = NoPeriod
+ private[Types] def invalidateSingleTypeCaches(): Unit = {
+ underlyingCache = NoType
+ underlyingPeriod = NoPeriod
+ }
override def underlying: Type = {
val cache = underlyingCache
if (underlyingPeriod == currentPeriod && cache != null) cache
@@ -1354,6 +1358,12 @@ trait Types
private[reflect] var baseTypeSeqPeriod = NoPeriod
private[reflect] var baseClassesCache: List[Symbol] = _
private[reflect] var baseClassesPeriod = NoPeriod
+ private[Types] def invalidatedCompoundTypeCaches() {
+ baseTypeSeqCache = null
+ baseTypeSeqPeriod = NoPeriod
+ baseClassesCache = null
+ baseClassesPeriod = NoPeriod
+ }
override def baseTypeSeq: BaseTypeSeq = {
val cached = baseTypeSeqCache
@@ -1912,6 +1922,9 @@ trait Types
narrowedCache
}
+ private[Types] def invalidateModuleTypeRefCaches(): Unit = {
+ narrowedCache = null
+ }
override protected def finishPrefix(rest: String) = objectPrefix + rest
override def directObjectString = super.safeToString
override def toLongString = toString
@@ -1989,8 +2002,12 @@ trait Types
* several times. Hence, no need to protected with synchronized in a multi-threaded
* usage scenario.
*/
- private[Types] var relativeInfoCache: Type = _
- private[Types] var relativeInfoPeriod: Period = NoPeriod
+ private var relativeInfoCache: Type = _
+ private var relativeInfoPeriod: Period = NoPeriod
+ private[Types] def invalidateNonClassTypeRefCaches(): Unit = {
+ relativeInfoCache = NoType
+ relativeInfoPeriod = NoPeriod
+ }
private[Types] def relativeInfo = /*trace(s"relativeInfo(${safeToString}})")*/{
if (relativeInfoPeriod != currentPeriod) {
@@ -2123,6 +2140,10 @@ trait Types
}
thisInfoCache
}
+ private[Types] def invalidateAbstractTypeRefCaches(): Unit = {
+ symInfoCache = null
+ thisInfoCache = null
+ }
override def bounds = thisInfo.bounds
override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
override def kind = "AbstractTypeRef"
@@ -2142,9 +2163,12 @@ trait Types
trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args))
toBoolean(trivial)
}
- private[scala] def invalidateCaches(): Unit = {
+ private[Types] def invalidateTypeRefCaches(): Unit = {
+ parentsCache = null
parentsPeriod = NoPeriod
+ baseTypeSeqCache = null
baseTypeSeqPeriod = NoPeriod
+ normalized = null
}
private[reflect] var parentsCache: List[Type] = _
private[reflect] var parentsPeriod = NoPeriod
@@ -4575,14 +4599,31 @@ trait Types
invalidateCaches(tp, updatedSyms)
}
- def invalidateCaches(t: Type, updatedSyms: List[Symbol]) = t match {
- case st: SingleType if updatedSyms.contains(st.sym) =>
- st.underlyingCache = NoType
- st.underlyingPeriod = NoPeriod
- case tr: NonClassTypeRef if updatedSyms.contains(tr.sym) =>
- tr.relativeInfoCache = NoType
- tr.relativeInfoPeriod = NoPeriod
- case _ =>
+ def invalidateCaches(t: Type, updatedSyms: List[Symbol]) = {
+ t match {
+ case st: SingleType if updatedSyms.contains(st.sym) => st.invalidateSingleTypeCaches()
+ case _ =>
+ }
+ t match {
+ case tr: NonClassTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateNonClassTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: AbstractTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateAbstractTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: TypeRef if updatedSyms.contains(tr.sym) => tr.invalidateTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: ModuleTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateModuleTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case ct: CompoundType if ct.baseClasses.exists(updatedSyms.contains) => ct.invalidatedCompoundTypeCaches()
+ case _ =>
+ }
}
val shorthands = Set(