summaryrefslogtreecommitdiff
path: root/src/inc/corbbtprof.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/corbbtprof.h')
-rw-r--r--src/inc/corbbtprof.h589
1 files changed, 589 insertions, 0 deletions
diff --git a/src/inc/corbbtprof.h b/src/inc/corbbtprof.h
new file mode 100644
index 0000000000..2f69dcccc8
--- /dev/null
+++ b/src/inc/corbbtprof.h
@@ -0,0 +1,589 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*****************************************************************************\
+* *
+* CorBBTProf.h - File format for profile data *
+* *
+* Version 1.0 *
+*******************************************************************************
+* *
+* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
+* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
+* PURPOSE. *
+* *
+\*****************************************************************************/
+
+#ifndef _COR_BBTPROF_H_
+#define _COR_BBTPROF_H_
+
+#include <cor.h>
+#include <corinfo.h>
+
+const CorTokenType ibcExternalNamespace = CorTokenType(0x61000000);
+const CorTokenType ibcExternalType = CorTokenType(0x62000000);
+const CorTokenType ibcExternalSignature = CorTokenType(0x63000000);
+const CorTokenType ibcExternalMethod = CorTokenType(0x64000000);
+const CorTokenType ibcTypeSpec = CorTokenType(0x68000000);
+const CorTokenType ibcMethodSpec = CorTokenType(0x69000000);
+
+typedef mdToken idExternalNamespace; // External Namespace token in the IBC data
+typedef mdToken idExternalType; // External Type token in the IBC data
+typedef mdToken idExternalSignature; // External Signature token in the IBC data
+typedef mdToken idExternalMethod; // External Method token in the IBC data
+typedef mdToken idTypeSpec; // TypeSpec token in the IBC data
+typedef mdToken idMethodSpec; // MethodSpec token in the IBC data
+
+#define idExternalNamespaceNil ((idExternalNamespace) ibcExternalNamespace)
+#define idExternalTypeNil ((idExternalType) ibcExternalType)
+#define idExternalSignatureNil ((idExternalSignature) ibcExternalSignature)
+#define idExternalMethodNil ((idExternalMethod) ibcExternalMethod)
+#define idTypeSpecNil ((idTypeSpec) ibcTypeSpec)
+#define idMethodSpecNil ((idMethodSpec) ibcMethodSpec)
+
+//
+// File format:
+//
+// CORBBTPROF_FILE_HEADER
+// CORBBTPROF_SECTION_TABLE_HEADER
+// CORBBTPROF_SECTION_TABLE_ENTRY
+// ... (can be multiple entries)
+//
+// Method block counts section:
+// CORBBTPROF_METHOD_BLOCK_COUNTS_SECTION_HEADER
+// CORBBTPROF_METHOD_HEADER
+// CORBBTPROF_BLOCK_DATA
+// ... (can be multiple method header/block data entries)
+//
+// Method load order section:
+// CORBBTPROF_TOKEN_LIST_SECTION_HEADER
+// ... (list of tokens)
+//
+// Type token usage information
+// CORBBTPROF_TOKEN_LIST_SECTION_HEADER
+// ... (list of tokens)
+//
+
+// MethodDef token usage information
+// CORBBTPROF_TOKEN_LIST_SECTION_HEADER
+// ... (list of tokens)
+//
+
+// RIDs to not use slim headers section
+// CORBBTPROF_TOKEN_LIST_SECTION_HEADER
+// ... (list of tokens)
+//
+
+// Metadata hints to re-order some tables
+// Instantiated TypeSPecs to re-order EEClasses
+//
+// The header for the profile data file.
+// ... (list of CORBBTPROF_BLOB_ENTRY)
+// terminated by null
+
+struct CORBBTPROF_FILE_HEADER
+{
+ DWORD HeaderSize;
+ DWORD Magic;
+ DWORD Version;
+ GUID MVID;
+};
+
+// Optional in V1 and V2. Usually present in V2. Must be present in V3.
+struct CORBBTPROF_FILE_OPTIONAL_HEADER
+{
+ DWORD Size; // Including the size field
+ DWORD MinorVersion;
+ DWORD FileFlags; // Only in V3 or later
+ // future fields
+};
+
+enum CORBBTPROF_FILE_FLAGS
+{
+ CORBBTPROF_FILE_FLAG_MINIFIED = 1,
+ CORBBTPROF_FILE_FLAG_PARTIAL_NGEN = 2
+};
+
+enum
+{
+ CORBBTPROF_V0_VERSION = 0,
+ CORBBTPROF_V1_VERSION = 1,
+ CORBBTPROF_V2_VERSION = 2,
+ CORBBTPROF_V3_VERSION = 3,
+ CORBBTPROF_CURRENT_VERSION = CORBBTPROF_V2_VERSION, // V3 is opt-in
+ CORBBTPROF_MAGIC = 0xb1d0f11e,
+ CORBBTPROF_END_TOKEN = 0xb4356f98
+};
+
+//
+// The profile data can be mapped anywhere in memory. So instead of using pointers,
+// to denote sections, we will instead use offsets from the beginning of the file.
+//
+
+struct Section
+{
+ DWORD Offset;
+ DWORD Size;
+};
+
+//
+// Section types, where various sections contains different types of profile data.
+//
+
+#define CORBBTPROF_TOKEN_MAX_NUM_FLAGS 32
+
+enum TypeProfilingDataFlags
+{
+ // Important: update toolbox\ibcmerge\ibcmerge.cs if you change these
+ ReadMethodTable = 0, // 0x00001
+ ReadEEClass = 1, // 0x00002
+ WriteEEClass = 2, // 0x00004
+// ReadStoredEnumData = 3, // 0x00008
+ ReadFieldDescs = 4, // 0x00010
+ ReadCCtorInfo = 5, // 0x00020
+ ReadClassHashTable = 6, // 0x00040
+ ReadDispatchMap = 7, // 0x00080
+ ReadDispatchTable = 8, // 0x00100
+ ReadMethodTableWriteableData = 9, // 0x00200
+ ReadFieldMarshalers = 10, // 0x00400
+// Unused = 11, // 0x00800 ... Was WriteDispatchTable in the past
+// WriteMethodTable = 12, // 0x01000
+ WriteMethodTableWriteableData = 13, // 0x02000
+ ReadTypeDesc = 14, // 0x04000
+ WriteTypeDesc = 15, // 0x08000
+ ReadTypeHashTable = 16, // 0x10000
+// WriteTypeHashTable = 17, // 0x20000
+// ReadDictionary = 18, // 0x40000
+// WriteDictionary = 19, // 0x80000
+ ReadNonVirtualSlots = 20, // 0x100000
+};
+
+enum MethodProfilingDataFlags
+{
+ // Important: update toolbox\ibcmerge\ibcmerge.cs if you change these
+ ReadMethodCode = 0, // 0x00001
+ ReadMethodDesc = 1, // 0x00002
+ RunOnceMethod = 2, // 0x00004 // was CommonMethod
+ RunNeverMethod = 3, // 0x00008 // was MethodMetadataAccess
+// MethodStoredDataAccess = 4, // 0x00010
+ WriteMethodDesc = 5, // 0x00020
+// ReadFCallHash = 6, // 0x00040
+ ReadGCInfo = 7, // 0x00080
+ CommonReadGCInfo = 8, // 0x00100
+// ReadMethodDefRidMap = 9, // 0x00200
+ ReadCerMethodList = 10, // 0x00400
+ ReadMethodPrecode = 11, // 0x00800
+ WriteMethodPrecode = 12, // 0x01000
+};
+
+enum GeneralProfilingDataFlags
+{
+ // Important: update ibcmerge.cs if you change these
+ // ZapImage.h depends on 0xFFFFFFFF being an invalid flag value. If this
+ // changes, update ReadFlagWithMemory in that file.
+ // Important: make sure these don't collide with TypeProfilingDataFlags or MethodProfilingDataFlags
+ // These grow downward from CORBBTPROF_TOKEN_MAX_NUM_FLAGS-1 to minimize the chance of collision
+ ProfilingFlags_MetaData = 31, // 0x800...
+ CommonMetaData = 30, // 0x400...
+ RidMap = 29, // 0x200...
+ RVAFieldData = 28, // 0x100...
+ ProfilingFlags_MetaDataSearch = 27, // 0x080...
+};
+
+enum BlobType
+{
+ /* IMPORTANT: Keep the first four enums together in the same order and at
+ the very begining of this enum. See MetaModelPub.h for the order */
+ MetadataStringPool = 0,
+ MetadataGuidPool = 1,
+ MetadataBlobPool = 2,
+ MetadataUserStringPool = 3,
+
+ FirstMetadataPool = 0,
+ LastMetadataPool = 3,
+
+ // SectionFormat only supports tokens, which have to already exist in the module.
+ // For instantiated paramterized types, there may be no corresponding token
+ // in the module, if a dependent module caused the type to be instantiated.
+ // For such instantiated types, we save a blob/signature to identify the type.
+ //
+ ParamTypeSpec = 4, // Instantiated Type Signature
+ ParamMethodSpec = 5, // Instantiated Method Signature
+ ExternalNamespaceDef = 6, // External Namespace Token Definition
+ ExternalTypeDef = 7, // External Type Token Definition
+ ExternalSignatureDef = 8, // External Signature Definition
+ ExternalMethodDef = 9, // External Method Token Definition
+
+ IllegalBlob = 10, // Failed to allocate the blob
+
+ EndOfBlobStream = -1
+};
+
+enum SectionFormat
+{
+ // Important: update ibcmerge.cs if you change these
+ ScenarioInfo = 0,
+ MethodBlockCounts = 1, // Basic-block counts. Cold blocks will be placed in the cold-code section
+ BlobStream = 2, // metadata access, inst-type-spec and inst-method-spec blobs
+
+ FirstTokenFlagSection = 3,
+
+ ModuleProfilingData = FirstTokenFlagSection + (mdtModule >> 24),
+ TypeRefProfilingData = FirstTokenFlagSection + (mdtTypeRef >> 24),
+ TypeProfilingData = FirstTokenFlagSection + (mdtTypeDef >> 24),
+ FieldDefProfilingData = FirstTokenFlagSection + (mdtFieldDef >> 24),
+ MethodProfilingData = FirstTokenFlagSection + (mdtMethodDef >> 24),
+ ParamDefProfilingData = FirstTokenFlagSection + (mdtParamDef >> 24),
+ InterfaceImplProfilingData = FirstTokenFlagSection + (mdtInterfaceImpl >> 24),
+ MemberRefProfilingData = FirstTokenFlagSection + (mdtMemberRef >> 24),
+ CustomAttributeProfilingData = FirstTokenFlagSection + (mdtCustomAttribute >> 24),
+ PermissionProfilingData = FirstTokenFlagSection + (mdtPermission >> 24),
+ SignatureProfilingData = FirstTokenFlagSection + (mdtSignature >> 24),
+ EventProfilingData = FirstTokenFlagSection + (mdtEvent >> 24),
+ PropertyProfilingData = FirstTokenFlagSection + (mdtProperty >> 24),
+ ModuleRefProfilingData = FirstTokenFlagSection + (mdtModuleRef >> 24),
+ TypeSpecProfilingData = FirstTokenFlagSection + (mdtTypeSpec >> 24),
+ AssemblyProfilingData = FirstTokenFlagSection + (mdtAssembly >> 24),
+ AssemblyRefProfilingData = FirstTokenFlagSection + (mdtAssemblyRef >> 24),
+ FileProfilingData = FirstTokenFlagSection + (mdtFile >> 24),
+ ExportedTypeProfilingData = FirstTokenFlagSection + (mdtExportedType >> 24),
+ ManifestResourceProfilingData = FirstTokenFlagSection + (mdtManifestResource >> 24),
+ GenericParamProfilingData = FirstTokenFlagSection + (mdtGenericParam >> 24),
+ MethodSpecProfilingData = FirstTokenFlagSection + (mdtMethodSpec >> 24),
+ GenericParamConstraintProfilingData = FirstTokenFlagSection + (mdtGenericParamConstraint >> 24),
+
+ StringPoolProfilingData,
+ GuidPoolProfilingData,
+ BlobPoolProfilingData,
+ UserStringPoolProfilingData,
+
+ FirstMetadataPoolSection = StringPoolProfilingData,
+ LastMetadataPoolSection = UserStringPoolProfilingData,
+ LastTokenFlagSection = LastMetadataPoolSection,
+
+ IbcTypeSpecSection,
+ IbcMethodSpecSection,
+
+ GenericTypeProfilingData = 63, // Deprecated with V2 IBC data
+ SectionFormatCount = 64, // 0x40
+
+ SectionFormatInvalid = -1
+};
+
+struct CORBBTPROF_SECTION_TABLE_ENTRY
+{
+ SectionFormat FormatID;
+ Section Data;
+};
+
+struct CORBBTPROF_SECTION_TABLE_HEADER
+{
+ DWORD NumEntries;
+ CORBBTPROF_SECTION_TABLE_ENTRY Entries[0];
+};
+
+//
+// ScenarioInfo section
+//
+
+struct CORBBTPROF_SCENARIO_RUN
+{
+ FILETIME runTime; // the FILETIME when the scenario was cnt
+ GUID mvid; // The GUID of this assembly when the scenario was run (useful for incremental ibcdata)
+ DWORD cCmdLine; // the count of WCHAR's in the cmdLine for this run of the scenario
+ DWORD cSystemInfo; // the count of WCHAR's in the systemInfo string for this run of the scenario
+ WCHAR cmdLine[0]; // the command line used, the array is 'cName' in length
+// WCHAR systemInfo[]; // the system information, the array is 'cSystemInfo' in length
+
+ DWORD sizeofCmdLine()
+ {
+ return (cCmdLine * (DWORD)sizeof(WCHAR));
+ }
+
+ DWORD sizeofSystemInfo()
+ {
+ return (cSystemInfo * (DWORD)sizeof(WCHAR));
+ }
+
+ DWORD Size()
+ {
+ return (DWORD)sizeof(CORBBTPROF_SCENARIO_RUN) + sizeofCmdLine() + sizeofSystemInfo();
+ }
+
+ CORBBTPROF_SCENARIO_RUN* GetNextRun()
+ {
+ return reinterpret_cast< CORBBTPROF_SCENARIO_RUN* >(
+ reinterpret_cast< PBYTE >( this + 1 ) + Size() );
+ }
+};
+
+struct CORBBTPROF_SCENARIO_INFO
+{
+ DWORD ordinal; // the id number for this scenario
+ DWORD mask; // the one-bit mask use to identify this scenario
+ DWORD priority; // the priority of this scenario
+ DWORD numRuns; // the number of times this scenario was run
+ DWORD cName; // the count of WCHAR's in name[]
+ WCHAR name[0]; // the name of this scenario, the array is 'cName' in length
+// CORBBTPROF_SCENARIO_RUN run[]; // the array is 'numRuns' in length
+
+ DWORD sizeofName()
+ {
+ return (DWORD) (cName * sizeof(WCHAR));
+ }
+
+ DWORD Size()
+ {
+ return (DWORD) sizeof(CORBBTPROF_SCENARIO_INFO) + sizeofName() + sizeofRuns();
+ }
+
+ CORBBTPROF_SCENARIO_RUN* GetScenarioRun()
+ {
+ return reinterpret_cast< CORBBTPROF_SCENARIO_RUN* >(
+ reinterpret_cast< PBYTE >( this ) + (DWORD)sizeof(CORBBTPROF_SCENARIO_INFO) + sizeofName());
+ }
+
+ DWORD sizeofRuns()
+ {
+ DWORD sum = 0;
+ if (numRuns > 0)
+ {
+ DWORD cnt = 1;
+ CORBBTPROF_SCENARIO_RUN* pRun = GetScenarioRun();
+ do
+ {
+ sum += pRun->Size();
+ if (cnt == numRuns)
+ break;
+ cnt++;
+ pRun = pRun->GetNextRun();
+ }
+ while (true);
+ }
+ return sum;
+ }
+};
+
+struct CORBBTPROF_SCENARIO_HEADER
+{
+ DWORD size; // Size to skip to get to the next CORBBTPROF_SCENARIO_HEADER
+ CORBBTPROF_SCENARIO_INFO scenario;
+
+ DWORD Size()
+ {
+ return (DWORD) sizeof(CORBBTPROF_SCENARIO_HEADER) + scenario.sizeofName() + scenario.sizeofRuns();
+ }
+};
+
+struct CORBBTPROF_SCENARIO_INFO_SECTION_HEADER
+{
+ DWORD TotalNumRuns;
+ DWORD NumScenarios;
+// CORBBTPROF_SCENARIO_HEADER scenario[0]; // array is 'NumScenarios' in length
+};
+
+//
+// MethodBlockCounts section
+//
+
+struct CORBBTPROF_METHOD_BLOCK_COUNTS_SECTION_HEADER_V1
+{
+ DWORD NumMethods;
+ DWORD NumRuns;
+};
+
+struct CORBBTPROF_METHOD_BLOCK_COUNTS_SECTION_HEADER
+{
+ DWORD NumMethods;
+};
+
+struct CORBBTPROF_BLOCK_DATA // Also defined here code:ICorJitInfo.ProfileBuffer
+{
+ DWORD ILOffset;
+ DWORD ExecutionCount;
+};
+
+struct CORBBTPROF_METHOD_DETAIL_HEADER
+{
+ DWORD size; // Size to skip to get to the next CORBBTPROF_METHOD_DETAIL_HEADER at this level
+ DWORD kind; // Identifier that specifies what kind this CORBBTPROF_METHOD_DETAIL_HEADER actually represents
+
+ size_t Size()
+ {
+ return size;
+ }
+};
+
+//
+// This struct records the basic block execution counts for a method
+//
+struct CORBBTPROF_METHOD_INFO
+{
+ DWORD token; // token for this method
+ DWORD ILSize; // IL size for this method
+ DWORD cBlock; // count for block[]
+ CORBBTPROF_BLOCK_DATA block[0]; // actually 'cBlock' in length
+
+ size_t Size()
+ {
+ return sizeof(CORBBTPROF_METHOD_INFO) + sizeofBlock();
+ }
+
+ size_t sizeofBlock()
+ {
+ return cBlock * sizeof(CORBBTPROF_BLOCK_DATA);
+ }
+};
+
+struct CORBBTPROF_METHOD_HEADER_V1
+{
+ DWORD HeaderSize;
+ mdToken MethodToken;
+ DWORD Size;
+};
+
+struct CORBBTPROF_METHOD_HEADER
+{
+ DWORD size; // Size to skip to get to the next CORBBTPROF_METHOD_HEADER
+ DWORD cDetail; // the count of CORBBTPROF_METHOD_DETAIL_HEADER records that folow this record
+ CORBBTPROF_METHOD_INFO method; // Basic block execution counts for a method
+ // ... followed by 'cDetail' occurances of CORBBTPROF_METHOD_DETAIL_HEADER
+
+ size_t Size()
+ {
+ return sizeof(CORBBTPROF_METHOD_HEADER) + method.sizeofBlock();
+ }
+};
+
+
+struct CORBBTPROF_TOKEN_LIST_SECTION_HEADER
+{
+ DWORD NumTokens;
+};
+
+struct CORBBTPROF_TOKEN_LIST_ENTRY_V1
+{
+ mdToken token;
+ DWORD flags;
+};
+
+struct CORBBTPROF_TOKEN_INFO // Was CORBBTPROF_TOKEN_LIST_ENTRY
+{
+ mdToken token;
+ DWORD flags;
+ DWORD scenarios; // Could use UINT64 instead
+
+ CORBBTPROF_TOKEN_INFO()
+ : token(0)
+ , flags(0)
+ , scenarios(0)
+ {}
+
+ CORBBTPROF_TOKEN_INFO( mdToken t, DWORD f = 0, DWORD s = 0)
+ : token(t)
+ , flags(f)
+ , scenarios(s)
+ {}
+
+ CORBBTPROF_TOKEN_INFO( CORBBTPROF_TOKEN_INFO const & right )
+ : token(right.token)
+ , flags(right.flags)
+ , scenarios(right.scenarios)
+ {}
+
+ CORBBTPROF_TOKEN_INFO operator=( CORBBTPROF_TOKEN_INFO const & right )
+ {
+ token = right.token;
+ flags = right.flags;
+ scenarios = right.scenarios;
+ return *this;
+ }
+
+ bool operator<( CORBBTPROF_TOKEN_INFO const & right ) const
+ {
+ return token < right.token;
+ }
+};
+
+struct CORBBTPROF_BLOB_ENTRY_V1
+{
+ BlobType blobType;
+ DWORD flags;
+ DWORD cBuffer;
+ BYTE pBuffer[0]; // actually 'cBuffer' in length
+
+ CORBBTPROF_BLOB_ENTRY_V1 * GetNextEntry()
+ {
+ return reinterpret_cast< CORBBTPROF_BLOB_ENTRY_V1* >(
+ reinterpret_cast< PBYTE >( this + 1 ) + cBuffer );
+ }
+};
+
+struct CORBBTPROF_BLOB_ENTRY
+{
+ DWORD size;
+ BlobType type;
+ mdToken token; // The code:CORBBTPROF_BLOB_ENTRY.token field is not a real meta-data token
+ // but a look-alike that IBCMerge makes to represent blob entry
+
+ bool TypeIsValid()
+ {
+ return (type >= MetadataStringPool) && (type < IllegalBlob);
+ }
+
+ CORBBTPROF_BLOB_ENTRY * GetNextEntry()
+ {
+ return reinterpret_cast< CORBBTPROF_BLOB_ENTRY* >(
+ reinterpret_cast< PBYTE >( this ) + size);
+ }
+};
+
+struct CORBBTPROF_BLOB_PARAM_SIG_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ DWORD cSig;
+ COR_SIGNATURE sig[0]; // actually 'cSig' in length
+};
+
+struct CORBBTPROF_BLOB_NAMESPACE_DEF_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ DWORD cName;
+ CHAR name[0]; // actually cName in length
+};
+
+struct CORBBTPROF_BLOB_TYPE_DEF_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ mdToken assemblyRefToken;
+ mdToken nestedClassToken;
+ mdToken nameSpaceToken;
+ DWORD cName;
+ CHAR name[0]; // actually cName in length
+};
+
+struct CORBBTPROF_BLOB_SIGNATURE_DEF_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ DWORD cSig;
+ COR_SIGNATURE sig[0]; // actually 'cSig' in length
+};
+
+struct CORBBTPROF_BLOB_METHOD_DEF_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ mdToken nestedClassToken;
+ mdToken signatureToken;
+ DWORD cName;
+ CHAR name[0]; // actually cName in length
+};
+
+struct CORBBTPROF_BLOB_POOL_ENTRY
+{
+ CORBBTPROF_BLOB_ENTRY blob;
+ DWORD cBuffer;
+ BYTE buffer[0]; // actually 'cBuffer' in length
+};
+#endif /* COR_BBTPROF_H_ */