@@ -4,9 +4,11 @@ package core
4
4
import Types ._ , Contexts ._ , util .Stats ._ , Hashable ._ , Names ._
5
5
import config .Config
6
6
import Decorators ._
7
- import util .{HashSet , Stats }
7
+ import util .{WeakHashSet , Stats }
8
+ import WeakHashSet .Entry
9
+ import scala .annotation .tailrec
8
10
9
- class Uniques extends HashSet [Type ](Config .initialUniquesCapacity):
11
+ class Uniques extends WeakHashSet [Type ](Config .initialUniquesCapacity):
10
12
override def hash (x : Type ): Int = x.hash
11
13
override def isEqual (x : Type , y : Type ) = x.eql(y)
12
14
@@ -32,7 +34,7 @@ object Uniques:
32
34
if tp.hash == NotCached then tp
33
35
else ctx.uniques.put(tp).asInstanceOf [T ]
34
36
35
- final class NamedTypeUniques extends HashSet [NamedType ](Config .initialUniquesCapacity * 4 ) with Hashable :
37
+ final class NamedTypeUniques extends WeakHashSet [NamedType ](Config .initialUniquesCapacity * 4 ) with Hashable :
36
38
override def hash (x : NamedType ): Int = x.hash
37
39
38
40
def enterIfNew (prefix : Type , designator : Designator , isTerm : Boolean )(using Context ): NamedType =
@@ -43,17 +45,25 @@ object Uniques:
43
45
else new CachedTypeRef (prefix, designator, h)
44
46
if h == NotCached then newType
45
47
else
48
+ // Inlined from WeakHashSet#put
46
49
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
54
64
end NamedTypeUniques
55
65
56
- final class AppliedUniques extends HashSet [AppliedType ](Config .initialUniquesCapacity * 2 ) with Hashable :
66
+ final class AppliedUniques extends WeakHashSet [AppliedType ](Config .initialUniquesCapacity * 2 ) with Hashable :
57
67
override def hash (x : AppliedType ): Int = x.hash
58
68
59
69
def enterIfNew (tycon : Type , args : List [Type ]): AppliedType =
@@ -62,13 +72,21 @@ object Uniques:
62
72
if monitored then recordCaching(h, classOf [CachedAppliedType ])
63
73
if h == NotCached then newType
64
74
else
75
+ // Inlined from WeakHashSet#put
65
76
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
73
91
end AppliedUniques
74
92
end Uniques
0 commit comments