Skip to content

Commit e405898

Browse files
committed
Cache NamedTypes with thisType prefix in Symbols
... rather than the global ctx.uniqueNamedRefs hashtable. This reduces the size of the hashtable by a bit more than half
1 parent 7587f9c commit e405898

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,11 +1173,27 @@ object SymDenotations {
11731173
/** The type This(cls), where cls is this class, NoPrefix for all other symbols */
11741174
def thisType(implicit ctx: Context): Type = NoPrefix
11751175

1176+
private[this] var cachedRef: NamedType = null
1177+
1178+
def namedRef(implicit ctx: Context): NamedType = {
1179+
if (cachedRef == null) {
1180+
val initl = initial
1181+
val thistpe = maybeOwner.thisType
1182+
if ((initl `ne` this) && (thistpe `eq` initl.maybeOwner.thisType))
1183+
cachedRef = initial.namedRef
1184+
else {
1185+
Stats.record("namedRef create")
1186+
cachedRef = ctx.uniqueNamedTypes.newType(thistpe, symbol, isTerm)
1187+
}
1188+
}
1189+
cachedRef
1190+
}
1191+
11761192
override def typeRef(implicit ctx: Context): TypeRef =
1177-
TypeRef(owner.thisType, symbol)
1193+
namedRef.asInstanceOf[TypeRef]
11781194

11791195
override def termRef(implicit ctx: Context): TermRef =
1180-
TermRef(owner.thisType, symbol)
1196+
namedRef.asInstanceOf[TermRef]
11811197

11821198
/** The variance of this type parameter or type member as an Int, with
11831199
* +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter

compiler/src/dotty/tools/dotc/core/Uniques.scala

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,33 @@ object Uniques {
5353
e
5454
}
5555

56+
def newType(prefix: Type, designator: Designator, hc: Int, isTerm: Boolean): NamedType =
57+
if (isTerm) new CachedTermRef(prefix, designator, hc)
58+
else new CachedTypeRef(prefix, designator, hc)
59+
60+
def newType(prefix: Type, designator: Designator, isTerm: Boolean)(implicit ctx: Context): NamedType =
61+
newType(prefix, designator, doHash(null, designator, prefix), isTerm)
62+
5663
def enterIfNew(prefix: Type, designator: Designator, isTerm: Boolean)(implicit ctx: Context): NamedType = {
5764
val h = doHash(null, designator, prefix)
5865
if (monitored) recordCaching(h, classOf[NamedType])
59-
def newType =
60-
if (isTerm) new CachedTermRef(prefix, designator, h)
61-
else new CachedTypeRef(prefix, designator, h)
62-
if (h == NotCached) newType
66+
designator match {
67+
case sym: Symbol =>
68+
val symd = sym.lastKnownDenotation
69+
if (symd != null) {
70+
val ref = symd.namedRef
71+
if (prefix `eq` ref.prefix) {
72+
record("namedRef reuse")
73+
return ref
74+
}
75+
}
76+
case _ =>
77+
}
78+
if (h == NotCached) newType(prefix, designator, h, isTerm)
6379
else {
6480
val r = findPrevious(h, prefix, designator)
65-
if ((r ne null) && (r.isTerm == isTerm)) r else addEntryAfterScan(newType)
81+
if ((r ne null) && (r.isTerm == isTerm)) r
82+
else addEntryAfterScan(newType(prefix, designator, h, isTerm))
6683
}
6784
}
6885
}

0 commit comments

Comments
 (0)