Browse Source

Fix performance regression in stack analysis (probably caused by increased complexity from Ldloca support).

pull/205/head
Pent Ploompuu 14 years ago
parent
commit
1388f0b678
  1. 25
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  2. 68
      ICSharpCode.Decompiler/ILAst/NullableOperators.cs

25
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -339,7 +339,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -339,7 +339,7 @@ namespace ICSharpCode.Decompiler.ILAst
if (byteCode.Code == ILCode.Stloc || byteCode.Code == ILCode.Ldloca) {
int varIndex = ((VariableReference)byteCode.Operand).Index;
newVariableState[varIndex] = byteCode.Code == ILCode.Stloc || byteCode.Next.Code == ILCode.Initobj ?
new VariableSlot(byteCode) : new VariableSlot(newVariableState[varIndex].StoredBy.Union(new[] { byteCode }), false);
new VariableSlot(byteCode) : new VariableSlot(newVariableState[varIndex].StoredBy.Union(byteCode), false);
}
// After the leave, finally block might have touched the variables
@ -810,15 +810,34 @@ namespace ICSharpCode.Decompiler.ILAst @@ -810,15 +810,34 @@ namespace ICSharpCode.Decompiler.ILAst
list.RemoveRange(start, count);
return ret;
}
public static T[] Union<T>(this T[] a, T b)
{
if (a.Length == 0)
return new[] { b };
if (Array.IndexOf(a, b) >= 0)
return a;
var res = new T[a.Length + 1];
Array.Copy(a, res, a.Length);
res[res.Length - 1] = b;
return res;
}
public static T[] Union<T>(this T[] a, T[] b)
{
if (a == b)
return a;
if (a.Length == 0)
return b;
if (b.Length == 0)
return a;
if (a.Length == 1 && b.Length == 1 && a[0].Equals(b[0]))
return a;
if (a.Length == 1) {
if (b.Length == 1)
return a[0].Equals(b[0]) ? a : new[] { a[0], b[0] };
return b.Union(a[0]);
}
if (b.Length == 1)
return a.Union(b[0]);
return Enumerable.Union(a, b).ToArray();
}
}

68
ICSharpCode.Decompiler/ILAst/NullableOperators.cs

@ -140,10 +140,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -140,10 +140,8 @@ namespace ICSharpCode.Decompiler.ILAst
public override bool Match(PatternMatcher pm, ILExpression e)
{
if (e.Code != this.code) return false;
var m = e.Operand as MethodReference;
if (m == null || m.Name != this.method) return false;
var t = m.DeclaringType;
return TypeAnalysis.IsNullableType(t) && base.Match(pm, e);
var m = (MethodReference)e.Operand;
return m.Name == this.method && TypeAnalysis.IsNullableType(m.DeclaringType) && base.Match(pm, e);
}
}
@ -236,35 +234,39 @@ namespace ICSharpCode.Decompiler.ILAst @@ -236,35 +234,39 @@ namespace ICSharpCode.Decompiler.ILAst
bool IsCustomOperator(string s)
{
if (s.Length < 10 || !s.StartsWith("op_", StringComparison.Ordinal)) return false;
switch (s) {
case "op_Equality":
return type == OperatorType.Equality;
case "op_Inequality":
return type == OperatorType.InEquality;
case "op_GreaterThan":
case "op_GreaterThanOrEqual":
case "op_LessThan":
case "op_LessThanOrEqual":
return type == OperatorType.Comparison;
case "op_Addition":
case "op_Subtraction":
case "op_Multiply":
case "op_Division":
case "op_Modulus":
case "op_BitwiseAnd":
case "op_BitwiseOr":
case "op_ExclusiveOr":
case "op_LeftShift":
case "op_RightShift":
case "op_UnaryNegation":
case "op_UnaryPlus":
case "op_LogicalNot":
case "op_OnesComplement":
case "op_Increment":
case "op_Decrement":
return type == OperatorType.Other;
default: return false;
switch (type) {
case OperatorType.Equality: return s == "op_Equality";
case OperatorType.InEquality: return s == "op_Inequality";
case OperatorType.Comparison:
if (s.Length < 11 || !s.StartsWith("op_", StringComparison.Ordinal)) return false;
switch (s) {
case "op_GreaterThan":
case "op_GreaterThanOrEqual":
case "op_LessThan":
case "op_LessThanOrEqual": return true;
default: return false;
}
default:
if (s.Length < 10 || !s.StartsWith("op_", StringComparison.Ordinal)) return false;
switch (s) {
case "op_Addition":
case "op_Subtraction":
case "op_Multiply":
case "op_Division":
case "op_Modulus":
case "op_BitwiseAnd":
case "op_BitwiseOr":
case "op_ExclusiveOr":
case "op_LeftShift":
case "op_RightShift":
case "op_UnaryNegation":
case "op_UnaryPlus":
case "op_LogicalNot":
case "op_OnesComplement":
case "op_Increment":
case "op_Decrement": return true;
default: return false;
}
}
}

Loading…
Cancel
Save