@@ -4,9 +4,11 @@ package core
44import Types ._ , Contexts ._ , util .Stats ._ , Hashable ._ , Names ._
55import config .Config
66import Decorators ._
7- import util .{HashSet , Stats }
7+ import util .{WeakHashSet , Stats }
8+ import WeakHashSet .Entry
9+ import scala .annotation .tailrec
810
9- class Uniques extends HashSet [Type ](Config .initialUniquesCapacity):
11+ class Uniques extends WeakHashSet [Type ](Config .initialUniquesCapacity):
1012 override def hash (x : Type ): Int = x.hash
1113 override def isEqual (x : Type , y : Type ) = x.eql(y)
1214
@@ -32,7 +34,7 @@ object Uniques:
3234 if tp.hash == NotCached then tp
3335 else ctx.uniques.put(tp).asInstanceOf [T ]
3436
35- final class NamedTypeUniques extends HashSet [NamedType ](Config .initialUniquesCapacity * 4 ) with Hashable :
37+ final class NamedTypeUniques extends WeakHashSet [NamedType ](Config .initialUniquesCapacity * 4 ) with Hashable :
3638 override def hash (x : NamedType ): Int = x.hash
3739
3840 def enterIfNew (prefix : Type , designator : Designator , isTerm : Boolean )(using Context ): NamedType =
@@ -43,17 +45,25 @@ object Uniques:
4345 else new CachedTypeRef (prefix, designator, h)
4446 if h == NotCached then newType
4547 else
48+ // Inlined from WeakHashSet#put
4649 Stats .record(statsItem(" put" ))
47- var idx = index(h)
48- var e = entryAt(idx)
49- while e != null do
50- if (e.prefix eq prefix) && (e.designator eq designator) && (e.isTerm == isTerm) then return e
51- idx = nextIndex(idx)
52- e = entryAt(idx)
53- addEntryAt(idx, newType)
50+ removeStaleEntries()
51+ val bucket = index(h)
52+ val oldHead = table(bucket)
53+
54+ @ tailrec
55+ def linkedListLoop (entry : Entry [NamedType ]): NamedType = entry match
56+ case null => addEntryAt(bucket, newType, h, oldHead)
57+ case _ =>
58+ val e = entry.get
59+ if e != null && (e.prefix eq prefix) && (e.designator eq designator) && (e.isTerm == isTerm) then e
60+ else linkedListLoop(entry.tail)
61+
62+ linkedListLoop(oldHead)
63+ end if
5464 end NamedTypeUniques
5565
56- final class AppliedUniques extends HashSet [AppliedType ](Config .initialUniquesCapacity * 2 ) with Hashable :
66+ final class AppliedUniques extends WeakHashSet [AppliedType ](Config .initialUniquesCapacity * 2 ) with Hashable :
5767 override def hash (x : AppliedType ): Int = x.hash
5868
5969 def enterIfNew (tycon : Type , args : List [Type ]): AppliedType =
@@ -62,13 +72,21 @@ object Uniques:
6272 if monitored then recordCaching(h, classOf [CachedAppliedType ])
6373 if h == NotCached then newType
6474 else
75+ // Inlined from WeakHashSet#put
6576 Stats .record(statsItem(" put" ))
66- var idx = index(h)
67- var e = entryAt(idx)
68- while e != null do
69- if (e.tycon eq tycon) && e.args.eqElements(args) then return e
70- idx = nextIndex(idx)
71- e = entryAt(idx)
72- addEntryAt(idx, newType)
77+ removeStaleEntries()
78+ val bucket = index(h)
79+ val oldHead = table(bucket)
80+
81+ @ tailrec
82+ def linkedListLoop (entry : Entry [AppliedType ]): AppliedType = entry match
83+ case null => addEntryAt(bucket, newType, h, oldHead)
84+ case _ =>
85+ val e = entry.get
86+ if e != null && (e.tycon eq tycon) && e.args.eqElements(args) then e
87+ else linkedListLoop(entry.tail)
88+
89+ linkedListLoop(oldHead)
90+ end if
7391 end AppliedUniques
7492end Uniques
0 commit comments