Skip to content

Commit

Permalink
Merge pull request #15337 from asecchia/RemoveActionAllocation
Browse files Browse the repository at this point in the history
Remove 250MB of gc generated by delegate allocations during OOP synchronization.
  • Loading branch information
CyrusNajmabadi authored Nov 18, 2016
2 parents cca7c7c + 260e041 commit d5fb6fd
Showing 1 changed file with 18 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public async Task<DiagnosticAnalysisResult> GetAnalysisDataAsync(Project project
}
}

if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, builder.AddOthers, cancellationToken).ConfigureAwait(false))
if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, s_addOthers, builder, cancellationToken).ConfigureAwait(false))
{
// this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
// analysis happened.
Expand Down Expand Up @@ -182,7 +182,7 @@ public async Task<DiagnosticAnalysisResult> GetProjectAnalysisDataAsync(Project
var serializer = new DiagnosticDataSerializer(_owner.AnalyzerVersion, lastResult.Version);
var builder = new Builder(project.Id, lastResult.Version);

if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, builder.AddOthers, cancellationToken).ConfigureAwait(false))
if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, s_addOthers, builder, cancellationToken).ConfigureAwait(false))
{
// this can happen if SaveAsync is not yet called but active file merge happened. one of case is if user did build before the very first
// analysis happened.
Expand Down Expand Up @@ -301,7 +301,7 @@ private async Task<DiagnosticAnalysisResult> LoadInitialAnalysisDataAsync(Projec
}
}

if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, builder.AddOthers, cancellationToken).ConfigureAwait(false))
if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, s_addOthers, builder, cancellationToken).ConfigureAwait(false))
{
return new DiagnosticAnalysisResult(project.Id, VersionStamp.Default, ImmutableHashSet<DocumentId>.Empty, isEmpty: true, fromBuild: false);
}
Expand Down Expand Up @@ -333,7 +333,7 @@ private async Task<DiagnosticAnalysisResult> LoadInitialProjectAnalysisDataAsync
var serializer = new DiagnosticDataSerializer(_owner.AnalyzerVersion, version);
var builder = new Builder(project.Id, version);

if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, builder.AddOthers, cancellationToken).ConfigureAwait(false))
if (!await TryDeserializeAsync(serializer, project, project.Id, _owner.NonLocalStateName, s_addOthers, builder, cancellationToken).ConfigureAwait(false))
{
return new DiagnosticAnalysisResult(project.Id, VersionStamp.Default, ImmutableHashSet<DocumentId>.Empty, isEmpty: true, fromBuild: false);
}
Expand All @@ -355,30 +355,36 @@ private async Task SerializeAsync(DiagnosticDataSerializer serializer, object do
InMemoryStorage.Cache(_owner.Analyzer, ValueTuple.Create(key, stateKey), new CacheEntry(serializer.Version, diagnostics));
}

private static Action<Builder, DocumentId, ImmutableArray<DiagnosticData>> s_addSyntaxLocals = (b, id, locals) => b.AddSyntaxLocals(id, locals);
private static Action<Builder, DocumentId, ImmutableArray<DiagnosticData>> s_addSemanticLocals = (b, id, locals) => b.AddSemanticLocals(id, locals);
private static Action<Builder, DocumentId, ImmutableArray<DiagnosticData>> s_addNonLocals = (b, id, locals) => b.AddNonLocals(id, locals);
private static Action<Builder, ProjectId, ImmutableArray<DiagnosticData>> s_addOthers = (b, id, locals) => b.AddOthers(id, locals);

private async Task<bool> TryDeserializeDocumentAsync(DiagnosticDataSerializer serializer, Document document, Builder builder, CancellationToken cancellationToken)
{
var result = true;

result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.SyntaxStateName, builder.AddSyntaxLocals, cancellationToken).ConfigureAwait(false);
result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.SemanticStateName, builder.AddSemanticLocals, cancellationToken).ConfigureAwait(false);
result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.NonLocalStateName, builder.AddNonLocals, cancellationToken).ConfigureAwait(false);
result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.SyntaxStateName, s_addSyntaxLocals, builder, cancellationToken).ConfigureAwait(false);
result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.SemanticStateName, s_addSemanticLocals, builder, cancellationToken).ConfigureAwait(false);
result &= await TryDeserializeAsync(serializer, document, document.Id, _owner.NonLocalStateName, s_addNonLocals, builder, cancellationToken).ConfigureAwait(false);

return result;
}

private async Task<bool> TryDeserializeAsync<T>(
private async Task<bool> TryDeserializeAsync<TKey, TArg>(
DiagnosticDataSerializer serializer,
object documentOrProject, T key, string stateKey,
Action<T, ImmutableArray<DiagnosticData>> add,
CancellationToken cancellationToken) where T : class
object documentOrProject, TKey key, string stateKey,
Action<TArg, TKey, ImmutableArray<DiagnosticData>> add,
TArg arg,
CancellationToken cancellationToken) where TKey : class
{
var diagnostics = await DeserializeAsync(serializer, documentOrProject, key, stateKey, cancellationToken).ConfigureAwait(false);
if (diagnostics == null)
{
return false;
}

add(key, diagnostics.Value);
add(arg, key, diagnostics.Value);
return true;
}

Expand Down

0 comments on commit d5fb6fd

Please sign in to comment.