提交 a2a8e14f 编写于 作者: M Manish Vasani

Replace the conditional weak table in the analyzer driver with a weak reference to the cached data.

Analyzer driver needs to cache some per-compilation data across analyzer diagnostic requests from the IDE. Currently we cache this data using a conditional weak table keyed by the compilation. However, we don't really need the old data once we move to analyzing a new compilation, so we can just use a weak reference.
上级 c807cb47
...@@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics ...@@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics
{ {
internal abstract partial class AnalyzerDriver : IDisposable internal abstract partial class AnalyzerDriver : IDisposable
{ {
protected static readonly ConditionalWeakTable<Compilation, CompilationData> s_compilationDataCache = new ConditionalWeakTable<Compilation, CompilationData>(); private static readonly WeakReference<CompilationData> s_cachedCompilationData = new WeakReference<CompilationData>(null);
internal class CompilationData internal class CompilationData
{ {
...@@ -28,12 +28,18 @@ internal class CompilationData ...@@ -28,12 +28,18 @@ internal class CompilationData
public CompilationData(Compilation comp) public CompilationData(Compilation comp)
{ {
this.Compilation = comp;
_semanticModelsMap = new Dictionary<SyntaxTree, SemanticModel>(); _semanticModelsMap = new Dictionary<SyntaxTree, SemanticModel>();
_symbolDeclarationsMap = new Dictionary<ISymbol, ImmutableArray<SyntaxReference>>(); _symbolDeclarationsMap = new Dictionary<ISymbol, ImmutableArray<SyntaxReference>>();
this.SuppressMessageAttributeState = new SuppressMessageAttributeState(comp); this.SuppressMessageAttributeState = new SuppressMessageAttributeState(comp);
this.DeclarationAnalysisDataMap = new Dictionary<SyntaxReference, DeclarationAnalysisData>(); this.DeclarationAnalysisDataMap = new Dictionary<SyntaxReference, DeclarationAnalysisData>();
} }
/// <summary>
/// Compilation whose data is cached.
/// </summary>
public readonly Compilation Compilation;
public SuppressMessageAttributeState SuppressMessageAttributeState { get; } public SuppressMessageAttributeState SuppressMessageAttributeState { get; }
public Dictionary<SyntaxReference, DeclarationAnalysisData> DeclarationAnalysisDataMap { get; } public Dictionary<SyntaxReference, DeclarationAnalysisData> DeclarationAnalysisDataMap { get; }
...@@ -146,12 +152,29 @@ public void Free() ...@@ -146,12 +152,29 @@ public void Free()
internal static CompilationData GetOrCreateCachedCompilationData(Compilation compilation) internal static CompilationData GetOrCreateCachedCompilationData(Compilation compilation)
{ {
return s_compilationDataCache.GetValue(compilation, c => new CompilationData(c)); CompilationData data;
if (!s_cachedCompilationData.TryGetTarget(out data) || data == null || data.Compilation != compilation)
{
data = new CompilationData(compilation);
s_cachedCompilationData.SetTarget(data);
}
return data;
}
internal static bool TryGetCachedCompilationData(Compilation compilation, out CompilationData compilationData)
{
return s_cachedCompilationData.TryGetTarget(out compilationData) &&
compilationData?.Compilation == compilation;
} }
internal static bool RemoveCachedCompilationData(Compilation compilation) internal static void RemoveCachedCompilationData(Compilation compilation)
{ {
return s_compilationDataCache.Remove(compilation); CompilationData compilationData;
if (TryGetCachedCompilationData(compilation, out compilationData))
{
s_cachedCompilationData.SetTarget(null);
}
} }
public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Compilation compilation, CancellationToken cancellationToken) public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Compilation compilation, CancellationToken cancellationToken)
...@@ -160,11 +183,13 @@ public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Comp ...@@ -160,11 +183,13 @@ public static SemanticModel GetOrCreateCachedSemanticModel(SyntaxTree tree, Comp
return compilationData.GetOrCreateCachedSemanticModel(tree, compilation, cancellationToken); return compilationData.GetOrCreateCachedSemanticModel(tree, compilation, cancellationToken);
} }
public static bool RemoveCachedSemanticModel(SyntaxTree tree, Compilation compilation) public static void RemoveCachedSemanticModel(SyntaxTree tree, Compilation compilation)
{ {
CompilationData compilationData; CompilationData compilationData;
return s_compilationDataCache.TryGetValue(compilation, out compilationData) && if (TryGetCachedCompilationData(compilation, out compilationData))
{
compilationData.RemoveCachedSemanticModel(tree); compilationData.RemoveCachedSemanticModel(tree);
}
} }
public static bool TryGetCachedDeclaringReferences(ISymbol symbol, Compilation compilation, out ImmutableArray<SyntaxReference> declaringReferences) public static bool TryGetCachedDeclaringReferences(ISymbol symbol, Compilation compilation, out ImmutableArray<SyntaxReference> declaringReferences)
...@@ -179,11 +204,13 @@ public static void CacheDeclaringReferences(ISymbol symbol, Compilation compilat ...@@ -179,11 +204,13 @@ public static void CacheDeclaringReferences(ISymbol symbol, Compilation compilat
compilationData.CacheDeclaringReferences(symbol, declaringReferences); compilationData.CacheDeclaringReferences(symbol, declaringReferences);
} }
public static bool RemoveCachedDeclaringReferences(ISymbol symbol, Compilation compilation) public static void RemoveCachedDeclaringReferences(ISymbol symbol, Compilation compilation)
{ {
CompilationData compilationData; CompilationData compilationData;
return s_compilationDataCache.TryGetValue(compilation, out compilationData) && if (TryGetCachedCompilationData(compilation, out compilationData))
{
compilationData.RemoveCachedDeclaringReferences(symbol); compilationData.RemoveCachedDeclaringReferences(symbol);
}
} }
} }
} }
\ No newline at end of file
...@@ -1137,7 +1137,7 @@ private void ClearCachedAnalysisDataIfAnalyzed(SyntaxReference declaration, Synt ...@@ -1137,7 +1137,7 @@ private void ClearCachedAnalysisDataIfAnalyzed(SyntaxReference declaration, Synt
Debug.Assert(analysisState != null); Debug.Assert(analysisState != null);
CompilationData compilationData; CompilationData compilationData;
if (!s_compilationDataCache.TryGetValue(compilation, out compilationData) || if (!TryGetCachedCompilationData(compilation, out compilationData) ||
!analysisState.IsDeclarationComplete(node)) !analysisState.IsDeclarationComplete(node))
{ {
return; return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册