diff options
Diffstat (limited to 'src/inc')
-rw-r--r-- | src/inc/clrconfigvalues.h | 7 | ||||
-rw-r--r-- | src/inc/corerror.xml | 5 | ||||
-rw-r--r-- | src/inc/corprof.idl | 83 | ||||
-rw-r--r-- | src/inc/dacprivate.h | 55 | ||||
-rw-r--r-- | src/inc/dacvars.h | 8 | ||||
-rw-r--r-- | src/inc/profilepriv.inl | 15 | ||||
-rw-r--r-- | src/inc/simplerhash.h | 47 | ||||
-rw-r--r-- | src/inc/sospriv.idl | 12 | ||||
-rw-r--r-- | src/inc/switches.h | 2 |
9 files changed, 228 insertions, 6 deletions
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index 8f33e40c27..062ffb6e01 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -319,9 +319,12 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_StatsUpdatePeriod, W("StatsUpdatePeriod"), RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_SuspendTimeLog, W("SuspendTimeLog"), "Specifies the name of the log file for suspension statistics") RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_GCMixLog, W("GCMixLog"), "Specifies the name of the log file for GC mix statistics") CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_GCLatencyMode, W("GCLatencyMode"), "Specifies the GC latency mode - batch, interactive or low latency (note that the same thing can be specified via API which is the supported way)") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCConfigLogEnabled, W("GCConfigLogEnabled"), 0, "Specifies if you want to turn on config logging in GC") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCLogEnabled, W("GCLogEnabled"), 0, "Specifies if you want to turn on logging in GC") RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_GCLogFile, W("GCLogFile"), "Specifies the name of the GC log file") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCLogFileSize, W("GCLogFileSize"), 0, "Specifies the maximum GC log file size") +RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_GCConfigLogFile, W("GCConfigLogFile"), "Specifies the name of the GC config log file") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCLogFileSize, W("GCLogFileSize"), 0, "Specifies the GC log file size") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCCompactRatio, W("GCCompactRatio"), 0, "Specifies the ratio compacting GCs vs sweeping ") RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_GCPollType, W("GCPollType"), "") RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_NewGCCalc, W("NewGCCalc"), "", CLRConfig::REGUTIL_default) RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCprnLvl, W("GCprnLvl"), "Specifies the maximum level of GC logging") @@ -598,6 +601,8 @@ RETAIL_CONFIG_STRING_INFO(INTERNAL_WinMDPath, W("WinMDPath"), "Path for Windows // CONFIG_DWORD_INFO_EX(INTERNAL_LoaderHeapCallTracing, W("LoaderHeapCallTracing"), 0, "Loader heap troubleshooting", CLRConfig::REGUTIL_default) RETAIL_CONFIG_DWORD_INFO(INTERNAL_CodeHeapReserveForJumpStubs, W("CodeHeapReserveForJumpStubs"), 2, "Percentage of code heap to reserve for jump stubs") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_NGenReserveForJumpStubs, W("NGenReserveForJumpStubs"), 0, "Percentage of ngen image size to reserve for jump stubs") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_BreakOnOutOfMemoryWithinRange, W("BreakOnOutOfMemoryWithinRange"), 0, "Break before out of memory within range exception is thrown") // // Log diff --git a/src/inc/corerror.xml b/src/inc/corerror.xml index e4ddd973b0..98d41ea845 100644 --- a/src/inc/corerror.xml +++ b/src/inc/corerror.xml @@ -3650,6 +3650,11 @@ <Comment> This call can't be completed safely because the runtime is not suspended </Comment> </HRESULT> --> + +<HRESULT NumericValue="0x80131382"> + <SymbolicName>CORPROF_E_CALLBACK7_REQUIRED</SymbolicName> + <Comment> Profiler must implement ICorProfilerCallback7 interface for this call to be supported. </Comment> +</HRESULT> <HRESULT NumericValue="0x80131400"> <SymbolicName>SECURITY_E_XML_TO_ASN_ENCODING</SymbolicName> diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl index 894a8850be..328fbe01e1 100644 --- a/src/inc/corprof.idl +++ b/src/inc/corprof.idl @@ -615,9 +615,11 @@ typedef enum COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES = 0x00000001, + COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x00000002, + COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0, - COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = 0, + COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED, // MONITOR_IMMUTABLE represents all flags that may only be set during initialization. // Trying to change any of these flags elsewhere will result in a @@ -2349,6 +2351,29 @@ interface ICorProfilerCallback6 : ICorProfilerCallback5 }; +[ + object, + uuid(F76A2DBA-1D52-4539-866C-2AA518F9EFC3), + pointer_default(unique), + local +] +interface ICorProfilerCallback7 : ICorProfilerCallback6 +{ + // This event is triggered whenever the symbol stream associated with an + // in-memory module is updated. Even when symbols are provided up-front in + // a call to the managed API Assembly.Load(byte[], byte[], ...) the runtime + // may not actually associate the symbolic data with the module until after + // the ModuleLoadFinished callback has occured. This event provides a later + // opportunity to collect symbols for such modules. + // + // This event is controlled by the COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED + // event mask flag. + // + // Note: This event is not currently raised for symbols implicitly created or + // modified via Reflection.Emit APIs. + HRESULT ModuleInMemorySymbolsUpdated(ModuleID moduleId); +} + /* * COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific @@ -3699,6 +3724,62 @@ interface ICorProfilerInfo6 : ICorProfilerInfo5 [out] ICorProfilerMethodEnum** ppEnum); }; +[ + object, + uuid(9AEECC0D-63E0-4187-8C00-E312F503F663), + pointer_default(unique), + local +] +interface ICorProfilerInfo7 : ICorProfilerInfo6 +{ + /* + * Applies the newly emitted Metadata. + * + * This method can be used to apply the newly defined metadata by IMetadataEmit::Define* methods + * to the module. + * + * If metadata changes are made after ModuleLoadFinished callback, + * it is required to call this method before using the new metadata + */ + HRESULT ApplyMetaData( + [in] ModuleID moduleId); + + /* Returns the length of an in-memory symbol stream + * + * If the module has in-memory symbols the length of the stream will + * be placed in pCountSymbolBytes. If the module doesn't have in-memory + * symbols, *pCountSymbolBytes = 0 + * + * Returns S_OK if the length could be determined (even if it is 0) + * + * Note: The current implementation does not support reflection.emit. + * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case. + */ + HRESULT GetInMemorySymbolsLength( + [in] ModuleID moduleId, + [out] DWORD* pCountSymbolBytes); + + /* Reads bytes from an in-memory symbol stream + * + * This function attempts to read countSymbolBytes of data starting at offset + * symbolsReadOffset within the in-memory stream. The data will be copied into + * pSymbolBytes which is expected to have countSymbolBytes of space available. + * pCountSymbolsBytesRead contains the actual number of bytes read which + * may be less than countSymbolBytes if the end of the stream is reached. + * + * Returns S_OK if a non-zero number of bytes were read. + * + * Note: The current implementation does not support reflection.emit. + * CORPROF_E_MODULE_IS_DYNAMIC will be returned in that case. + */ + HRESULT ReadInMemorySymbols( + [in] ModuleID moduleId, + [in] DWORD symbolsReadOffset, + [out] BYTE* pSymbolBytes, + [in] DWORD countSymbolBytes, + [out] DWORD* pCountSymbolBytesRead); + +}; /* * This interface lets you iterate over methods in the runtime. diff --git a/src/inc/dacprivate.h b/src/inc/dacprivate.h index 087d89b2f1..5ec6e7fead 100644 --- a/src/inc/dacprivate.h +++ b/src/inc/dacprivate.h @@ -753,6 +753,61 @@ struct DacpOomData : ZeroInit<DacpOomData> } }; +// This is the value of max_idp_count in ndp\clr\src\vm\gcpriv.h +#define NUM_GC_DATA_POINTS 9 +// These are from ndp\clr\src\vm\gcrecord.h +#define MAX_COMPACT_REASONS_COUNT 11 +#define MAX_EXPAND_MECHANISMS_COUNT 6 +#define MAX_GC_MECHANISM_BITS_COUNT 2 +// This is from ndp\clr\src\vm\common.h +#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6 +struct DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData> +{ + size_t interestingDataPoints[NUM_GC_DATA_POINTS]; + size_t compactReasons[MAX_COMPACT_REASONS_COUNT]; + size_t expandMechanisms[MAX_EXPAND_MECHANISMS_COUNT]; + size_t bitMechanisms[MAX_GC_MECHANISM_BITS_COUNT]; + size_t globalMechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT]; + + HRESULT RequestGlobal(ISOSDacInterface *sos) + { + HRESULT hr; + ISOSDacInterface3 *psos3 = NULL; + if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) + { + hr = psos3->GetGCGlobalMechanisms(globalMechanisms); + psos3->Release(); + } + return hr; + } + + HRESULT Request(ISOSDacInterface *sos) + { + HRESULT hr; + ISOSDacInterface3 *psos3 = NULL; + if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) + { + hr = psos3->GetGCInterestingInfoStaticData(this); + psos3->Release(); + } + return hr; + } + + // Use this for Server mode, as there are multiple heaps, + // and you need to pass a heap address in addr. + HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr) + { + HRESULT hr; + ISOSDacInterface3 *psos3 = NULL; + if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface3), (void**) &psos3))) + { + hr = psos3->GetGCInterestingInfoData(addr, this); + psos3->Release(); + } + return hr; + } +}; + struct DacpGcHeapAnalyzeData : ZeroInit<DacpGcHeapAnalyzeData> { diff --git a/src/inc/dacvars.h b/src/inc/dacvars.h index 560d63a795..4195b863aa 100644 --- a/src/inc/dacvars.h +++ b/src/inc/dacvars.h @@ -201,6 +201,14 @@ DEFINE_DACVAR(ULONG, PTR_BYTE, dac__g_highest_address, ::g_highest_address) DEFINE_DACVAR(ULONG, GCHeap, dac__g_pGCHeap, ::g_pGCHeap) +#ifdef GC_CONFIG_DRIVEN +DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__interesting_data_per_heap, ::interesting_data_per_heap) +DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__compact_reasons_per_heap, ::compact_reasons_per_heap) +DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__expand_mechanisms_per_heap, ::expand_mechanisms_per_heap) +DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__interesting_mechanism_bits_per_heap, ::interesting_mechanism_bits_per_heap) +DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__gc_global_mechanisms, ::gc_global_mechanisms) +#endif //GC_CONFIG_DRIVEN + DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pThinLockThreadIdDispenser, ::g_pThinLockThreadIdDispenser) DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pModuleIndexDispenser, ::g_pModuleIndexDispenser) DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pObjectClass, ::g_pObjectClass) diff --git a/src/inc/profilepriv.inl b/src/inc/profilepriv.inl index 8e0e4ffa21..d8997fd8b6 100644 --- a/src/inc/profilepriv.inl +++ b/src/inc/profilepriv.inl @@ -722,6 +722,21 @@ inline BOOL CORProfilerAddsAssemblyReferences() ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES)); } +inline BOOL CORProfilerInMemorySymbolsUpdatesEnabled() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + CANNOT_TAKE_LOCK; + SO_NOT_MAINLINE; + } + CONTRACTL_END; + + return (CORProfilerPresent() && + ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED)); +} + #if defined(PROFILING_SUPPORTED) && !defined(CROSSGEN_COMPILE) #if defined(FEATURE_PROFAPI_ATTACH_DETACH) diff --git a/src/inc/simplerhash.h b/src/inc/simplerhash.h index 37b0b8fb0b..538eacf059 100644 --- a/src/inc/simplerhash.h +++ b/src/inc/simplerhash.h @@ -467,10 +467,49 @@ struct LargePrimitiveKeyFuncs: public KeyFuncsDefEquals<T> { static unsigned GetHashCode(const T val) { - UINT64 asUINT64 = static_cast<UINT64>(val); - unsigned res = asUINT64 >> 32; - res = res ^ static_cast<unsigned>(asUINT64 & ((((UINT64)1) << 32) - 1)); - return res; + // A static cast when T is a float or a double converts the value (i.e. 0.25 converts to 0) + // + // Instead we want to use all of the bits of a float to create the hash value + // So we cast the address of val to a pointer to an equivalent sized unsigned int + // This allows us to read the actual bit representation of a float type + // + // We can't read beyond the end of val, so we use sizeof(T) to determine + // exactly how many bytes to read + // + if (sizeof(T) == 8) + { + // cast &val to (UINT64 *) then deref to get the bits + UINT64 asUINT64 = *(reinterpret_cast<const UINT64 *>(&val)); + + // Get the upper and lower 32-bit values from the 64-bit value + UINT32 upper32 = static_cast<UINT32> (asUINT64 >> 32); + UINT32 lower32 = static_cast<UINT32> (asUINT64 & 0xFFFFFFFF); + + // Exclusive-Or the upper32 and the lower32 values + return static_cast<unsigned>(upper32 ^ lower32); + + } + else if (sizeof(T) == 4) + { + // cast &val to (UINT32 *) then deref to get the bits + UINT32 asUINT32 = *(reinterpret_cast<const UINT32 *>(&val)); + + // Just return the 32-bit value + return static_cast<unsigned>(asUINT32); + } + else if ((sizeof(T) == 2) || (sizeof(T) == 1)) + { + // For small sizes we must have an integer type + // so we can just use the static_cast. + // + return static_cast<unsigned>(val); + } + else + { + // Only support Hashing for types that are 8,4,2 or 1 bytes in size + assert(!"Unsupported size"); + return static_cast<unsigned>(val); // compile-time error here when we have a illegal size + } } }; diff --git a/src/inc/sospriv.idl b/src/inc/sospriv.idl index 9ef6cc2ffa..48c76cbf87 100644 --- a/src/inc/sospriv.idl +++ b/src/inc/sospriv.idl @@ -336,3 +336,15 @@ interface ISOSDacInterface2 : IUnknown HRESULT GetObjectExceptionData(CLRDATA_ADDRESS objAddr, struct DacpExceptionObjectData *data); HRESULT IsRCWDCOMProxy(CLRDATA_ADDRESS rcwAddr, BOOL* isDCOMProxy); }; + +[ + object, + local, + uuid(B08C5CDC-FD8A-49C5-AB38-5FEEF35235B4) +] +interface ISOSDacInterface3 : IUnknown +{ + HRESULT GetGCInterestingInfoData(CLRDATA_ADDRESS interestingInfoAddr, struct DacpGCInterestingInfoData *data); + HRESULT GetGCInterestingInfoStaticData(struct DacpGCInterestingInfoData *data); + HRESULT GetGCGlobalMechanisms(size_t* globalMechanisms); +};
\ No newline at end of file diff --git a/src/inc/switches.h b/src/inc/switches.h index b298b5563b..dd4da272c0 100644 --- a/src/inc/switches.h +++ b/src/inc/switches.h @@ -20,6 +20,8 @@ #define VERIFY_HEAP #endif +#define GC_CONFIG_DRIVEN + // define this to test data safety for the DAC. See code:DataTest::TestDataSafety. #define TEST_DATA_CONSISTENCY |