Browse Source

Performance Optimization: Do no longer collect all lower case type and member names.

pull/2752/head
Siegfried Pammer 3 years ago
parent
commit
6584a2f576
  1. 4
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  2. 82
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

4
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -203,6 +203,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -203,6 +203,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
#region EnsureExpressionStatementsAreValid
void EnsureExpressionStatementsAreValid(AstNode rootNode)
{
string[] reservedNames = null;
foreach (var stmt in rootNode.DescendantsAndSelf.OfType<ExpressionStatement>())
{
if (!IsValidInStatementExpression(stmt.Expression))
@ -218,6 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -218,6 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
else
{
reservedNames ??= rootNode.DescendantsAndSelf.OfType<Identifier>().Select(i => i.Name).ToArray();
// assign result to dummy variable
var type = stmt.Expression.GetResolveResult().Type;
var v = function.RegisterVariable(
@ -226,7 +228,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -226,7 +228,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
AssignVariableNames.GenerateVariableName(function, type,
stmt.Expression.Annotations.OfType<ILInstruction>()
.Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(),
mustResolveConflicts: true)
reservedNames: reservedNames)
);
stmt.Expression = new AssignmentExpression(
new IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)),

82
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -53,7 +53,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -53,7 +53,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
};
ILTransformContext context;
List<string> currentLowerCaseTypeOrMemberNames;
Dictionary<string, int> reservedVariableNames;
Dictionary<MethodDefinitionHandle, string> localFunctionMapping;
HashSet<ILVariable> loopCounters;
@ -64,16 +63,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -64,16 +63,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
this.context = context;
reservedVariableNames = new Dictionary<string, int>();
currentLowerCaseTypeOrMemberNames = new List<string>();
var currentLowerCaseMemberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition);
foreach (var name in currentLowerCaseMemberNames)
currentLowerCaseTypeOrMemberNames.Add(name);
var currentLowerCaseTypeNames = CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition);
foreach (var name in currentLowerCaseTypeNames)
{
currentLowerCaseTypeOrMemberNames.Add(name);
AddExistingName(reservedVariableNames, name);
}
localFunctionMapping = new Dictionary<MethodDefinitionHandle, string>();
loopCounters = CollectLoopCounters(function);
foreach (var f in function.Descendants.OfType<ILFunction>())
@ -157,24 +146,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -157,24 +146,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
static IEnumerable<string> CollectAllLowerCaseMemberNames(ITypeDefinition type)
{
foreach (var item in type.GetMembers(m => IsLowerCase(m.Name)))
yield return item.Name;
}
static IEnumerable<string> CollectAllLowerCaseTypeNames(ITypeDefinition type)
{
foreach (var item in type.ParentModule.TopLevelTypeDefinitions)
{
if (item.Namespace != type.Namespace)
continue;
if (IsLowerCase(item.Name))
yield return item.Name;
}
}
static bool IsLowerCase(string name)
{
return name.Length > 0 && char.ToLower(name[0]) == name[0];
@ -425,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -425,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var proposedNameForAddress = variable.AddressInstructions.OfType<LdLoca>()
.Select(arg => arg.Parent is CallInstruction c ? c.GetParameter(arg.ChildIndex)?.Name : null)
.Where(arg => !string.IsNullOrWhiteSpace(arg))
.Except(currentLowerCaseTypeOrMemberNames).ToList();
.ToList();
if (proposedNameForAddress.Count > 0)
{
proposedName = proposedNameForAddress[0];
@ -435,7 +406,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -435,7 +406,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
var proposedNameForStores = variable.StoreInstructions.OfType<StLoc>()
.Select(expr => GetNameFromInstruction(expr.Value))
.Except(currentLowerCaseTypeOrMemberNames).ToList();
.ToList();
if (proposedNameForStores.Count == 1)
{
proposedName = proposedNameForStores[0];
@ -445,7 +416,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -445,7 +416,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
var proposedNameForLoads = variable.LoadInstructions
.Select(arg => GetNameForArgument(arg.Parent, arg.ChildIndex))
.Except(currentLowerCaseTypeOrMemberNames).ToList();
.ToList();
if (proposedNameForLoads.Count == 1)
{
proposedName = proposedNameForLoads[0];
@ -455,7 +426,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -455,7 +426,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType<StLoc>()
.Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context)))
.Except(currentLowerCaseTypeOrMemberNames).ToList();
.ToList();
if (proposedNameForStoresFromNewObj.Count == 1)
{
proposedName = proposedNameForStoresFromNewObj[0];
@ -689,35 +660,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -689,35 +660,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return variableType;
}
static Dictionary<string, int> CollectReservedVariableNames(ILFunction function,
ILVariable existingVariable, bool mustResolveConflicts)
{
var reservedVariableNames = new Dictionary<string, int>();
var rootFunction = function.Ancestors.OfType<ILFunction>().Single(f => f.Parent == null);
foreach (var f in rootFunction.Descendants.OfType<ILFunction>())
{
foreach (var p in rootFunction.Parameters)
{
AddExistingName(reservedVariableNames, p.Name);
}
foreach (var v in f.Variables.Where(v => v.Kind != VariableKind.Parameter))
{
if (v != existingVariable)
AddExistingName(reservedVariableNames, v.Name);
}
}
if (mustResolveConflicts)
{
var memberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition)
.Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition));
foreach (var name in memberNames)
AddExistingName(reservedVariableNames, name);
}
return reservedVariableNames;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext,
ILVariable existingVariable = null, bool mustResolveConflicts = false)
ILVariable existingVariable = null, string[] reservedNames = null)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
@ -725,7 +669,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -725,7 +669,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return existingVariable.Name;
}
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
var reservedVariableNames = new Dictionary<string, int>();
foreach (var name in reservedNames ?? Array.Empty<string>())
{
reservedVariableNames[name] = 1;
}
string baseName = GetNameFromInstruction(valueContext);
if (string.IsNullOrEmpty(baseName))
@ -777,11 +726,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -777,11 +726,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static string GenerateVariableName(ILFunction function, IType type,
ILInstruction valueContext = null, ILVariable existingVariable = null,
bool mustResolveConflicts = false)
string[] reservedNames = null)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
var reservedVariableNames = new Dictionary<string, int>();
foreach (var name in reservedNames ?? Array.Empty<string>())
{
reservedVariableNames[name] = 1;
}
string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type);
string proposedName = "obj";

Loading…
Cancel
Save