提交 b99d0b38 编写于 作者: S Sam Harwell

Parallelize namespace members when analyzing the entire compilation

上级 317dba82
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -24,6 +26,9 @@ internal partial class ClsComplianceChecker : CSharpSymbolVisitor
private readonly ConcurrentDictionary<Symbol, Compliance> _declaredOrInheritedCompliance;
/// <seealso cref="MethodCompiler._compilerTasks"/>
private ConcurrentStack<Task> _compilerTasks;
private ClsComplianceChecker(
CSharpCompilation compilation,
SyntaxTree filterTree,
......@@ -52,7 +57,13 @@ public static void CheckCompliance(CSharpCompilation compilation, DiagnosticBag
{
var queue = new ConcurrentQueue<Diagnostic>();
var checker = new ClsComplianceChecker(compilation, filterTree, filterSpanWithinTree, queue, cancellationToken);
if (compilation.Options.ConcurrentBuild)
{
checker._compilerTasks = new ConcurrentStack<Task>();
}
checker.Visit(compilation.Assembly);
checker.WaitForWorkers();
foreach (Diagnostic diag in queue)
{
......@@ -145,7 +156,20 @@ public override void VisitAssembly(AssemblySymbol symbol)
Visit(symbol.GlobalNamespace);
}
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", IsParallelEntry = false)]
private void WaitForWorkers()
{
var tasks = _compilerTasks;
if (tasks == null)
{
return;
}
while (tasks.TryPop(out Task curTask))
{
curTask.GetAwaiter().GetResult();
}
}
public override void VisitNamespace(NamespaceSymbol symbol)
{
_cancellationToken.ThrowIfCancellationRequested();
......@@ -158,6 +182,36 @@ public override void VisitNamespace(NamespaceSymbol symbol)
CheckMemberDistinctness(symbol);
}
if (_filterTree == null && _compilation.Options.ConcurrentBuild)
{
VisitNamespaceMembersAsTasks(symbol);
}
else
{
VisitNamespaceMembers(symbol);
}
}
private void VisitNamespaceMembersAsTasks(NamespaceSymbol symbol)
{
foreach (var m in symbol.GetMembersUnordered())
{
_compilerTasks.Push(Task.Run(UICultureUtilities.WithCurrentUICulture(() =>
{
try
{
Visit(m);
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
}), _cancellationToken));
}
}
private void VisitNamespaceMembers(NamespaceSymbol symbol)
{
foreach (var m in symbol.GetMembersUnordered())
{
Visit(m);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册