Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid allocations in LightupHelpers.CanWrap... methods #8107

Merged
merged 4 commits into from
Oct 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Avoid captures
  • Loading branch information
martin-strecker-sonarsource committed Sep 28, 2023
commit 412e90b2ec645e098f3d455677819011933a4f86
48 changes: 24 additions & 24 deletions analyzers/src/SonarAnalyzer.CFG/ShimLayer/LightupHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,15 @@ internal static bool CanWrapObject(object obj, Type underlyingType)
}

// Avoid creating the delegate if the value already exists
if (!wrappedObject.TryGetValue(obj.GetType(), out var canCast))
{
canCast = wrappedObject.GetOrAdd(
obj.GetType(),
kind => underlyingType.GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was very weird... the key kind was not used at all...

}

return canCast;
return wrappedObject.TryGetValue(obj.GetType(), out var canCast)
? canCast
: GetOrAdd(obj, underlyingType, wrappedObject);

// Dont' inline this method. The capture class will span the whole method otherwise.
#pragma warning disable HAA0301, HAA0302 // Display class allocation to capture closure
static bool GetOrAdd(object obj, Type underlyingType, ConcurrentDictionary<Type, bool> wrappedObject) =>
wrappedObject.GetOrAdd(obj.GetType(), kind => underlyingType.GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo()));
#pragma warning restore HAA0301, HAA0302
}

[PerformanceSensitive("https://github.com/SonarSource/sonar-dotnet/issues/8106", AllowCaptures = false, AllowGenericEnumeration = false, AllowImplicitBoxing = false)]
Expand All @@ -93,15 +94,13 @@ internal static bool CanWrapNode(SyntaxNode node, Type underlyingType)
wrappedSyntax = SupportedSyntaxWrappers.GetOrAdd(underlyingType, static _ => new ConcurrentDictionary<SyntaxKind, bool>());
}

// Avoid creating the delegate if the value already exists
if (!wrappedSyntax.TryGetValue(node.Kind(), out var canCast))
{
canCast = wrappedSyntax.GetOrAdd(
node.Kind(),
kind => underlyingType.GetTypeInfo().IsAssignableFrom(node.GetType().GetTypeInfo()));
}
return wrappedSyntax.TryGetValue(node.Kind(), out var canCast) ? canCast : GetOrAdd(node, underlyingType, wrappedSyntax);

return canCast;
// Dont' inline this method. The capture class will span the whole method otherwise.
#pragma warning disable HAA0301, HAA0302 // Display class allocation to capture closure
static bool GetOrAdd(SyntaxNode node, Type underlyingType, ConcurrentDictionary<SyntaxKind, bool> wrappedSyntax) =>
wrappedSyntax.GetOrAdd(node.Kind(), kind => underlyingType.GetTypeInfo().IsAssignableFrom(node.GetType().GetTypeInfo()));
#pragma warning restore HAA0301, HAA0302
}

[PerformanceSensitive("https://github.com/SonarSource/sonar-dotnet/issues/8106", AllowCaptures = false, AllowGenericEnumeration = false, AllowImplicitBoxing = false)]
Expand All @@ -126,14 +125,15 @@ internal static bool CanWrapOperation(IOperation operation, Type underlyingType)
}

// Avoid creating the delegate if the value already exists
if (!wrappedSyntax.TryGetValue(operation.Kind, out var canCast))
{
canCast = wrappedSyntax.GetOrAdd(
operation.Kind,
kind => underlyingType.GetTypeInfo().IsAssignableFrom(operation.GetType().GetTypeInfo()));
}

return canCast;
return wrappedSyntax.TryGetValue(operation.Kind, out var canCast)
? canCast
: GetOrAdd(operation, underlyingType, wrappedSyntax);

// Dont' inline this method. The capture class will span the whole method otherwise.
#pragma warning disable HAA0301, HAA0302 // Display class allocation to capture closure
static bool GetOrAdd(IOperation operation, Type underlyingType, ConcurrentDictionary<OperationKind, bool> wrappedSyntax) =>
wrappedSyntax.GetOrAdd(operation.Kind, kind => underlyingType.GetTypeInfo().IsAssignableFrom(operation.GetType().GetTypeInfo()));
#pragma warning restore HAA0301, HAA0302
}

internal static Func<TOperation, TProperty> CreateOperationPropertyAccessor<TOperation, TProperty>(Type type, string propertyName)
Expand Down