@@ -4,93 +4,71 @@ package core
44import Types ._ , Contexts ._ , util .Stats ._ , Hashable ._ , Names ._
55import config .Config
66import Decorators ._
7- import util .HashSet
7+ import util .{HashSet , Stats }
8+
9+ class Uniques extends HashSet [Type ](Config .initialUniquesCapacity):
10+ override def hash (x : Type ): Int = x.hash
11+ override def isEqual (x : Type , y : Type ) = x.eql(y)
812
913/** Defines operation `unique` for hash-consing types.
1014 * Also defines specialized hash sets for hash consing uniques of a specific type.
1115 * All sets offer a `enterIfNew` method which checks whether a type
1216 * with the given parts exists already and creates a new one if not.
1317 */
14- object Uniques {
18+ object Uniques :
1519
16- private def recordCaching (tp : Type ): Unit = recordCaching(tp.hash, tp.getClass)
17- private def recordCaching (h : Int , clazz : Class [? ]): Unit =
18- if (h == NotCached ) {
19- record(" uncached-types" )
20- record(s " uncached: $clazz" )
21- }
22- else {
23- record(" cached-types" )
24- record(s " cached: $clazz" )
25- }
20+ private inline def recordCaching (tp : Type ): Unit = recordCaching(tp.hash, tp.getClass)
21+ private inline def recordCaching (h : Int , clazz : Class [? ]): Unit =
22+ if monitored then
23+ if h == NotCached then
24+ record(" uncached-types" )
25+ record(s " uncached: $clazz" )
26+ else
27+ record(" cached-types" )
28+ record(s " cached: $clazz" )
2629
27- def unique [T <: Type ](tp : T )(using Context ): T = {
28- if (monitored) recordCaching(tp)
29- if (tp.hash == NotCached ) tp
30- else if (monitored) {
31- val size = ctx.uniques.size
32- val result = ctx.uniques.findEntryOrUpdate(tp).asInstanceOf [T ]
33- if (ctx.uniques.size > size) record(s " fresh unique ${tp.getClass}" )
34- result
35- }
36- else ctx.uniques.findEntryOrUpdate(tp).asInstanceOf [T ]
37- }
38- /* !!! DEBUG
39- ensuring (
40- result => tp.toString == result.toString || {
41- println(s"cache mismatch; tp = $tp, cached = $result")
42- false
43- }
44- )
45- */
30+ def unique [T <: Type ](tp : T )(using Context ): T =
31+ recordCaching(tp)
32+ if tp.hash == NotCached then tp
33+ else ctx.uniques.put(tp).asInstanceOf [T ]
4634
47- final class NamedTypeUniques extends HashSet [NamedType ](Config .initialUniquesCapacity) with Hashable {
35+ final class NamedTypeUniques extends HashSet [NamedType ](Config .initialUniquesCapacity) with Hashable :
4836 override def hash (x : NamedType ): Int = x.hash
4937
50- private def findPrevious (h : Int , prefix : Type , designator : Designator ): NamedType = {
51- var e = findEntryByHash(h)
52- while (e != null ) {
53- if ((e.prefix eq prefix) && (e.designator eq designator)) return e
54- e = nextEntryByHash(h)
55- }
56- e
57- }
58-
59- def enterIfNew (prefix : Type , designator : Designator , isTerm : Boolean )(using Context ): NamedType = {
38+ def enterIfNew (prefix : Type , designator : Designator , isTerm : Boolean )(using Context ): NamedType =
6039 val h = doHash(null , designator, prefix)
61- if ( monitored) recordCaching(h, classOf [NamedType ])
40+ if monitored then recordCaching(h, classOf [NamedType ])
6241 def newType =
6342 if (isTerm) new CachedTermRef (prefix, designator, h)
6443 else new CachedTypeRef (prefix, designator, h)
65- if (h == NotCached ) newType
66- else {
67- val r = findPrevious(h, prefix, designator)
68- if ((r ne null ) && (r.isTerm == isTerm)) r else addEntryAfterScan(newType)
69- }
70- }
71- }
44+ if h == NotCached then newType
45+ else
46+ 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)
54+ end NamedTypeUniques
7255
73- final class AppliedUniques extends HashSet [AppliedType ](Config .initialUniquesCapacity) with Hashable {
56+ final class AppliedUniques extends HashSet [AppliedType ](Config .initialUniquesCapacity) with Hashable :
7457 override def hash (x : AppliedType ): Int = x.hash
7558
76- private def findPrevious (h : Int , tycon : Type , args : List [Type ]): AppliedType = {
77- var e = findEntryByHash(h)
78- while (e != null ) {
79- if ((e.tycon eq tycon) && e.args.eqElements(args)) return e
80- e = nextEntryByHash(h)
81- }
82- e
83- }
84-
85- def enterIfNew (tycon : Type , args : List [Type ]): AppliedType = {
59+ def enterIfNew (tycon : Type , args : List [Type ]): AppliedType =
8660 val h = doHash(null , tycon, args)
8761 def newType = new CachedAppliedType (tycon, args, h)
88- if (monitored) recordCaching(h, classOf [CachedAppliedType ])
89- if (h == NotCached ) newType
90- else {
91- val r = findPrevious(h, tycon, args)
92- if (r ne null ) r else addEntryAfterScan(newType)
93- }
94- }
95- }
96- }
62+ if monitored then recordCaching(h, classOf [CachedAppliedType ])
63+ if h == NotCached then newType
64+ else
65+ 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)
73+ end AppliedUniques
74+ end Uniques
0 commit comments