Skip to content

Commit 8c94821

Browse files
committed
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.
1 parent fbdfc83 commit 8c94821

File tree

2 files changed

+55
-18
lines changed

2 files changed

+55
-18
lines changed

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,9 @@ trait Namers extends MethodSynthesis {
163163
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
164164
debuglog("[overwrite] " + sym)
165165
val newFlags = (sym.flags & LOCKED) | flags
166-
sym.rawInfo match {
167-
case tr: TypeRef =>
168-
// !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
169-
// over this mutated symbol, and we witness a stale cache for `parents`.
170-
tr.invalidateCaches()
171-
case _ =>
172-
}
166+
// !!! needed for: pos/t5954d; the uniques type cache will happily serve up the same TypeRef
167+
// over this mutated symbol, and we witness a stale cache for `parents`.
168+
invalidateCaches(sym.rawInfo, sym :: sym.moduleClass :: Nil)
173169
sym reset NoType setFlag newFlags setPos pos
174170
sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
175171

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,10 @@ trait Types
12141214

12151215
private[reflect] var underlyingCache: Type = NoType
12161216
private[reflect] var underlyingPeriod = NoPeriod
1217+
private[Types] def invalidateSingleTypeCaches(): Unit = {
1218+
underlyingCache = NoType
1219+
underlyingPeriod = NoPeriod
1220+
}
12171221
override def underlying: Type = {
12181222
val cache = underlyingCache
12191223
if (underlyingPeriod == currentPeriod && cache != null) cache
@@ -1354,6 +1358,12 @@ trait Types
13541358
private[reflect] var baseTypeSeqPeriod = NoPeriod
13551359
private[reflect] var baseClassesCache: List[Symbol] = _
13561360
private[reflect] var baseClassesPeriod = NoPeriod
1361+
private[Types] def invalidatedCompoundTypeCaches() {
1362+
baseTypeSeqCache = null
1363+
baseTypeSeqPeriod = NoPeriod
1364+
baseClassesCache = null
1365+
baseClassesPeriod = NoPeriod
1366+
}
13571367

13581368
override def baseTypeSeq: BaseTypeSeq = {
13591369
val cached = baseTypeSeqCache
@@ -1912,6 +1922,9 @@ trait Types
19121922

19131923
narrowedCache
19141924
}
1925+
private[Types] def invalidateModuleTypeRefCaches(): Unit = {
1926+
narrowedCache = null
1927+
}
19151928
override protected def finishPrefix(rest: String) = objectPrefix + rest
19161929
override def directObjectString = super.safeToString
19171930
override def toLongString = toString
@@ -1989,8 +2002,12 @@ trait Types
19892002
* several times. Hence, no need to protected with synchronized in a multi-threaded
19902003
* usage scenario.
19912004
*/
1992-
private[Types] var relativeInfoCache: Type = _
1993-
private[Types] var relativeInfoPeriod: Period = NoPeriod
2005+
private var relativeInfoCache: Type = _
2006+
private var relativeInfoPeriod: Period = NoPeriod
2007+
private[Types] def invalidateNonClassTypeRefCaches(): Unit = {
2008+
relativeInfoCache = NoType
2009+
relativeInfoPeriod = NoPeriod
2010+
}
19942011

19952012
private[Types] def relativeInfo = /*trace(s"relativeInfo(${safeToString}})")*/{
19962013
if (relativeInfoPeriod != currentPeriod) {
@@ -2123,6 +2140,10 @@ trait Types
21232140
}
21242141
thisInfoCache
21252142
}
2143+
private[Types] def invalidateAbstractTypeRefCaches(): Unit = {
2144+
symInfoCache = null
2145+
thisInfoCache = null
2146+
}
21262147
override def bounds = thisInfo.bounds
21272148
override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
21282149
override def kind = "AbstractTypeRef"
@@ -2142,9 +2163,12 @@ trait Types
21422163
trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args))
21432164
toBoolean(trivial)
21442165
}
2145-
private[scala] def invalidateCaches(): Unit = {
2166+
private[Types] def invalidateTypeRefCaches(): Unit = {
2167+
parentsCache = null
21462168
parentsPeriod = NoPeriod
2169+
baseTypeSeqCache = null
21472170
baseTypeSeqPeriod = NoPeriod
2171+
normalized = null
21482172
}
21492173
private[reflect] var parentsCache: List[Type] = _
21502174
private[reflect] var parentsPeriod = NoPeriod
@@ -4575,14 +4599,31 @@ trait Types
45754599
invalidateCaches(tp, updatedSyms)
45764600
}
45774601

4578-
def invalidateCaches(t: Type, updatedSyms: List[Symbol]) = t match {
4579-
case st: SingleType if updatedSyms.contains(st.sym) =>
4580-
st.underlyingCache = NoType
4581-
st.underlyingPeriod = NoPeriod
4582-
case tr: NonClassTypeRef if updatedSyms.contains(tr.sym) =>
4583-
tr.relativeInfoCache = NoType
4584-
tr.relativeInfoPeriod = NoPeriod
4585-
case _ =>
4602+
def invalidateCaches(t: Type, updatedSyms: List[Symbol]) = {
4603+
t match {
4604+
case st: SingleType if updatedSyms.contains(st.sym) => st.invalidateSingleTypeCaches()
4605+
case _ =>
4606+
}
4607+
t match {
4608+
case tr: NonClassTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateNonClassTypeRefCaches()
4609+
case _ =>
4610+
}
4611+
t match {
4612+
case tr: AbstractTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateAbstractTypeRefCaches()
4613+
case _ =>
4614+
}
4615+
t match {
4616+
case tr: TypeRef if updatedSyms.contains(tr.sym) => tr.invalidateTypeRefCaches()
4617+
case _ =>
4618+
}
4619+
t match {
4620+
case tr: ModuleTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateModuleTypeRefCaches()
4621+
case _ =>
4622+
}
4623+
t match {
4624+
case ct: CompoundType if ct.baseClasses.exists(updatedSyms.contains) => ct.invalidatedCompoundTypeCaches()
4625+
case _ =>
4626+
}
45864627
}
45874628

45884629
val shorthands = Set(

0 commit comments

Comments
 (0)