Browse Source

Merge pull request #2519 from icsharpcode/christophwille/measure

Add ETW for Performance Measuring
pull/2526/head
Christoph Wille 4 years ago committed by GitHub
parent
commit
7979d19299
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 99
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  3. 59
      ICSharpCode.Decompiler/Instrumentation/DecompilerEventSource.cs

99
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1209,6 +1209,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1209,6 +1209,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
@ -1361,6 +1362,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1361,6 +1362,11 @@ namespace ICSharpCode.Decompiler.CSharp
{
throw new DecompilerException(module, typeDef, innerException);
}
finally
{
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileTypeDefinition(typeDef.FullName, watch.ElapsedMilliseconds);
}
}
enum EnumValueDisplayMode
@ -1447,43 +1453,52 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1447,43 +1453,52 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == method);
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
var methodDecl = typeSystemAstBuilder.ConvertEntity(method);
int lastDot = method.Name.LastIndexOf('.');
if (method.IsExplicitInterfaceImplementation && lastDot >= 0)
{
methodDecl.Name = method.Name.Substring(lastDot + 1);
}
FixParameterNames(methodDecl);
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
if (!settings.LocalFunctions && LocalFunctionDecompiler.LocalFunctionNeedsAccessibilityChange(method.ParentModule.PEFile, (MethodDefinitionHandle)method.MetadataToken))
{
// if local functions are not active and we're dealing with a local function,
// reduce the visibility of the method to private,
// otherwise this leads to compile errors because the display classes have lesser accessibility.
// Note: removing and then adding the static modifier again is necessary to set the private modifier before all other modifiers.
methodDecl.Modifiers &= ~(Modifiers.Internal | Modifiers.Static);
methodDecl.Modifiers |= Modifiers.Private | (method.IsStatic ? Modifiers.Static : 0);
}
if (methodDefinition.HasBody())
{
DecompileBody(method, methodDecl, decompileRun, decompilationContext);
}
else if (!method.IsAbstract && method.DeclaringType.Kind != TypeKind.Interface)
{
methodDecl.Modifiers |= Modifiers.Extern;
}
if (method.SymbolKind == SymbolKind.Method && !method.IsExplicitInterfaceImplementation && methodDefinition.HasFlag(System.Reflection.MethodAttributes.Virtual) == methodDefinition.HasFlag(System.Reflection.MethodAttributes.NewSlot))
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
SetNewModifier(methodDecl);
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
var methodDecl = typeSystemAstBuilder.ConvertEntity(method);
int lastDot = method.Name.LastIndexOf('.');
if (method.IsExplicitInterfaceImplementation && lastDot >= 0)
{
methodDecl.Name = method.Name.Substring(lastDot + 1);
}
FixParameterNames(methodDecl);
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
if (!settings.LocalFunctions && LocalFunctionDecompiler.LocalFunctionNeedsAccessibilityChange(method.ParentModule.PEFile, (MethodDefinitionHandle)method.MetadataToken))
{
// if local functions are not active and we're dealing with a local function,
// reduce the visibility of the method to private,
// otherwise this leads to compile errors because the display classes have lesser accessibility.
// Note: removing and then adding the static modifier again is necessary to set the private modifier before all other modifiers.
methodDecl.Modifiers &= ~(Modifiers.Internal | Modifiers.Static);
methodDecl.Modifiers |= Modifiers.Private | (method.IsStatic ? Modifiers.Static : 0);
}
if (methodDefinition.HasBody())
{
DecompileBody(method, methodDecl, decompileRun, decompilationContext);
}
else if (!method.IsAbstract && method.DeclaringType.Kind != TypeKind.Interface)
{
methodDecl.Modifiers |= Modifiers.Extern;
}
if (method.SymbolKind == SymbolKind.Method && !method.IsExplicitInterfaceImplementation && methodDefinition.HasFlag(System.Reflection.MethodAttributes.Virtual) == methodDefinition.HasFlag(System.Reflection.MethodAttributes.NewSlot))
{
SetNewModifier(methodDecl);
}
if (IsCovariantReturnOverride(method))
{
RemoveAttribute(methodDecl, KnownAttribute.PreserveBaseOverrides);
methodDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);
methodDecl.Modifiers |= Modifiers.Override;
}
return methodDecl;
}
if (IsCovariantReturnOverride(method))
finally
{
RemoveAttribute(methodDecl, KnownAttribute.PreserveBaseOverrides);
methodDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);
methodDecl.Modifiers |= Modifiers.Override;
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileMethod(method.FullName, watch.ElapsedMilliseconds);
}
return methodDecl;
}
private bool IsCovariantReturnOverride(IEntity entity)
@ -1684,6 +1699,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1684,6 +1699,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == field);
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
@ -1746,6 +1762,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1746,6 +1762,11 @@ namespace ICSharpCode.Decompiler.CSharp
{
throw new DecompilerException(module, field, innerException);
}
finally
{
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileField(field.FullName, watch.ElapsedMilliseconds);
}
}
internal static bool IsFixedField(IField field, out IType type, out int elementCount)
@ -1768,6 +1789,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1768,6 +1789,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == property);
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
@ -1822,11 +1844,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1822,11 +1844,17 @@ namespace ICSharpCode.Decompiler.CSharp
{
throw new DecompilerException(module, property, innerException);
}
finally
{
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileProperty(property.FullName, watch.ElapsedMilliseconds);
}
}
EntityDeclaration DoDecompile(IEvent ev, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == ev);
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
@ -1862,6 +1890,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1862,6 +1890,11 @@ namespace ICSharpCode.Decompiler.CSharp
{
throw new DecompilerException(module, ev, innerException);
}
finally
{
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileEvent(ev.FullName, watch.ElapsedMilliseconds);
}
}
#region Sequence Points

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -100,6 +100,7 @@ @@ -100,6 +100,7 @@
<Compile Include="IL\Transforms\LdLocaDupInitObjTransform.cs" />
<Compile Include="IL\Transforms\PatternMatchingTransform.cs" />
<Compile Include="IL\Transforms\RemoveInfeasiblePathTransform.cs" />
<Compile Include="Instrumentation\DecompilerEventSource.cs" />
<Compile Include="Metadata\ReferenceLoadInfo.cs" />
<Compile Include="Semantics\OutVarResolveResult.cs" />
<Compile Include="SingleFileBundle.cs" />

