@@ -50,20 +50,30 @@ public SemanticModel Model(SyntaxNode node)
5050 /// <returns><code>true</code> iff the label already existed.</returns>
5151 public bool GetOrAddCachedLabel ( ICachedEntity entity )
5252 {
53- var id = GetId ( entity ) ;
53+ // Look up the label in the entityLabelCache
54+ if ( entityLabelCache . TryGetValue ( entity , out Label label ) )
55+ {
56+ entity . Label = label ;
57+ return true ;
58+ }
59+
60+ var id = entity . Id ;
61+
5462 if ( id == null )
5563 throw new InternalError ( "Attempt to create a null entity for {0}" , entity . GetType ( ) ) ;
5664
57- Label existingLabel ;
58- if ( labelCache . TryGetValue ( id , out existingLabel ) )
65+ // Look up the Id in the idLabelCache
66+ if ( idLabelCache . TryGetValue ( id , out label ) )
5967 {
60- entity . Label = existingLabel ;
68+ entity . Label = label ;
69+ entityLabelCache [ entity ] = label ;
6170 return true ;
6271 }
6372
64- entity . Label = new Label ( NewId ( ) ) ;
65- DefineLabel ( entity . Label , id ) ;
66- labelCache [ id ] = entity . Label ;
73+ entity . Label = label = new Label ( NewId ( ) ) ;
74+ DefineLabel ( label , id ) ;
75+ entityLabelCache [ entity ] = label ;
76+ idLabelCache [ id ] = label ;
6777 return false ;
6878 }
6979
@@ -90,25 +100,6 @@ public bool ExtractGenerics(ICachedEntity entity)
90100 }
91101 }
92102
93- /// <summary>
94- /// Gets the ID belonging to cached entity <paramref name="entity"/>.
95- ///
96- /// The ID itself is also cached, but unlike the label cache (which is used
97- /// to prevent reextraction/infinite loops), this is a pure performance
98- /// optimization. Moreover, the label cache is injective, which the ID cache
99- /// need not be.
100- /// </summary>
101- IId GetId ( ICachedEntity entity )
102- {
103- IId id ;
104- if ( ! idCache . TryGetValue ( entity , out id ) )
105- {
106- id = entity . Id ;
107- idCache [ entity ] = id ;
108- }
109- return id ;
110- }
111-
112103 /// <summary>
113104 /// Creates a fresh label with ID "*", and set it on the
114105 /// supplied <paramref name="entity"/> object.
@@ -120,7 +111,8 @@ public void AddFreshLabel(IEntity entity)
120111 entity . Label = label ;
121112 }
122113
123- readonly Dictionary < IId , Label > labelCache = new Dictionary < IId , Label > ( ) ;
114+ readonly Dictionary < IId , Label > idLabelCache = new Dictionary < IId , Label > ( ) ;
115+ readonly Dictionary < ICachedEntity , Label > entityLabelCache = new Dictionary < ICachedEntity , Label > ( ) ;
124116 readonly HashSet < Label > extractedGenerics = new HashSet < Label > ( ) ;
125117
126118 public void DefineLabel ( IEntity entity )
@@ -134,8 +126,6 @@ void DefineLabel(Label label, IId id)
134126 TrapWriter . Emit ( new DefineLabelEmitter ( label , id ) ) ;
135127 }
136128
137- readonly Dictionary < object , IId > idCache = new Dictionary < object , IId > ( ) ;
138-
139129 /// <summary>
140130 /// Queue of items to populate later.
141131 /// The only reason for this is so that the call stack does not
0 commit comments