summaryrefslogtreecommitdiff
path: root/src/reflect
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/reflect
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/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala63
1 files changed, 52 insertions, 11 deletions
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(