Skip to content

Commit ce5290f

Browse files
committed
Hash-cons applied types in their own table
1 parent a5b1eee commit ce5290f

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,15 +608,19 @@ object Contexts {
608608
/** A table for hash consing unique refined types */
609609
private[dotc] val uniqueRefinedTypes = new RefinedUniques // @!!! replace with uniqueAppliedTypes
610610

611+
/** A table for hash consing unique refined types */
612+
private[dotc] val uniqueAppliedTypes = new AppliedUniques
613+
611614
/** A table for hash consing unique named types */
612615
private[core] val uniqueNamedTypes = new NamedTypeUniques
613616

614617
/** A table for hash consing unique type bounds */
615-
private[core] val uniqueTypeAliases = new TypeAliasUniques
618+
private[core] val uniqueTypeAliases = new TypeAliasUniques // @!!! replace
616619

617620
private def uniqueSets = Map(
618621
"uniques" -> uniques,
619622
"uniqueRefinedTypes" -> uniqueRefinedTypes,
623+
"uniqueAppliedTypes" -> uniqueAppliedTypes,
620624
"uniqueNamedTypes" -> uniqueNamedTypes,
621625
"uniqueTypeAliases" -> uniqueTypeAliases)
622626

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,30 +3177,18 @@ object Types {
31773177
def derivedAppliedType(tycon: Type, args: List[Type])(implicit ctx: Context): Type =
31783178
if ((tycon eq this.tycon) && (args eq this.args)) this
31793179
else tycon.appliedTo(args)
3180-
3181-
override def computeHash = doHash(tycon, args)
3182-
3183-
protected def checkInst(implicit ctx: Context): this.type = {
3184-
def check(tycon: Type): Unit = tycon.stripTypeVar match {
3185-
case tycon: TypeRef =>
3186-
case _: TypeParamRef | _: ErrorType | _: WildcardType =>
3187-
case _: TypeLambda =>
3188-
assert(!args.exists(_.isInstanceOf[TypeBounds]), s"unreduced type apply: $this")
3189-
case tycon: AnnotatedType =>
3190-
check(tycon.underlying)
3191-
case _ =>
3192-
assert(false, s"illegal type constructor in $this")
3193-
}
3194-
if (Config.checkHKApplications) check(tycon)
3195-
this
3196-
}
31973180
}
31983181

3199-
final class CachedAppliedType(tycon: Type, args: List[Type]) extends AppliedType(tycon, args)
3182+
final class CachedAppliedType(tycon: Type, args: List[Type], hc: Int) extends AppliedType(tycon, args) {
3183+
myHash = hc
3184+
override def computeHash = unsupported("computeHash")
3185+
}
32003186

32013187
object AppliedType {
3202-
def apply(tycon: Type, args: List[Type])(implicit ctx: Context) =
3203-
unique(new CachedAppliedType(tycon, args)).checkInst
3188+
def apply(tycon: Type, args: List[Type])(implicit ctx: Context) = {
3189+
assertUnerased()
3190+
ctx.base.uniqueAppliedTypes.enterIfNew(tycon, args)
3191+
}
32043192
}
32053193

32063194
object ClassRef {

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,37 @@ object Uniques {
9191
}
9292
}
9393

94+
95+
final class AppliedUniques extends HashSet[AppliedType](Config.initialUniquesCapacity) with Hashable {
96+
override def hash(x: AppliedType): Int = x.hash
97+
98+
private def findPrevious(h: Int, tycon: Type, args: List[Type]): AppliedType = {
99+
var e = findEntryByHash(h)
100+
while (e != null) {
101+
def sameArgs(args1: List[Type], args2: List[Type]): Boolean = {
102+
val empty1 = args1.isEmpty
103+
val empty2 = args2.isEmpty
104+
if (empty1) empty2
105+
else (!empty2 && (args1.head eq args2.head) && sameArgs(args1.tail, args2.tail))
106+
}
107+
if ((e.tycon eq tycon) && sameArgs(e.args, args)) return e
108+
e = nextEntryByHash(h)
109+
}
110+
e
111+
}
112+
113+
def enterIfNew(tycon: Type, args: List[Type]): AppliedType = {
114+
val h = doHash(tycon, args)
115+
def newType = new CachedAppliedType(tycon, args, h)
116+
if (monitored) recordCaching(h, classOf[CachedAppliedType])
117+
if (h == NotCached) newType
118+
else {
119+
val r = findPrevious(h, tycon, args)
120+
if (r ne null) r else addEntryAfterScan(newType)
121+
}
122+
}
123+
}
124+
94125
final class RefinedUniques extends HashSet[RefinedType](Config.initialUniquesCapacity) with Hashable {
95126
override val hashSeed = classOf[CachedRefinedType].hashCode // some types start life as CachedRefinedTypes, need to have same hash seed
96127
override def hash(x: RefinedType): Int = x.hash

0 commit comments

Comments
 (0)