59
ICSharpCode.Decompiler/Instrumentation/DecompilerEventSource.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
// Copyright (c) 2021 Christoph Wille
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Diagnostics.Tracing;
namespace ICSharpCode.Decompiler.Instrumentation
{
[EventSource(Name = "ICSharpCode.Decompiler")]
public sealed class DecompilerEventSource : EventSource
{
[Event(1, Level = EventLevel.Informational)]
public void DoDecompileEvent(string eventName, long elapsedMilliseconds)
{
WriteEvent(1, eventName, elapsedMilliseconds);
}
[Event(2, Level = EventLevel.Informational)]
public void DoDecompileProperty(string propertyName, long elapsedMilliseconds)
{
WriteEvent(2, propertyName, elapsedMilliseconds);
}
[Event(3, Level = EventLevel.Informational)]
public void DoDecompileField(string fieldName, long elapsedMilliseconds)
{
WriteEvent(3, fieldName, elapsedMilliseconds);
}
[Event(4, Level = EventLevel.Informational)]
public void DoDecompileTypeDefinition(string typeDefName, long elapsedMilliseconds)
{
WriteEvent(4, typeDefName, elapsedMilliseconds);
}
[Event(5, Level = EventLevel.Informational)]
public void DoDecompileMethod(string methodName, long elapsedMilliseconds)
{
WriteEvent(5, methodName, elapsedMilliseconds);
}
public static DecompilerEventSource Log = new DecompilerEventSource();
}
}
Loading…
Cancel
Save