зеркало из https://github.com/microsoft/BPerf.git
Additional support
This commit is contained in:
Родитель
a7dcb27ab8
Коммит
9dba8a3205
|
@ -51,7 +51,6 @@ jobs:
|
|||
|
||||
steps:
|
||||
|
||||
|
||||
- task: CMake@1
|
||||
displayName: CMake
|
||||
inputs:
|
||||
|
@ -92,14 +91,14 @@ jobs:
|
|||
- task: DotNetCoreCLI@2
|
||||
displayName: 'dotnet build'
|
||||
inputs:
|
||||
projects: '$(Build.SourcesDirectory)/CoreCLRProfiler/managed/Microsoft.BPerf.ProfilerInterop.csproj'
|
||||
projects: '$(Build.SourcesDirectory)/CoreCLRProfiler/managed/Microsoft.BPerf.ProfilerInteropGenerator.csproj'
|
||||
arguments: '-c Release'
|
||||
workingDirectory: CoreCLRProfiler/managed
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: $(Pipeline.Workspace)'
|
||||
inputs:
|
||||
SourceFolder: '$(Build.SourcesDirectory)/CoreCLRProfiler/managed/bin/Release/netstandard2.0'
|
||||
SourceFolder: '$(Build.SourcesDirectory)/CoreCLRProfiler/managed/bin/Release/netcoreapp3.1'
|
||||
Contents: Microsoft.BPerf.ProfilerInterop.dll
|
||||
TargetFolder: '$(Pipeline.Workspace)'
|
||||
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
namespace Microsoft.BPerf
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public static class ProfilerInterop
|
||||
{
|
||||
private const string dllName = "Microsoft.BPerf.CoreCLRProfiler";
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetNumberOfExceptionsThrown();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetNumberOfFiltersExecuted();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetNumberOfFinallysExecuted();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalILBytesJittedForMetadataMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfMetadataMethodsJitted();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfMetadataMethodsJitted();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalMachineCodeBytesGeneratedForMetadataMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalILBytesJittedForDynamicMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalMachineCodeBytesGeneratedForDynamicMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfDynamicMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfDynamicMethods();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalCachedMethodsSearched();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalCachedMethodsRestored();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalCachedMethodsMachineCodeBytesRestored();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfRuntimeSuspsensions();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfRuntimeSuspensionsForGC();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfRuntimeSuspensionsForGCPrep();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfClassesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfClassesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfClassLoadFailures();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfAssembliesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfAssembliesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfModulesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfModulesLoaded();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetCurrentNumberOfLogicalThreads();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfInducedGarbageCollections();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfGen0Collections();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfGen1Collections();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfGen2Collections();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetTotalNumberOfBytesInAllHeaps();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetGen0HeapSize();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetGen1HeapSize();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetGen2HeapSize();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetGen3HeapSize();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetFrozenHeapSize();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetNumberOfGCSegments();
|
||||
|
||||
[DllImport(dllName)]
|
||||
public static extern IntPtr GetNumberOfFrozenSegments();
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<DelaySign>false</DelaySign>
|
||||
<AssemblyOriginatorKeyFile>InteropSign.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="GenAssembly" AfterTargets="AfterBuild">
|
||||
<Exec Command="dotnet $(MSBuildThisFileDirectory)/bin/$(Configuration)/$(TargetFramework)/Microsoft.BPerf.ProfilerInteropGenerator.dll $(MSBuildThisFileDirectory)/bin/$(Configuration)/$(TargetFramework)/Microsoft.BPerf.ProfilerInterop.dll $(MSBuildThisFileDirectory)/publickey.bin" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,398 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.BPerf.BuildTools
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
Console.WriteLine("Usage: Microsoft.BPerf.BuildTools.exe OutputAssemblyPath PublicKeyBinPath");
|
||||
}
|
||||
|
||||
var outputAssemblyPath = args[0];
|
||||
var publicKey = File.ReadAllBytes(args[1]);
|
||||
CreateInternalCallsAssembly(Path.GetFileName(outputAssemblyPath), Path.GetFileNameWithoutExtension(outputAssemblyPath), new Version(1, 0, 0, 0), outputAssemblyPath, publicKey);
|
||||
}
|
||||
|
||||
public static void CreateInternalCallsAssembly(string outputModuleName, string outputAssemblyName, Version version, string outputAssemblyFilePath, byte[] publicKey)
|
||||
{
|
||||
var metadataBuilder = new MetadataBuilder();
|
||||
var publicKeyBlobHandle = metadataBuilder.GetOrAddBlob(publicKey);
|
||||
|
||||
metadataBuilder.AddModule(0, metadataBuilder.GetOrAddString(outputModuleName), metadataBuilder.GetOrAddGuid(Guid.NewGuid()), default, default);
|
||||
var assemblyHandle = metadataBuilder.AddAssembly(metadataBuilder.GetOrAddString(outputAssemblyName), version, default, publicKeyBlobHandle, AssemblyFlags.PublicKey, AssemblyHashAlgorithm.Sha1);
|
||||
metadataBuilder.AddTypeDefinition(default, default, metadataBuilder.GetOrAddString("<Module>"), default, MetadataTokens.FieldDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1));
|
||||
|
||||
var netstandardAssemblyRef = metadataBuilder.AddAssemblyReference(metadataBuilder.GetOrAddString("netstandard"), new Version(2, 0, 0, 0), default, metadataBuilder.GetOrAddBlob(new byte[] { 0xCC, 0x7B, 0x13, 0xFF, 0xCD, 0x2D, 0xDD, 0x51 }), default, default);
|
||||
var attributeTypeRef = metadataBuilder.AddTypeReference(netstandardAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("Attribute"));
|
||||
var assemblyNameField = CreateAssemblyNameField(metadataBuilder);
|
||||
var systemObjectTypeRef = metadataBuilder.AddTypeReference(netstandardAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("Object"));
|
||||
|
||||
var codeBuilder = new BlobBuilder();
|
||||
|
||||
var spcAssemblyRef = metadataBuilder.AddAssemblyReference(metadataBuilder.GetOrAddString("System.Private.CoreLib"), new Version(4, 0, 0, 0), default, metadataBuilder.GetOrAddBlob(new byte[] { 0x7C, 0xEC, 0x85, 0xD7, 0xBE, 0xA7, 0x79, 0x8E }), default, default);
|
||||
var gcTypeRef = metadataBuilder.AddTypeReference(spcAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("GC"));
|
||||
var exceptionTypeRef = metadataBuilder.AddTypeReference(spcAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("Exception"));
|
||||
var runtimeEventSourceHelperTypeRef = metadataBuilder.AddTypeReference(spcAssemblyRef, metadataBuilder.GetOrAddString("System.Diagnostics.Tracing"), metadataBuilder.GetOrAddString("RuntimeEventSourceHelper"));
|
||||
var systemReflectionTypeRef = metadataBuilder.AddTypeReference(spcAssemblyRef, metadataBuilder.GetOrAddString("System.Reflection"), metadataBuilder.GetOrAddString("Assembly"));
|
||||
var moduleReferenceHandle = metadataBuilder.AddModuleReference(metadataBuilder.GetOrAddString("Microsoft.BPerf.CoreCLRProfiler"));
|
||||
|
||||
metadataBuilder.AddTypeDefinition(TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, metadataBuilder.GetOrAddString("Microsoft.BPerf"), metadataBuilder.GetOrAddString("ProfilerInterop"), systemObjectTypeRef, assemblyNameField, MetadataTokens.MethodDefinitionHandle(1));
|
||||
|
||||
CreateGetGenerationSizeMethod(metadataBuilder, codeBuilder, CreateGetGenerationSizeMemberReferenceHandle(metadataBuilder, gcTypeRef));
|
||||
CreateNoArgsThunkMethod(metadataBuilder, codeBuilder, CreateNoArgsMemberReferenceHandle(metadataBuilder, runtimeEventSourceHelperTypeRef, "GetCpuUsage", TypeCode.Int32), "GetCpuUsage", TypeCode.Int32);
|
||||
CreateNoArgsThunkMethod(metadataBuilder, codeBuilder, CreateNoArgsMemberReferenceHandle(metadataBuilder, exceptionTypeRef, "GetExceptionCount", TypeCode.UInt32), "GetExceptionCount", TypeCode.UInt32);
|
||||
CreateNoArgsThunkMethod(metadataBuilder, codeBuilder, CreateNoArgsMemberReferenceHandle(metadataBuilder, gcTypeRef, "GetLastGCPercentTimeInGC", TypeCode.Int32), "GetLastGCPercentTimeInGC", TypeCode.Int32);
|
||||
CreateNoArgsThunkMethod(metadataBuilder, codeBuilder, CreateNoArgsMemberReferenceHandle(metadataBuilder, systemReflectionTypeRef, "GetAssemblyCount", TypeCode.UInt32), "GetAssemblyCount", TypeCode.UInt32);
|
||||
|
||||
int methodIndex = 5; // because we've put 5 methods prior to this method.
|
||||
|
||||
CreatePInvokeImpl(metadataBuilder, "GetNumberOfExceptionsThrown", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetNumberOfFiltersExecuted", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetNumberOfFinallysExecuted", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalILBytesJittedForMetadataMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfMetadataMethodsJitted", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfMetadataMethodsJitted", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalMachineCodeBytesGeneratedForMetadataMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalILBytesJittedForDynamicMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalMachineCodeBytesGeneratedForDynamicMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfDynamicMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfDynamicMethods", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalCachedMethodsSearched", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalCachedMethodsRestored", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalCachedMethodsMachineCodeBytesRestored", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfRuntimeSuspsensions", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfRuntimeSuspensionsForGC", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfRuntimeSuspensionsForGCPrep", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfClassesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfClassesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfClassLoadFailures", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfAssembliesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfAssembliesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfModulesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfModulesLoaded", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetCurrentNumberOfLogicalThreads", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfInducedGarbageCollections", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfGen0Collections", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfGen1Collections", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfGen2Collections", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetTotalNumberOfBytesInAllHeaps", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetGen0HeapSize", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetGen1HeapSize", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetGen2HeapSize", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetGen3HeapSize", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetFrozenHeapSize", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetNumberOfGCSegments", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "GetNumberOfFrozenSegments", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "EnableAllocationMonitoring", moduleReferenceHandle, ref methodIndex);
|
||||
CreatePInvokeImpl(metadataBuilder, "DisableAllocationMonitoring", moduleReferenceHandle, ref methodIndex);
|
||||
|
||||
var ignoresAccessChecksToAttributeConstructor = CreateIgnoresAccessChecksToAttributeConstructorMethod(metadataBuilder, codeBuilder, CreateAttributeConstructorMemberRef(metadataBuilder, attributeTypeRef), assemblyNameField);
|
||||
metadataBuilder.AddCustomAttribute(assemblyHandle, ignoresAccessChecksToAttributeConstructor, metadataBuilder.GetOrAddBlob(new byte[] { 0x01, 0x00, 0x16, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2E, 0x43, 0x6F, 0x72, 0x65, 0x4C, 0x69, 0x62, 0x00, 0x00 }));
|
||||
|
||||
var ignoresAccessChecksToAttributeTypeDefinitionHandle = metadataBuilder.AddTypeDefinition(TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, metadataBuilder.GetOrAddString("System.Runtime.CompilerServices"), metadataBuilder.GetOrAddString("IgnoresAccessChecksToAttribute"), attributeTypeRef, assemblyNameField, ignoresAccessChecksToAttributeConstructor);
|
||||
metadataBuilder.AddCustomAttribute(ignoresAccessChecksToAttributeTypeDefinitionHandle, CreateAttributeUsageAttributeMemberRef(metadataBuilder, netstandardAssemblyRef), metadataBuilder.GetOrAddBlob(new byte[] { 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x02, 0x0D, 0x41, 0x6C, 0x6C, 0x6F, 0x77, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x6C, 0x65, 0x01 }));
|
||||
metadataBuilder.AddMethodSemantics(CreateIgnoresAccessChecksToAttributeAssemblyNameProperty(metadataBuilder, ignoresAccessChecksToAttributeTypeDefinitionHandle), MethodSemanticsAttributes.Getter, CreateIgnoresAccessChecksToAttributeGetAssemblyNameMethod(metadataBuilder, codeBuilder, assemblyNameField));
|
||||
|
||||
using var fs = new FileStream(outputAssemblyFilePath, FileMode.Create, FileAccess.Write);
|
||||
WritePEImage(fs, metadataBuilder, codeBuilder);
|
||||
}
|
||||
|
||||
private static MemberReferenceHandle CreateGetGenerationSizeMemberReferenceHandle(MetadataBuilder metadataBuilder, TypeReferenceHandle systemReflectionTypeRef)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature().
|
||||
Parameters(1,
|
||||
returnType => returnType.Type().UInt64(),
|
||||
parameters =>
|
||||
{
|
||||
parameters.AddParameter().Type().Int32();
|
||||
});
|
||||
|
||||
return metadataBuilder.AddMemberReference(systemReflectionTypeRef, metadataBuilder.GetOrAddString("GetGenerationSize"), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
}
|
||||
|
||||
private static MemberReferenceHandle CreateNoArgsMemberReferenceHandle(MetadataBuilder metadataBuilder, TypeReferenceHandle typeRef, string methodName, TypeCode type)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature().
|
||||
Parameters(0,
|
||||
returnType =>
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TypeCode.Int32:
|
||||
returnType.Type().Int32();
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
returnType.Type().UInt32();
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
returnType.Type().UInt64();
|
||||
break;
|
||||
}
|
||||
},
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
return metadataBuilder.AddMemberReference(typeRef, metadataBuilder.GetOrAddString(methodName), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
}
|
||||
|
||||
private static void CreateGetGenerationSizeMethod(MetadataBuilder metadataBuilder, BlobBuilder codeBuilder, MemberReferenceHandle createGetGenerationSizeMemberReferenceHandle)
|
||||
{
|
||||
codeBuilder.Align(4);
|
||||
|
||||
var ilBuilder = new BlobBuilder();
|
||||
var il = new InstructionEncoder(ilBuilder);
|
||||
|
||||
il.LoadArgument(0);
|
||||
il.OpCode(ILOpCode.Call);
|
||||
il.Token(createGetGenerationSizeMemberReferenceHandle);
|
||||
il.OpCode(ILOpCode.Ret);
|
||||
|
||||
var methodBodyStream = new MethodBodyStreamEncoder(codeBuilder);
|
||||
int bodyOffset = methodBodyStream.AddMethodBody(il);
|
||||
ilBuilder.Clear();
|
||||
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature().
|
||||
Parameters(1,
|
||||
returnType => returnType.Type().UInt64(),
|
||||
parameters =>
|
||||
{
|
||||
parameters.AddParameter().Type().Int32();
|
||||
});
|
||||
|
||||
metadataBuilder.AddParameter(ParameterAttributes.None, metadataBuilder.GetOrAddString("generation"), 1);
|
||||
metadataBuilder.AddMethodDefinition(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadataBuilder.GetOrAddString("GetGenerationSize"), metadataBuilder.GetOrAddBlob(signatureBuilder), bodyOffset, parameterList: MetadataTokens.ParameterHandle(1));
|
||||
}
|
||||
|
||||
private static void CreateNoArgsThunkMethod(MetadataBuilder metadataBuilder, BlobBuilder codeBuilder, MemberReferenceHandle memberReferenceHandle, string methodName, TypeCode type)
|
||||
{
|
||||
codeBuilder.Align(4);
|
||||
|
||||
var ilBuilder = new BlobBuilder();
|
||||
var il = new InstructionEncoder(ilBuilder);
|
||||
|
||||
il.OpCode(ILOpCode.Call);
|
||||
il.Token(memberReferenceHandle);
|
||||
il.OpCode(ILOpCode.Ret);
|
||||
|
||||
var methodBodyStream = new MethodBodyStreamEncoder(codeBuilder);
|
||||
int bodyOffset = methodBodyStream.AddMethodBody(il);
|
||||
ilBuilder.Clear();
|
||||
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature().
|
||||
Parameters(0,
|
||||
returnType =>
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TypeCode.Int32:
|
||||
returnType.Type().Int32();
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
returnType.Type().UInt32();
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
returnType.Type().UInt64();
|
||||
break;
|
||||
}
|
||||
},
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
metadataBuilder.AddMethodDefinition(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadataBuilder.GetOrAddString(methodName), metadataBuilder.GetOrAddBlob(signatureBuilder), bodyOffset, parameterList: MetadataTokens.ParameterHandle(2));
|
||||
}
|
||||
|
||||
private static void CreatePInvokeImpl2(MetadataBuilder metadataBuilder, string methodName)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature().
|
||||
Parameters(0,
|
||||
returnType =>
|
||||
{
|
||||
returnType.Type().IntPtr();
|
||||
},
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
|
||||
metadataBuilder.AddMethodDefinition(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.PinvokeImpl, MethodImplAttributes.IL | MethodImplAttributes.PreserveSig | MethodImplAttributes.Managed, metadataBuilder.GetOrAddString(methodName), metadataBuilder.GetOrAddBlob(signatureBuilder), -1, parameterList: MetadataTokens.ParameterHandle(2));
|
||||
}
|
||||
|
||||
private static void CreatePInvokeImpl(MetadataBuilder metadataBuilder, string methodName, ModuleReferenceHandle moduleReferenceHandle, ref int methodRowIndex)
|
||||
{
|
||||
methodRowIndex++;
|
||||
metadataBuilder.AddMethodImport(MetadataTokens.MethodDefinitionHandle(methodRowIndex), MethodImportAttributes.CallingConventionWinApi, metadataBuilder.GetOrAddString(methodName), moduleReferenceHandle);
|
||||
CreatePInvokeImpl2(metadataBuilder, methodName);
|
||||
}
|
||||
|
||||
private static MemberReferenceHandle CreateAttributeConstructorMemberRef(MetadataBuilder metadataBuilder, TypeReferenceHandle attributeTypeRef)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature(SignatureCallingConvention.Default, 0, true).
|
||||
Parameters(0,
|
||||
returnType => returnType.Void(),
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
return metadataBuilder.AddMemberReference(attributeTypeRef, metadataBuilder.GetOrAddString(".ctor"), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
}
|
||||
|
||||
private static MemberReferenceHandle CreateAttributeUsageAttributeMemberRef(MetadataBuilder metadataBuilder, AssemblyReferenceHandle netstandardAssemblyRef)
|
||||
{
|
||||
var attributeTargetsTypeRef = metadataBuilder.AddTypeReference(netstandardAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("AttributeTargets"));
|
||||
var attributeUsageAttributeTypeRef = metadataBuilder.AddTypeReference(netstandardAssemblyRef, metadataBuilder.GetOrAddString("System"), metadataBuilder.GetOrAddString("AttributeUsageAttribute"));
|
||||
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature(SignatureCallingConvention.Default, 0, true).
|
||||
Parameters(1,
|
||||
returnType => returnType.Void(),
|
||||
parameters =>
|
||||
{
|
||||
parameters.AddParameter().Type().Type(attributeTargetsTypeRef, true);
|
||||
});
|
||||
|
||||
return metadataBuilder.AddMemberReference(attributeUsageAttributeTypeRef, metadataBuilder.GetOrAddString(".ctor"), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
}
|
||||
|
||||
private static FieldDefinitionHandle CreateAssemblyNameField(MetadataBuilder metadataBuilder)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).FieldSignature().String();
|
||||
|
||||
return metadataBuilder.AddFieldDefinition(FieldAttributes.Private | FieldAttributes.InitOnly, metadataBuilder.GetOrAddString("assemblyName"), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
}
|
||||
|
||||
private static PropertyDefinitionHandle CreateIgnoresAccessChecksToAttributeAssemblyNameProperty(MetadataBuilder metadataBuilder, TypeDefinitionHandle typeDefinitionHandle)
|
||||
{
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
PropertySignature(true).
|
||||
Parameters(0,
|
||||
returnType => returnType.Type().String(),
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
var propertyDefinitionHandle = metadataBuilder.AddProperty(PropertyAttributes.None, metadataBuilder.GetOrAddString("AssemblyName"), metadataBuilder.GetOrAddBlob(signatureBuilder));
|
||||
|
||||
metadataBuilder.AddPropertyMap(typeDefinitionHandle, propertyDefinitionHandle);
|
||||
|
||||
return propertyDefinitionHandle;
|
||||
}
|
||||
|
||||
private static MethodDefinitionHandle CreateIgnoresAccessChecksToAttributeConstructorMethod(MetadataBuilder metadataBuilder, BlobBuilder codeBuilder, MemberReferenceHandle attributeConstructor, FieldDefinitionHandle assemblyNameField)
|
||||
{
|
||||
codeBuilder.Align(4);
|
||||
|
||||
var ilBuilder = new BlobBuilder();
|
||||
var il = new InstructionEncoder(ilBuilder);
|
||||
|
||||
il.LoadArgument(0);
|
||||
il.OpCode(ILOpCode.Dup);
|
||||
il.OpCode(ILOpCode.Call);
|
||||
il.Token(attributeConstructor);
|
||||
il.LoadArgument(1);
|
||||
il.OpCode(ILOpCode.Stfld);
|
||||
il.Token(assemblyNameField);
|
||||
il.OpCode(ILOpCode.Ret);
|
||||
|
||||
var methodBodyStream = new MethodBodyStreamEncoder(codeBuilder);
|
||||
int mainBodyOffset = methodBodyStream.AddMethodBody(il);
|
||||
ilBuilder.Clear();
|
||||
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature(SignatureCallingConvention.Default, 0, true).
|
||||
Parameters(1,
|
||||
returnType => returnType.Void(),
|
||||
parameters =>
|
||||
{
|
||||
parameters.AddParameter().Type().String();
|
||||
});
|
||||
|
||||
metadataBuilder.AddParameter(ParameterAttributes.None, metadataBuilder.GetOrAddString("assemblyName"), 1);
|
||||
|
||||
return metadataBuilder.AddMethodDefinition(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadataBuilder.GetOrAddString(".ctor"), metadataBuilder.GetOrAddBlob(signatureBuilder), mainBodyOffset, parameterList: MetadataTokens.ParameterHandle(2));
|
||||
}
|
||||
|
||||
private static MethodDefinitionHandle CreateIgnoresAccessChecksToAttributeGetAssemblyNameMethod(MetadataBuilder metadataBuilder, BlobBuilder codeBuilder, FieldDefinitionHandle assemblyNameField)
|
||||
{
|
||||
codeBuilder.Align(4);
|
||||
|
||||
var ilBuilder = new BlobBuilder();
|
||||
var il = new InstructionEncoder(ilBuilder);
|
||||
|
||||
il.LoadArgument(0);
|
||||
il.OpCode(ILOpCode.Ldfld);
|
||||
il.Token(assemblyNameField);
|
||||
il.OpCode(ILOpCode.Ret);
|
||||
|
||||
var methodBodyStream = new MethodBodyStreamEncoder(codeBuilder);
|
||||
int bodyOffset = methodBodyStream.AddMethodBody(il);
|
||||
ilBuilder.Clear();
|
||||
|
||||
var signatureBuilder = new BlobBuilder();
|
||||
|
||||
new BlobEncoder(signatureBuilder).
|
||||
MethodSignature(SignatureCallingConvention.Default, 0, true).
|
||||
Parameters(0,
|
||||
returnType => returnType.Type().String(),
|
||||
parameters =>
|
||||
{
|
||||
});
|
||||
|
||||
return metadataBuilder.AddMethodDefinition(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadataBuilder.GetOrAddString("get_AssemblyName"), metadataBuilder.GetOrAddBlob(signatureBuilder), bodyOffset, parameterList: MetadataTokens.ParameterHandle(2));
|
||||
}
|
||||
|
||||
private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, Blob mvidFixup = default)
|
||||
{
|
||||
var peBuilder = new ManagedPEBuilder(new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll), new MetadataRootBuilder(metadataBuilder), ilBuilder, entryPoint: default, flags: CorFlags.ILOnly | CorFlags.StrongNameSigned);
|
||||
|
||||
var peBlob = new BlobBuilder();
|
||||
|
||||
var contentId = peBuilder.Serialize(peBlob);
|
||||
|
||||
if (!mvidFixup.IsDefault)
|
||||
{
|
||||
new BlobWriter(mvidFixup).WriteGuid(contentId.Guid);
|
||||
}
|
||||
|
||||
peBlob.WriteContentTo(peStream);
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
|
@ -89,7 +89,7 @@ HRESULT STDMETHODCALLTYPE BPerfProfilerCallback::Initialize(IUnknown* pICorProfi
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
const DWORD eventsMask = COR_PRF_MONITOR_THREADS |
|
||||
DWORD eventsMask = COR_PRF_MONITOR_THREADS |
|
||||
COR_PRF_MONITOR_SUSPENDS |
|
||||
COR_PRF_MONITOR_MODULE_LOADS |
|
||||
COR_PRF_MONITOR_CACHE_SEARCHES |
|
||||
|
@ -103,6 +103,12 @@ HRESULT STDMETHODCALLTYPE BPerfProfilerCallback::Initialize(IUnknown* pICorProfi
|
|||
COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS |
|
||||
COR_PRF_HIGH_BASIC_GC ;
|
||||
|
||||
const char* monitorObjectAllocated = std::getenv("BPERF_MONITOR_OBJECT_ALLOCATED");
|
||||
if (monitorObjectAllocated != nullptr && std::string(monitorObjectAllocated) == std::string("1"))
|
||||
{
|
||||
eventsMask |= COR_PRF_MONITOR_OBJECT_ALLOCATED;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
RegisterToETW();
|
||||
#endif
|
||||
|
@ -442,7 +448,7 @@ HRESULT STDMETHODCALLTYPE BPerfProfilerCallback::ObjectAllocated(ObjectID object
|
|||
size_t size;
|
||||
IfFailRet(this->corProfilerInfo->GetClassIDInfo2(classId, &moduleId, &typeDef, nullptr, 0, nullptr, nullptr));
|
||||
IfFailRet(this->corProfilerInfo->GetObjectSize2(objectId, &size));
|
||||
ReportLOHAllocation(moduleId, typeDef, size); // at the moment if we ever get this called it is back of LOH. This is because eventsHigh is restricting it.
|
||||
ReportObjectAllocation(moduleId, typeDef, size);
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -962,3 +968,19 @@ size_t BPerfProfilerCallback::GetNumberOfFrozenSegments() const
|
|||
{
|
||||
return this->numberOfFrozenSegments;
|
||||
}
|
||||
|
||||
bool BPerfProfilerCallback::EnableObjectAllocationMonitoring()
|
||||
{
|
||||
DWORD eventsLow, eventsHigh;
|
||||
this->corProfilerInfo->GetEventMask2(&eventsLow, &eventsHigh);
|
||||
eventsLow |= (COR_PRF_ENABLE_OBJECT_ALLOCATED);
|
||||
return this->corProfilerInfo->SetEventMask2(eventsLow, eventsHigh) == S_OK;
|
||||
}
|
||||
|
||||
bool BPerfProfilerCallback::DisableObjectAllocationMonitoring()
|
||||
{
|
||||
DWORD eventsLow, eventsHigh;
|
||||
this->corProfilerInfo->GetEventMask2(&eventsLow, &eventsHigh);
|
||||
eventsLow &= ~(COR_PRF_ENABLE_OBJECT_ALLOCATED);
|
||||
return this->corProfilerInfo->SetEventMask2(eventsLow, eventsHigh) == S_OK;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define IfFailRet(EXPR) do { HRESULT hr = (EXPR); if(FAILED(hr)) { return (hr); } } while (0)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
@ -175,6 +176,10 @@ public:
|
|||
size_t GetNumberOfGCSegments() const;
|
||||
size_t GetNumberOfFrozenSegments() const;
|
||||
|
||||
/* Control APIs */
|
||||
bool EnableObjectAllocationMonitoring();
|
||||
bool DisableObjectAllocationMonitoring();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
|
||||
{
|
||||
if (riid == __uuidof(ICorProfilerCallback9) ||
|
||||
|
|
|
@ -10,7 +10,7 @@ const char* Manifest = "<instrumentationManifest xmlns=\"http://schemas.microsof
|
|||
" <events xmlns=\"http://schemas.microsoft.com/win/2004/08/events\">\n"
|
||||
"<provider name=\"BPerfCoreCLRProfilerEventSource\" guid=\"{5a0f8851-25a1-54b6-6a29-300728cd9b65}\" resourceFileName=\"BPerfCoreCLRProfilerEventSource\" messageFileName=\"BPerfCoreCLRProfilerEventSource\" symbol=\"BPerfCoreCLRProfilerEventSource\">\n"
|
||||
" <tasks>\n"
|
||||
" <task name=\"LOHAllocation\" message=\"$(string.task_Log)\" value=\"1\"/>\n"
|
||||
" <task name=\"ObjectAllocation\" message=\"$(string.task_Log)\" value=\"1\"/>\n"
|
||||
" <task name=\"EventSourceMessage\" message=\"$(string.task_EventSourceMessage)\" value=\"65534\"/>\n"
|
||||
" </tasks>\n"
|
||||
" <opcodes>\n"
|
||||
|
@ -23,14 +23,14 @@ const char* Manifest = "<instrumentationManifest xmlns=\"http://schemas.microsof
|
|||
" </keywords>\n"
|
||||
" <events>\n"
|
||||
" <event value=\"0\" version=\"0\" level=\"win:LogAlways\" symbol=\"EventSourceMessage\" task=\"EventSourceMessage\" template=\"EventSourceMessageArgs\"/>\n"
|
||||
" <event value=\"1\" version=\"0\" level=\"win:LogAlways\" symbol=\"LOHAllocation\" task=\"LOHAllocation\" template=\"LOHAllocationArgs\"/>\n"
|
||||
" <event value=\"1\" version=\"0\" level=\"win:LogAlways\" symbol=\"ObjectAllocation\" task=\"ObjectAllocation\" template=\"ObjectAllocationArgs\"/>\n"
|
||||
" <event value=\"2\" version=\"0\" level=\"win:LogAlways\" symbol=\"TypeLoaded\" task=\"Log\" template=\"TypeLoadedArgs\"/>\n"
|
||||
" </events>\n"
|
||||
" <templates>\n"
|
||||
" <template tid=\"EventSourceMessageArgs\">\n"
|
||||
" <data name=\"message\" inType=\"win:UnicodeString\"/>\n"
|
||||
" </template>\n"
|
||||
" <template tid=\"LOHAllocationArgs\">\n"
|
||||
" <template tid=\"ObjectAllocationArgs\">\n"
|
||||
" <data name=\"moduleId\" inType=\"win:Pointer\"/>\n"
|
||||
" <data name=\"typeDef\" inType=\"win:UInt32\"/>\n"
|
||||
" <data name=\"size\" inType=\"win:UInt64\"/>\n"
|
||||
|
@ -118,7 +118,7 @@ static void BPerfEventEnableCallback(LPCGUID sourceId, ULONG isEnabled, UCHAR le
|
|||
WriteManifestEvent(RegHandle);
|
||||
}
|
||||
|
||||
static ULONG ReportLOHAllocation(UINT_PTR moduleId, unsigned typeDef, size_t size)
|
||||
static ULONG ReportObjectAllocation(UINT_PTR moduleId, unsigned typeDef, size_t size)
|
||||
{
|
||||
EVENT_DESCRIPTOR descriptor;
|
||||
descriptor.Id = 1;
|
||||
|
|
|
@ -394,6 +394,26 @@ extern "C" size_t GetTotalNumberOfBytesAllocatedSinceLastGC()
|
|||
return ProfilerInstance->GetTotalNumberOfBytesAllocatedSinceLastGC();
|
||||
}
|
||||
|
||||
extern "C" bool EnableObjectAllocationMonitoring()
|
||||
{
|
||||
if (ProfilerInstance == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ProfilerInstance->EnableObjectAllocationMonitoring();
|
||||
}
|
||||
|
||||
extern "C" bool DisableObjectAllocationMonitoring()
|
||||
{
|
||||
if (ProfilerInstance == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ProfilerInstance->DisableObjectAllocationMonitoring();
|
||||
}
|
||||
|
||||
class ClassFactory : public IClassFactory
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -40,3 +40,5 @@ EXPORTS
|
|||
GetFrozenHeapSize
|
||||
GetNumberOfGCSegments
|
||||
GetNumberOfFrozenSegments
|
||||
EnableObjectAllocationMonitoring
|
||||
DisableObjectAllocationMonitoring
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.BPerf.Dia2Lib" Version="1.0.0" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче