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

Merge pull request #10990 from mavasani/DisableAnalyzerStatePooling

Remove all the static analyzer state tracking pools in CompilationWit…
......@@ -15,7 +15,6 @@ internal partial class AnalysisState
{
private class PerAnalyzerState
{
private const int SymbolLimitForPooling = 100;
private readonly object _gate = new object();
private readonly Dictionary<CompilationEvent, AnalyzerStateData> _pendingEvents = new Dictionary<CompilationEvent, AnalyzerStateData>();
private readonly Dictionary<ISymbol, AnalyzerStateData> _pendingSymbols = new Dictionary<ISymbol, AnalyzerStateData>();
......@@ -38,48 +37,6 @@ private class PerAnalyzerState
_currentlyAnalyzingDeclarationsMapPool = currentlyAnalyzingDeclarationsMapPool;
}
/// <summary>
/// Returns true if the object should be returned to the pool.
/// </summary>
public bool Free()
{
lock (_gate)
{
foreach (var analyzerStateData in _pendingEvents.Values)
{
FreeState_NoLock(analyzerStateData, _analyzerStateDataPool);
}
foreach (var analyzerStateData in _pendingSymbols.Values)
{
FreeState_NoLock(analyzerStateData, _analyzerStateDataPool);
}
foreach (var declarationDataMap in _pendingDeclarations.Values)
{
foreach (var declarationStateData in declarationDataMap.Values)
{
FreeDeclarationAnalyzerState_NoLock(declarationStateData);
}
FreeDeclarationDataMap_NoLock(declarationDataMap);
}
// If we have too many symbols then just discard the state object from the pool - we don't want to hold onto really large dictionaries.
if (_pendingSymbols.Count > SymbolLimitForPooling)
{
return false;
}
_pendingEvents.Clear();
_pendingSymbols.Clear();
_pendingDeclarations.Clear();
_lazySyntaxTreesWithAnalysisData = null;
_pendingSyntaxAnalysisTreesCount = 0;
return true;
}
}
public void AddPendingEvents(HashSet<CompilationEvent> uniqueEvents)
{
lock (_gate)
......@@ -264,14 +221,6 @@ private bool TryStartAnalyzingDeclaration_NoLock(ISymbol symbol, int declaration
return true;
}
private void MarkDeclarationProcessed(ISymbol symbol, int declarationIndex)
{
lock (_gate)
{
MarkDeclarationProcessed_NoLock(symbol, declarationIndex);
}
}
private void MarkDeclarationProcessed_NoLock(ISymbol symbol, int declarationIndex)
{
Dictionary<int, DeclarationAnalyzerStateData> declarationDataMap;
......
......@@ -63,13 +63,6 @@ internal partial class AnalysisState
private readonly ObjectPool<HashSet<CompilationEvent>> _compilationEventsPool;
private readonly HashSet<CompilationEvent> _pooledEventsWithAnyActionsSet;
// Create static pools for heavily allocated per-analyzer state objects - this helps in reducing allocations across CompilationWithAnalyzer instances.
private const int PoolSize = 5000;
private static readonly ObjectPool<AnalyzerStateData> s_analyzerStateDataPool = new ObjectPool<AnalyzerStateData>(() => new AnalyzerStateData(), PoolSize);
private static readonly ObjectPool<DeclarationAnalyzerStateData> s_declarationAnalyzerStateDataPool = new ObjectPool<DeclarationAnalyzerStateData>(() => new DeclarationAnalyzerStateData(), PoolSize);
private static readonly ObjectPool<Dictionary<int, DeclarationAnalyzerStateData>> s_currentlyAnalyzingDeclarationsMapPool = new ObjectPool<Dictionary<int, DeclarationAnalyzerStateData>>(() => new Dictionary<int, DeclarationAnalyzerStateData>(), PoolSize);
private static readonly ObjectPool<PerAnalyzerState> s_perAnalyzerStatePool = new ObjectPool<PerAnalyzerState>(() => new PerAnalyzerState(s_analyzerStateDataPool, s_declarationAnalyzerStateDataPool, s_currentlyAnalyzingDeclarationsMapPool), PoolSize);
public AnalysisState(ImmutableArray<DiagnosticAnalyzer> analyzers, CompilationData compilationData)
{
_gate = new object();
......@@ -87,33 +80,19 @@ public AnalysisState(ImmutableArray<DiagnosticAnalyzer> analyzers, CompilationDa
_pooledEventsWithAnyActionsSet = new HashSet<CompilationEvent>();
}
~AnalysisState()
{
// Free the per-analyzer state tracking objects.
foreach (var analyzerState in _analyzerStates)
{
var shouldReturnToPool = analyzerState.Free();
// If we have too many symbols then just discard the state object from the pool - we don't want to hold onto really large dictionaries.
if (shouldReturnToPool)
{
s_perAnalyzerStatePool.Free(analyzerState);
}
else
{
s_perAnalyzerStatePool.ForgetTrackedObject(analyzerState);
}
}
}
private static ImmutableDictionary<DiagnosticAnalyzer, int> CreateAnalyzerStateMap(ImmutableArray<DiagnosticAnalyzer> analyzers, out ImmutableArray<PerAnalyzerState> analyzerStates)
{
var analyzerStateDataPool = new ObjectPool<AnalyzerStateData>(() => new AnalyzerStateData());
var declarationAnalyzerStateDataPool = new ObjectPool<DeclarationAnalyzerStateData>(() => new DeclarationAnalyzerStateData());
var currentlyAnalyzingDeclarationsMapPool = new ObjectPool<Dictionary<int, DeclarationAnalyzerStateData>>(
() => new Dictionary<int, DeclarationAnalyzerStateData>());
var statesBuilder = ImmutableArray.CreateBuilder<PerAnalyzerState>();
var map = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, int>();
var index = 0;
foreach (var analyzer in analyzers)
{
statesBuilder.Add(s_perAnalyzerStatePool.Allocate());
statesBuilder.Add(new PerAnalyzerState(analyzerStateDataPool, declarationAnalyzerStateDataPool, currentlyAnalyzingDeclarationsMapPool));
map[analyzer] = index;
index++;
}
......
......@@ -69,7 +69,7 @@ public class CompilationWithAnalyzers
/// <summary>
/// Pool of event queues to serve each diagnostics request.
/// </summary>
private static readonly ObjectPool<AsyncQueue<CompilationEvent>> s_eventQueuePool = new ObjectPool<AsyncQueue<CompilationEvent>>(() => new AsyncQueue<CompilationEvent>());
private readonly ObjectPool<AsyncQueue<CompilationEvent>> _eventQueuePool = new ObjectPool<AsyncQueue<CompilationEvent>>(() => new AsyncQueue<CompilationEvent>());
private static readonly AsyncQueue<CompilationEvent> s_EmptyEventQueue = new AsyncQueue<CompilationEvent>();
/// <summary>
......@@ -388,7 +388,7 @@ private async Task ComputeAnalyzerDiagnosticsWithoutStateTrackingAsync(Cancellat
return;
}
AsyncQueue<CompilationEvent> eventQueue = s_eventQueuePool.Allocate();
AsyncQueue<CompilationEvent> eventQueue = _eventQueuePool.Allocate();
AnalyzerDriver driver = null;
try
......@@ -422,13 +422,13 @@ private async Task ComputeAnalyzerDiagnosticsWithoutStateTrackingAsync(Cancellat
finally
{
driver?.Dispose();
FreeEventQueue(eventQueue);
FreeEventQueue(eventQueue, _eventQueuePool);
}
}
private async Task<ImmutableArray<Diagnostic>> GetAllDiagnosticsWithoutStateTrackingAsync(ImmutableArray<DiagnosticAnalyzer> analyzers, CancellationToken cancellationToken)
{
AsyncQueue<CompilationEvent> eventQueue = s_eventQueuePool.Allocate();
AsyncQueue<CompilationEvent> eventQueue = _eventQueuePool.Allocate();
AnalyzerDriver driver = null;
try
......@@ -452,7 +452,7 @@ private async Task<ImmutableArray<Diagnostic>> GetAllDiagnosticsWithoutStateTrac
finally
{
driver?.Dispose();
FreeEventQueue(eventQueue);
FreeEventQueue(eventQueue, _eventQueuePool);
}
}
......@@ -660,7 +660,7 @@ private async Task ComputeAnalyzerDiagnosticsAsync(AnalysisScope analysisScope,
}
finally
{
FreeEventQueue(eventQueue);
FreeEventQueue(eventQueue, _eventQueuePool);
}
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
......@@ -951,7 +951,7 @@ private void ClearExecutingTask(Task computeTask, SyntaxTree treeOpt)
private AsyncQueue<CompilationEvent> GetPendingEvents(ImmutableArray<DiagnosticAnalyzer> analyzers, SyntaxTree tree)
{
var eventQueue = s_eventQueuePool.Allocate();
var eventQueue = _eventQueuePool.Allocate();
Debug.Assert(!eventQueue.IsCompleted);
Debug.Assert(eventQueue.Count == 0);
......@@ -967,7 +967,7 @@ private AsyncQueue<CompilationEvent> GetPendingEvents(ImmutableArray<DiagnosticA
{
Debug.Assert(includeSourceEvents || includeNonSourceEvents);
var eventQueue = s_eventQueuePool.Allocate();
var eventQueue = _eventQueuePool.Allocate();
Debug.Assert(!eventQueue.IsCompleted);
Debug.Assert(eventQueue.Count == 0);
......@@ -979,7 +979,7 @@ private AsyncQueue<CompilationEvent> GetPendingEvents(ImmutableArray<DiagnosticA
return eventQueue;
}
private static void FreeEventQueue(AsyncQueue<CompilationEvent> eventQueue)
private static void FreeEventQueue(AsyncQueue<CompilationEvent> eventQueue, ObjectPool<AsyncQueue<CompilationEvent>> eventQueuePool)
{
if (eventQueue == null || ReferenceEquals(eventQueue, s_EmptyEventQueue))
{
......@@ -994,11 +994,11 @@ private static void FreeEventQueue(AsyncQueue<CompilationEvent> eventQueue)
if (!eventQueue.IsCompleted)
{
s_eventQueuePool.Free(eventQueue);
eventQueuePool.Free(eventQueue);
}
else
{
s_eventQueuePool.ForgetTrackedObject(eventQueue);
eventQueuePool.ForgetTrackedObject(eventQueue);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册