diff --git a/src/coreclr/gcinfo/gcinfoencoder.cpp b/src/coreclr/gcinfo/gcinfoencoder.cpp index d4596334bd3dc..57649af29bcd0 100644 --- a/src/coreclr/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/gcinfo/gcinfoencoder.cpp @@ -454,16 +454,6 @@ GcInfoEncoder::GcInfoEncoder( m_pAllocator = pJitAllocator; m_pNoMem = pNoMem; -#ifdef _DEBUG - CORINFO_METHOD_HANDLE methodHandle = pMethodInfo->ftn; - - // Get the name of the current method along with the enclosing class - // or module name. - m_MethodName = - pCorJitInfo->getMethodName(methodHandle, (const char **)&m_ModuleName); -#endif - - m_SlotTableSize = m_SlotTableInitialSize; m_SlotTable = (GcSlotDesc*) m_pAllocator->Alloc( m_SlotTableSize*sizeof(GcSlotDesc) ); m_NumSlots = 0; @@ -991,14 +981,19 @@ void GcInfoEncoder::Build() { #ifdef _DEBUG _ASSERTE(m_IsSlotTableFrozen || m_NumSlots == 0); -#endif _ASSERTE((1 << NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2) == NUM_NORM_CODE_OFFSETS_PER_CHUNK); + char methodName[256]; + m_pCorJitInfo->printMethodName(m_pMethodInfo->ftn, methodName, sizeof(methodName)); + + char className[256]; + m_pCorJitInfo->printClassName(m_pCorJitInfo->getMethodClass(m_pMethodInfo->ftn), className, sizeof(className)); + LOG((LF_GCINFO, LL_INFO100, - "Entering GcInfoEncoder::Build() for method %s[%s]\n", - m_MethodName, m_ModuleName - )); + "Entering GcInfoEncoder::Build() for method %s:%s\n", + className, methodName)); +#endif /////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index b4faaf34861d1..37d33c9bb474e 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2275,14 +2275,23 @@ class ICorStaticInfo // // Arguments: // handle - Direct object handle - // buffer - Pointer to buffer - // bufferSize - Buffer size - // pRequiredBufferSize - Full length of the textual UTF8 representation, can be used to call this - // API again with a bigger buffer to get the full string if the first buffer - // from that first attempt was not big enough. + // buffer - Pointer to buffer. Can be nullptr. + // bufferSize - Buffer size (in bytes). + // pRequiredBufferSize - Full length of the textual UTF8 representation, in bytes. + // Includes the null terminator, so the value is always at least 1, + // where 1 indicates an empty string. + // Can be used to call this API again with a bigger buffer to get the full + // string. // // Return Value: - // Bytes written to the given buffer, the range is [0..bufferSize) + // Bytes written to the buffer, excluding the null terminator. The range is [0..bufferSize). + // If bufferSize is 0, returns 0. + // + // Remarks: + // buffer and bufferSize can be respectively nullptr and 0 to query just the required buffer size. + // + // If the return value is less than bufferSize - 1 then the full string was written. In this case + // it is guaranteed that return value == *pRequiredBufferSize - 1. // virtual size_t printObjectDescription ( CORINFO_OBJECT_HANDLE handle, /* IN */ @@ -2303,11 +2312,6 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls ) = 0; - // for completeness - virtual const char* getClassName ( - CORINFO_CLASS_HANDLE cls - ) = 0; - // Return class name as in metadata, or nullptr if there is none. // Suitable for non-debugging use. virtual const char* getClassNameFromMetadata ( @@ -2322,40 +2326,14 @@ class ICorStaticInfo unsigned index ) = 0; - // Append a (possibly truncated) textual representation of the type `cls` to a preallocated buffer. - // - // Arguments: - // ppBuf - Pointer to buffer pointer. See below for details. - // pnBufLen - Pointer to buffer length. Must not be nullptr. See below for details. - // fNamespace - If true, include the namespace/enclosing classes. - // fFullInst - If true (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters. - // fAssembly - If true, suffix with a comma and the full assembly qualification. - // - // Returns the length of the representation, as a count of characters (but not including a terminating null character). - // Note that this will always be the actual number of characters required by the representation, even if the string - // was truncated when copied to the buffer. - // - // Operation: - // - // On entry, `*pnBufLen` specifies the size of the buffer pointed to by `*ppBuf` as a count of characters. - // There are two cases: - // 1. If the size is zero, the function computes the length of the representation and returns that. - // `ppBuf` is ignored (and may be nullptr) and `*ppBuf` and `*pnBufLen` are not updated. - // 2. If the size is non-zero, the buffer pointed to by `*ppBuf` is (at least) that size. The class name - // representation is copied to the buffer pointed to by `*ppBuf`. As many characters of the name as will fit in the - // buffer are copied. Thus, if the name is larger than the size of the buffer, the name will be truncated in the buffer. - // The buffer is guaranteed to be null terminated. Thus, the size must be large enough to include a terminating null - // character, or the string will be truncated to include one. On exit, `*pnBufLen` is updated by subtracting the - // number of characters that were actually copied to the buffer. Also, `*ppBuf` is updated to point at the null - // character that was added to the end of the name. - // - virtual int appendClassName( - _Outptr_opt_result_buffer_(*pnBufLen) char16_t** ppBuf, /* IN OUT */ - int* pnBufLen, /* IN OUT */ - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly + // Prints the name for a specified class including namespaces and enclosing + // classes. + // See printObjectDescription for documentation for the parameters. + virtual size_t printClassName( + CORINFO_CLASS_HANDLE cls, /* IN */ + char* buffer, /* OUT */ + size_t bufferSize, /* IN */ + size_t* pRequiredBufferSize = nullptr /* OUT */ ) = 0; // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & CORINFO_FLG_VALUECLASS, except faster. @@ -2545,10 +2523,6 @@ class ICorStaticInfo CORINFO_LOOKUP * pLookup ) = 0; - virtual const char* getHelperName( - CorInfoHelpFunc - ) = 0; - // This function tries to initialize the class (run the class constructor). // this function returns whether the JIT must insert helper calls before // accessing static field or method. @@ -2701,12 +2675,12 @@ class ICorStaticInfo // /**********************************************************************************/ - // this function is for debugging only. It returns the field name - // and if 'moduleName' is non-null, it sets it to something that will - // says which method (a class name, or a module name) - virtual const char* getFieldName ( - CORINFO_FIELD_HANDLE ftn, /* IN */ - const char **moduleName /* OUT */ + // Prints the name of a field into a buffer. See printObjectDescription for more documentation. + virtual size_t printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize = nullptr ) = 0; // return class it belongs to @@ -2962,19 +2936,14 @@ class ICorStaticInfo CORINFO_METHOD_HANDLE hMethod ) = 0; - // This function returns the method name and if 'moduleName' is non-null, - // it sets it to something that contains the method (a class - // name, or a module name). Note that the moduleName parameter is for - // diagnostics only. - // - // The method name returned is the same as getMethodNameFromMetadata except - // in the case of functions without metadata (e.g. IL stubs), where this - // function still returns a reasonable name while getMethodNameFromMetadata - // returns null. - virtual const char* getMethodName ( - CORINFO_METHOD_HANDLE ftn, /* IN */ - const char **moduleName /* OUT */ - ) = 0; + // This is similar to getMethodNameFromMetadata except that it also returns + // reasonable names for functions without metadata. + // See printObjectDescription for documentation of parameters. + virtual size_t printMethodName( + CORINFO_METHOD_HANDLE ftn, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize = nullptr) = 0; // Return method name as in metadata, or nullptr if there is none, // and optionally return the class, enclosing class, and namespace names diff --git a/src/coreclr/inc/gcinfoencoder.h b/src/coreclr/inc/gcinfoencoder.h index 33c1054aba718..490aacf8ede25 100644 --- a/src/coreclr/inc/gcinfoencoder.h +++ b/src/coreclr/inc/gcinfoencoder.h @@ -485,10 +485,6 @@ class GcInfoEncoder IAllocator* m_pAllocator; NoMemoryFunction m_pNoMem; -#ifdef _DEBUG - const char *m_MethodName, *m_ModuleName; -#endif - BitStreamWriter m_Info1; // Used for everything except for chunk encodings BitStreamWriter m_Info2; // Used for chunk encodings diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index dc05dced40a16..c912ee69d4c85 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -185,9 +185,6 @@ size_t printObjectDescription( CorInfoType asCorInfoType( CORINFO_CLASS_HANDLE cls) override; -const char* getClassName( - CORINFO_CLASS_HANDLE cls) override; - const char* getClassNameFromMetadata( CORINFO_CLASS_HANDLE cls, const char** namespaceName) override; @@ -196,13 +193,11 @@ CORINFO_CLASS_HANDLE getTypeInstantiationArgument( CORINFO_CLASS_HANDLE cls, unsigned index) override; -int appendClassName( - char16_t** ppBuf, - int* pnBufLen, +size_t printClassName( CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) override; + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) override; bool isValueClass( CORINFO_CLASS_HANDLE cls) override; @@ -308,9 +303,6 @@ void getReadyToRunDelegateCtorHelper( CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup) override; -const char* getHelperName( - CorInfoHelpFunc helpFunc) override; - CorInfoInitClassResult initClass( CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, @@ -384,9 +376,11 @@ CorInfoIsAccessAllowedResult canAccessClass( CORINFO_METHOD_HANDLE callerHandle, CORINFO_HELPER_DESC* pAccessHelper) override; -const char* getFieldName( - CORINFO_FIELD_HANDLE ftn, - const char** moduleName) override; +size_t printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) override; CORINFO_CLASS_HANDLE getFieldClass( CORINFO_FIELD_HANDLE field) override; @@ -497,9 +491,11 @@ const char16_t* getJitTimeLogFilename() override; mdMethodDef getMethodDefFromMethod( CORINFO_METHOD_HANDLE hMethod) override; -const char* getMethodName( +size_t printMethodName( CORINFO_METHOD_HANDLE ftn, - const char** moduleName) override; + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) override; const char* getMethodNameFromMetadata( CORINFO_METHOD_HANDLE ftn, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index a9c88b0a7c54d..d25e4fedf870f 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* e3c98d96-6e67-459a-9750-ebe799cfb788 */ - 0xe3c98d96, - 0x6e67, - 0x459a, - {0x97, 0x50, 0xeb, 0xe7, 0x99, 0xcf, 0xb7, 0x88} +constexpr GUID JITEEVersionIdentifier = { /* 1e794e80-ec63-4d7a-b11f-fcda6e7fe4f4 */ + 0x1e794e80, + 0xec63, + 0x4d7a, + {0xb1, 0x1f, 0xfc, 0xda, 0x6e, 0x7f, 0xe4, 0xf4} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index ed00cc191122b..1a6f869ba7052 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -43,10 +43,9 @@ DEF_CLR_API(isValidStringRef) DEF_CLR_API(getStringLiteral) DEF_CLR_API(printObjectDescription) DEF_CLR_API(asCorInfoType) -DEF_CLR_API(getClassName) DEF_CLR_API(getClassNameFromMetadata) DEF_CLR_API(getTypeInstantiationArgument) -DEF_CLR_API(appendClassName) +DEF_CLR_API(printClassName) DEF_CLR_API(isValueClass) DEF_CLR_API(canInlineTypeCheck) DEF_CLR_API(getClassAttribs) @@ -76,7 +75,6 @@ DEF_CLR_API(isObjectImmutable) DEF_CLR_API(getObjectType) DEF_CLR_API(getReadyToRunHelper) DEF_CLR_API(getReadyToRunDelegateCtorHelper) -DEF_CLR_API(getHelperName) DEF_CLR_API(initClass) DEF_CLR_API(classMustBeLoadedBeforeCodeIsRun) DEF_CLR_API(getBuiltinClass) @@ -97,7 +95,7 @@ DEF_CLR_API(getArrayRank) DEF_CLR_API(getArrayIntrinsicID) DEF_CLR_API(getArrayInitializationData) DEF_CLR_API(canAccessClass) -DEF_CLR_API(getFieldName) +DEF_CLR_API(printFieldName) DEF_CLR_API(getFieldClass) DEF_CLR_API(getFieldType) DEF_CLR_API(getFieldOffset) @@ -126,7 +124,7 @@ DEF_CLR_API(runWithSPMIErrorTrap) DEF_CLR_API(getEEInfo) DEF_CLR_API(getJitTimeLogFilename) DEF_CLR_API(getMethodDefFromMethod) -DEF_CLR_API(getMethodName) +DEF_CLR_API(printMethodName) DEF_CLR_API(getMethodNameFromMetadata) DEF_CLR_API(getMethodHash) DEF_CLR_API(findNameOfToken) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 8cedeccd48769..7bf0eb277a009 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -396,15 +396,6 @@ CorInfoType WrapICorJitInfo::asCorInfoType( return temp; } -const char* WrapICorJitInfo::getClassName( - CORINFO_CLASS_HANDLE cls) -{ - API_ENTER(getClassName); - const char* temp = wrapHnd->getClassName(cls); - API_LEAVE(getClassName); - return temp; -} - const char* WrapICorJitInfo::getClassNameFromMetadata( CORINFO_CLASS_HANDLE cls, const char** namespaceName) @@ -425,17 +416,15 @@ CORINFO_CLASS_HANDLE WrapICorJitInfo::getTypeInstantiationArgument( return temp; } -int WrapICorJitInfo::appendClassName( - char16_t** ppBuf, - int* pnBufLen, +size_t WrapICorJitInfo::printClassName( CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - API_ENTER(appendClassName); - int temp = wrapHnd->appendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); - API_LEAVE(appendClassName); + API_ENTER(printClassName); + size_t temp = wrapHnd->printClassName(cls, buffer, bufferSize, pRequiredBufferSize); + API_LEAVE(printClassName); return temp; } @@ -715,15 +704,6 @@ void WrapICorJitInfo::getReadyToRunDelegateCtorHelper( API_LEAVE(getReadyToRunDelegateCtorHelper); } -const char* WrapICorJitInfo::getHelperName( - CorInfoHelpFunc helpFunc) -{ - API_ENTER(getHelperName); - const char* temp = wrapHnd->getHelperName(helpFunc); - API_LEAVE(getHelperName); - return temp; -} - CorInfoInitClassResult WrapICorJitInfo::initClass( CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, @@ -916,13 +896,15 @@ CorInfoIsAccessAllowedResult WrapICorJitInfo::canAccessClass( return temp; } -const char* WrapICorJitInfo::getFieldName( - CORINFO_FIELD_HANDLE ftn, - const char** moduleName) +size_t WrapICorJitInfo::printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - API_ENTER(getFieldName); - const char* temp = wrapHnd->getFieldName(ftn, moduleName); - API_LEAVE(getFieldName); + API_ENTER(printFieldName); + size_t temp = wrapHnd->printFieldName(field, buffer, bufferSize, pRequiredBufferSize); + API_LEAVE(printFieldName); return temp; } @@ -1193,13 +1175,15 @@ mdMethodDef WrapICorJitInfo::getMethodDefFromMethod( return temp; } -const char* WrapICorJitInfo::getMethodName( +size_t WrapICorJitInfo::printMethodName( CORINFO_METHOD_HANDLE ftn, - const char** moduleName) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - API_ENTER(getMethodName); - const char* temp = wrapHnd->getMethodName(ftn, moduleName); - API_LEAVE(getMethodName); + API_ENTER(printMethodName); + size_t temp = wrapHnd->printMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); + API_LEAVE(printMethodName); return temp; } diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 0c660d71b52eb..e0dc50a0e83e0 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -7548,9 +7548,12 @@ void CodeGen::genReportRichDebugInfoInlineTreeToFile(FILE* file, InlineContext* fprintf(file, "\"ILOffset\":%u,", context->GetLocation().GetOffset()); fprintf(file, "\"LocationFlags\":%u,", (uint32_t)context->GetLocation().EncodeSourceTypes()); fprintf(file, "\"ExactILOffset\":%u,", context->GetActualCallOffset()); - const char* className; - const char* methodName = compiler->eeGetMethodName(context->GetCallee(), &className); - fprintf(file, "\"MethodName\":\"%s\",", methodName); + auto append = [&]() { + char buffer[256]; + const char* methodName = compiler->eeGetMethodName(context->GetCallee(), buffer, sizeof(buffer)); + fprintf(file, "\"MethodName\":\"%s\",", methodName); + }; + append(); fprintf(file, "\"Inlinees\":["); if (context->GetChild() != nullptr) { diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index e14f3439ee643..fde3d27730dcb 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -1789,7 +1789,7 @@ void Compiler::compInit(ArenaAllocator* pAlloc, info.compClassName = nullptr; info.compFullName = nullptr; - info.compMethodName = eeGetMethodName(methodHnd, nullptr); + info.compMethodName = eeGetMethodName(methodHnd); info.compClassName = eeGetClassName(info.compClassHnd); info.compFullName = eeGetMethodFullName(methodHnd); info.compPerfScore = 0.0; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 34a0b475d09ab..8e2b4f55712d3 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7588,37 +7588,51 @@ class Compiler var_types eeGetFieldType(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE* pStructHnd = nullptr); + template + void eeAppendPrint(class StringPrinter* printer, TPrint print); + // Conventions: the "base" primitive printing functions take StringPrinter* + // and do not do any SPMI handling. There are then convenience printing + // functions exposed on top that have SPMI handling and additional buffer + // handling. Note that the strings returned are never truncated here. void eePrintJitType(class StringPrinter* printer, var_types jitType); - void eePrintType(class StringPrinter* printer, - CORINFO_CLASS_HANDLE clsHnd, - bool includeNamespaces, - bool includeInstantiation); - void eePrintTypeOrJitAlias(class StringPrinter* printer, - CORINFO_CLASS_HANDLE clsHnd, - bool includeNamespaces, - bool includeInstantiation); + void eePrintType(class StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, bool includeInstantiation); + void eePrintTypeOrJitAlias(class StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, bool includeInstantiation); void eePrintMethod(class StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE methodHnd, CORINFO_SIG_INFO* sig, - bool includeNamespaces, bool includeClassInstantiation, bool includeMethodInstantiation, bool includeSignature, bool includeReturnType, bool includeThisSpecifier); -#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(TRACK_LSRA_STATS) - const char* eeGetMethodName(CORINFO_METHOD_HANDLE hnd, const char** className); + void eePrintField(class StringPrinter* printer, CORINFO_FIELD_HANDLE fldHnd, bool includeType); + const char* eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd, bool includeReturnType = true, - bool includeThisSpecifier = true); - unsigned compMethodHash(CORINFO_METHOD_HANDLE methodHandle); + bool includeThisSpecifier = true, + char* buffer = nullptr, + size_t bufferSize = 0); + + const char* eeGetMethodName(CORINFO_METHOD_HANDLE methHnd, char* buffer = nullptr, size_t bufferSize = 0); + + const char* eeGetFieldName(CORINFO_FIELD_HANDLE fldHnd, + bool includeType, + char* buffer = nullptr, + size_t bufferSize = 0); + + const char* eeGetClassName(CORINFO_CLASS_HANDLE clsHnd, char* buffer = nullptr, size_t bufferSize = 0); - bool eeIsNativeMethod(CORINFO_METHOD_HANDLE method); - CORINFO_METHOD_HANDLE eeGetMethodHandleForNative(CORINFO_METHOD_HANDLE method); + void eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle); + const char* eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd); + +#if defined(DEBUG) + unsigned eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd); #endif + unsigned compMethodHash(CORINFO_METHOD_HANDLE methodHandle); + var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig); var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig, bool* isPinned); CORINFO_CLASS_HANDLE eeGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE list); @@ -7640,10 +7654,6 @@ class Compiler void eeGetMethodSig(CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* retSig, CORINFO_CLASS_HANDLE owner = nullptr); - // Method entry-points, instrs - - CORINFO_METHOD_HANDLE eeMarkNativeTarget(CORINFO_METHOD_HANDLE method); - CORINFO_EE_INFO eeInfo; bool eeInfoInitialized; @@ -7848,16 +7858,6 @@ class Compiler // Utility functions - const char* eeGetFieldName(CORINFO_FIELD_HANDLE fieldHnd, const char** classNamePtr = nullptr); - -#if defined(DEBUG) - void eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle); - unsigned eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd); - const char16_t* eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd); -#endif - - const char* eeGetClassName(CORINFO_CLASS_HANDLE clsHnd); - static CORINFO_METHOD_HANDLE eeFindHelper(unsigned helper); static CorInfoHelpFunc eeGetHelperNum(CORINFO_METHOD_HANDLE method); diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index b89ebaf08715e..ba73f5439a37a 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -3649,33 +3649,6 @@ inline bool jitStaticFldIsGlobAddr(CORINFO_FIELD_HANDLE fldHnd) return (fldHnd == FLD_GLOBAL_DS || fldHnd == FLD_GLOBAL_FS); } -#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(FEATURE_TRACELOGGING) - -inline bool Compiler::eeIsNativeMethod(CORINFO_METHOD_HANDLE method) -{ - return ((((size_t)method) & 0x2) == 0x2); -} - -inline CORINFO_METHOD_HANDLE Compiler::eeGetMethodHandleForNative(CORINFO_METHOD_HANDLE method) -{ - assert((((size_t)method) & 0x3) == 0x2); - return (CORINFO_METHOD_HANDLE)(((size_t)method) & ~0x3); -} -#endif - -inline CORINFO_METHOD_HANDLE Compiler::eeMarkNativeTarget(CORINFO_METHOD_HANDLE method) -{ - assert((((size_t)method) & 0x3) == 0); - if (method == nullptr) - { - return method; - } - else - { - return (CORINFO_METHOD_HANDLE)(((size_t)method) | 0x2); - } -} - /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index b98322abe683e..c9528a9585ebd 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -120,6 +120,16 @@ extern "C" DLLEXPORT void jitStartup(ICorJitHost* jitHost) g_jitInitialized = true; } +#ifndef DEBUG +void jitprintf(const char* fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + vfprintf(jitstdout, fmt, vl); + va_end(vl); +} +#endif + void jitShutdown(bool processIsTerminating) { if (!g_jitInitialized) @@ -1401,148 +1411,7 @@ bool Compiler::eeRunWithSPMIErrorTrapImp(void (*function)(void*), void* param) return info.compCompHnd->runWithSPMIErrorTrap(function, param); } -/***************************************************************************** - * - * Utility functions - */ - -#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(FEATURE_TRACELOGGING) - -/*****************************************************************************/ - -// static helper names - constant array -const char* jitHlpFuncTable[CORINFO_HELP_COUNT] = { -#define JITHELPER(code, pfnHelper, sig) #code, -#define DYNAMICJITHELPER(code, pfnHelper, sig) #code, -#include "jithelpers.h" -}; - -/***************************************************************************** -* -* Filter wrapper to handle exception filtering. -* On Unix compilers don't support SEH. -*/ - -struct FilterSuperPMIExceptionsParam_ee_il -{ - Compiler* pThis; - Compiler::Info* pJitInfo; - CORINFO_FIELD_HANDLE field; - CORINFO_METHOD_HANDLE method; - CORINFO_CLASS_HANDLE clazz; - const char** classNamePtr; - const char* fieldOrMethodOrClassNamePtr; - char16_t* classNameWidePtr; - unsigned classSize; - EXCEPTION_POINTERS exceptionPointers; -}; - -const char* Compiler::eeGetMethodName(CORINFO_METHOD_HANDLE method, const char** classNamePtr) -{ - if (eeGetHelperNum(method) != CORINFO_HELP_UNDEF) - { - if (classNamePtr != nullptr) - { - *classNamePtr = "HELPER"; - } - CorInfoHelpFunc ftnNum = eeGetHelperNum(method); - const char* name = info.compCompHnd->getHelperName(ftnNum); - - // If it's something unknown from a RET VM, or from SuperPMI, then use our own helper name table. - if ((strcmp(name, "AnyJITHelper") == 0) || (strcmp(name, "Yickish helper name") == 0)) - { - if ((unsigned)ftnNum < CORINFO_HELP_COUNT) - { - name = jitHlpFuncTable[ftnNum]; - } - } - return name; - } - - if (eeIsNativeMethod(method)) - { - if (classNamePtr != nullptr) - { - *classNamePtr = "NATIVE"; - } - method = eeGetMethodHandleForNative(method); - } - - FilterSuperPMIExceptionsParam_ee_il param; - - param.pThis = this; - param.pJitInfo = &info; - param.method = method; - param.classNamePtr = classNamePtr; - - bool success = eeRunWithSPMIErrorTrap( - [](FilterSuperPMIExceptionsParam_ee_il* pParam) { - pParam->fieldOrMethodOrClassNamePtr = - pParam->pJitInfo->compCompHnd->getMethodName(pParam->method, pParam->classNamePtr); - }, - ¶m); - - if (!success) - { - if (param.classNamePtr != nullptr) - { - *(param.classNamePtr) = "hackishClassName"; - } - - param.fieldOrMethodOrClassNamePtr = "hackishMethodName"; - } - - return param.fieldOrMethodOrClassNamePtr; -} - -const char* Compiler::eeGetFieldName(CORINFO_FIELD_HANDLE field, const char** classNamePtr) -{ - FilterSuperPMIExceptionsParam_ee_il param; - - param.pThis = this; - param.pJitInfo = &info; - param.field = field; - param.classNamePtr = classNamePtr; - - bool success = eeRunWithSPMIErrorTrap( - [](FilterSuperPMIExceptionsParam_ee_il* pParam) { - pParam->fieldOrMethodOrClassNamePtr = - pParam->pJitInfo->compCompHnd->getFieldName(pParam->field, pParam->classNamePtr); - }, - ¶m); - - if (!success) - { - param.fieldOrMethodOrClassNamePtr = "hackishFieldName"; - } - - return param.fieldOrMethodOrClassNamePtr; -} - -//------------------------------------------------------------------------ -// eeGetClassName: -// Get the name (including namespace and instantiation) of a type. -// If missing information (in SPMI), then return a placeholder string. -// -// Return value: -// The name string. -// -const char* Compiler::eeGetClassName(CORINFO_CLASS_HANDLE clsHnd) -{ - StringPrinter printer(getAllocator(CMK_DebugOnly)); - if (!eeRunFunctorWithSPMIErrorTrap([&]() { eePrintType(&printer, clsHnd, true, true); })) - { - printer.Truncate(0); - printer.Append("hackishClassName"); - } - - return printer.GetBuffer(); -} - -#endif // DEBUG || FEATURE_JIT_METHOD_PERF - #ifdef DEBUG - //------------------------------------------------------------------------ // eeTryGetClassSize: wraps getClassSize but if doing SuperPMI replay // and the value isn't found, use a bogus size. @@ -1554,114 +1423,10 @@ const char* Compiler::eeGetClassName(CORINFO_CLASS_HANDLE clsHnd) // unsigned Compiler::eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd) { - FilterSuperPMIExceptionsParam_ee_il param; - - param.pThis = this; - param.pJitInfo = &info; - param.clazz = clsHnd; - - bool success = eeRunWithSPMIErrorTrap( - [](FilterSuperPMIExceptionsParam_ee_il* pParam) { - pParam->classSize = pParam->pJitInfo->compCompHnd->getClassSize(pParam->clazz); - }, - ¶m); + unsigned classSize = UINT_MAX; + eeRunFunctorWithSPMIErrorTrap([&]() { classSize = info.compCompHnd->getClassSize(clsHnd); }); - if (!success) - { - param.classSize = (unsigned)-1; // Use the maximum unsigned value as the size - } - return param.classSize; + return classSize; } -//------------------------------------------------------------------------ -// eeGetShortClassName: wraps appendClassName to provide functionality -// similar to getClassName(), but returns a class name that is shortened, -// not using full assembly info. -// -// Arguments: -// clsHnd - the class handle to get the type name of -// -// Return value: -// string class name. Note: unlike eeGetClassName/getClassName, this string is -// allocated from the JIT heap, so care should possibly be taken to avoid leaking it. -// It returns a char16_t string, since that's what appendClassName returns. -// -const char16_t* Compiler::eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd) -{ - FilterSuperPMIExceptionsParam_ee_il param; - - param.pThis = this; - param.pJitInfo = &info; - param.clazz = clsHnd; - - bool success = eeRunWithSPMIErrorTrap( - [](FilterSuperPMIExceptionsParam_ee_il* pParam) { - int len = 0; - constexpr bool fNamespace = true; - constexpr bool fFullInst = false; - constexpr bool fAssembly = false; - - // Warning: crossgen2 doesn't fully implement the `appendClassName` API. - // We need to pass size zero, get back the actual buffer size required, allocate that space, - // and call the API again to get the full string. - int cchStrLen = pParam->pJitInfo->compCompHnd->appendClassName(nullptr, &len, pParam->clazz, fNamespace, - fFullInst, fAssembly); - - size_t cchBufLen = (size_t)cchStrLen + /* null terminator */ 1; - pParam->classNameWidePtr = pParam->pThis->getAllocator(CMK_DebugOnly).allocate(cchBufLen); - char16_t* pbuf = pParam->classNameWidePtr; - len = (int)cchBufLen; - - int cchResultStrLen = pParam->pJitInfo->compCompHnd->appendClassName(&pbuf, &len, pParam->clazz, fNamespace, - fFullInst, fAssembly); - noway_assert(cchStrLen == cchResultStrLen); - noway_assert(pParam->classNameWidePtr[cchResultStrLen] == 0); - }, - ¶m); - - if (!success) - { - const char16_t substituteClassName[] = u"hackishClassName"; - size_t cchLen = ArrLen(substituteClassName); - param.classNameWidePtr = getAllocator(CMK_DebugOnly).allocate(cchLen); - memcpy(param.classNameWidePtr, substituteClassName, cchLen * sizeof(char16_t)); - } - - return param.classNameWidePtr; -} - -void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle) -{ - const size_t maxStrSize = 64; - char str[maxStrSize]; - size_t actualLen = 0; - - // Ignore potential SPMI failures - bool success = eeRunFunctorWithSPMIErrorTrap( - [&]() { actualLen = this->info.compCompHnd->printObjectDescription(handle, str, maxStrSize); }); - - if (!success) - { - return; - } - - for (size_t i = 0; i < actualLen; i++) - { - // Replace \n and \r symbols with whitespaces - if (str[i] == '\n' || str[i] == '\r') - { - str[i] = ' '; - } - } - - printf("%s '%s'\n", prefix, str); -} -#else // DEBUG -void jitprintf(const char* fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - vfprintf(jitstdout, fmt, vl); - va_end(vl); -} #endif // !DEBUG diff --git a/src/coreclr/jit/eeinterface.cpp b/src/coreclr/jit/eeinterface.cpp index b82a909218e9b..d9852afb9e537 100644 --- a/src/coreclr/jit/eeinterface.cpp +++ b/src/coreclr/jit/eeinterface.cpp @@ -10,9 +10,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -// ONLY FUNCTIONS common to all variants of the JIT (EXE, DLL) should go here) -// otherwise they belong in the corresponding directory. - #include "jitpch.h" #ifdef _MSC_VER @@ -83,8 +80,6 @@ void StringPrinter::Append(char chr) m_bufferIndex++; } -#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) - //------------------------------------------------------------------------ // eePrintJitType: // Print a JIT type. @@ -98,6 +93,34 @@ void Compiler::eePrintJitType(StringPrinter* printer, var_types jitType) printer->Append(varTypeName(jitType)); } +//------------------------------------------------------------------------ +// eeAppendPrint: +// Append the output of one of the JIT-EE 'print' functions to a StringPrinter. +// +// Arguments: +// printer - the printer +// print - A functor to print the string that follows the conventions of the JIT-EE print* functions. +// +template +void Compiler::eeAppendPrint(StringPrinter* printer, TPrint print) +{ + size_t requiredBufferSize; + char buffer[256]; + size_t printed = print(buffer, sizeof(buffer), &requiredBufferSize); + if (requiredBufferSize <= sizeof(buffer)) + { + assert(printed == requiredBufferSize - 1); + printer->Append(buffer); + } + else + { + char* pBuffer = new (this, CMK_DebugOnly) char[requiredBufferSize]; + printed = print(pBuffer, requiredBufferSize, nullptr); + assert(printed == requiredBufferSize - 1); + printer->Append(pBuffer); + } +} + //------------------------------------------------------------------------ // eePrintType: // Print a type given by a class handle. @@ -108,49 +131,34 @@ void Compiler::eePrintJitType(StringPrinter* printer, var_types jitType) // includeNamespace - Whether to print namespaces before type names // includeInstantiation - Whether to print the instantiation of the class // -void Compiler::eePrintType(StringPrinter* printer, - CORINFO_CLASS_HANDLE clsHnd, - bool includeNamespace, - bool includeInstantiation) +void Compiler::eePrintType(StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, bool includeInstantiation) { - const char* namespaceName; - const char* className = info.compCompHnd->getClassNameFromMetadata(clsHnd, &namespaceName); - if (className == nullptr) + unsigned arrayRank = info.compCompHnd->getArrayRank(clsHnd); + if (arrayRank > 0) { - unsigned arrayRank = info.compCompHnd->getArrayRank(clsHnd); - if (arrayRank > 0) + CORINFO_CLASS_HANDLE childClsHnd; + CorInfoType childType = info.compCompHnd->getChildType(clsHnd, &childClsHnd); + if ((childType == CORINFO_TYPE_CLASS) || (childType == CORINFO_TYPE_VALUECLASS)) { - CORINFO_CLASS_HANDLE childClsHnd; - CorInfoType childType = info.compCompHnd->getChildType(clsHnd, &childClsHnd); - if ((childType == CORINFO_TYPE_CLASS) || (childType == CORINFO_TYPE_VALUECLASS)) - { - eePrintType(printer, childClsHnd, includeNamespace, includeInstantiation); - } - else - { - eePrintJitType(printer, JitType2PreciseVarType(childType)); - } - - printer->Append('['); - for (unsigned i = 1; i < arrayRank; i++) - { - printer->Append(','); - } - printer->Append(']'); - return; + eePrintType(printer, childClsHnd, includeInstantiation); + } + else + { + eePrintJitType(printer, JitType2PreciseVarType(childType)); } - namespaceName = nullptr; - className = ""; - } - - if (includeNamespace && (namespaceName != nullptr) && (namespaceName[0] != '\0')) - { - printer->Append(namespaceName); - printer->Append('.'); + printer->Append('['); + for (unsigned i = 1; i < arrayRank; i++) + { + printer->Append(','); + } + printer->Append(']'); + return; } - printer->Append(className); + eeAppendPrint(printer, [&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { + return info.compCompHnd->printClassName(clsHnd, buffer, bufferSize, requiredBufferSize); + }); if (!includeInstantiation) { @@ -169,7 +177,7 @@ void Compiler::eePrintType(StringPrinter* printer, printer->Append(pref); pref = ','; - eePrintTypeOrJitAlias(printer, typeArg, includeNamespace, true); + eePrintTypeOrJitAlias(printer, typeArg, true); } if (pref != '[') @@ -186,18 +194,14 @@ void Compiler::eePrintType(StringPrinter* printer, // Arguments: // printer - the printer // clsHnd - Handle for the class -// includeNamespace - Whether to print namespaces before type names // includeInstantiation - Whether to print the instantiation of the class // -void Compiler::eePrintTypeOrJitAlias(StringPrinter* printer, - CORINFO_CLASS_HANDLE clsHnd, - bool includeNamespace, - bool includeInstantiation) +void Compiler::eePrintTypeOrJitAlias(StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, bool includeInstantiation) { CorInfoType typ = info.compCompHnd->asCorInfoType(clsHnd); if ((typ == CORINFO_TYPE_CLASS) || (typ == CORINFO_TYPE_VALUECLASS)) { - eePrintType(printer, clsHnd, includeNamespace, includeInstantiation); + eePrintType(printer, clsHnd, includeInstantiation); } else { @@ -205,6 +209,12 @@ void Compiler::eePrintTypeOrJitAlias(StringPrinter* printer, } } +static const char* s_jitHelperNames[CORINFO_HELP_COUNT] = { +#define JITHELPER(code, pfnHelper, sig) #code, +#define DYNAMICJITHELPER(code, pfnHelper, sig) #code, +#include "jithelpers.h" +}; + //------------------------------------------------------------------------ // eePrintMethod: // Print a method given by a method handle, its owning class handle and its @@ -214,7 +224,6 @@ void Compiler::eePrintTypeOrJitAlias(StringPrinter* printer, // printer - the printer // clsHnd - Handle for the owning class, or NO_CLASS_HANDLE to not print the class. // sig - The signature of the method. -// includeNamespaces - Whether to print namespaces before type names. // includeClassInstantiation - Whether to print the class instantiation. Only valid when clsHnd is passed. // includeMethodInstantiation - Whether to print the method instantiation. Requires the signature to be passed. // includeSignature - Whether to print the signature. @@ -226,21 +235,29 @@ void Compiler::eePrintMethod(StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, - bool includeNamespaces, bool includeClassInstantiation, bool includeMethodInstantiation, bool includeSignature, bool includeReturnType, bool includeThisSpecifier) { + CorInfoHelpFunc helper = eeGetHelperNum(methHnd); + if (helper != CORINFO_HELP_UNDEF) + { + assert(helper < CORINFO_HELP_COUNT); + printer->Append(s_jitHelperNames[helper]); + return; + } + if (clsHnd != NO_CLASS_HANDLE) { - eePrintType(printer, clsHnd, includeNamespaces, includeClassInstantiation); + eePrintType(printer, clsHnd, includeClassInstantiation); printer->Append(':'); } - const char* methName = info.compCompHnd->getMethodName(methHnd, nullptr); - printer->Append(methName); + eeAppendPrint(printer, [&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { + return info.compCompHnd->printMethodName(methHnd, buffer, bufferSize, requiredBufferSize); + }); if (includeMethodInstantiation && (sig->sigInst.methInstCount > 0)) { @@ -252,7 +269,7 @@ void Compiler::eePrintMethod(StringPrinter* printer, printer->Append(','); } - eePrintTypeOrJitAlias(printer, sig->sigInst.methInst[i], includeNamespaces, true); + eePrintTypeOrJitAlias(printer, sig->sigInst.methInst[i], true); } printer->Append(']'); } @@ -278,7 +295,7 @@ void Compiler::eePrintMethod(StringPrinter* printer, // For some SIMD struct types we can get a nullptr back from eeGetArgClass on Linux/X64 if (clsHnd != NO_CLASS_HANDLE) { - eePrintType(printer, clsHnd, includeNamespaces, true); + eePrintType(printer, clsHnd, true); break; } } @@ -308,7 +325,7 @@ void Compiler::eePrintMethod(StringPrinter* printer, CORINFO_CLASS_HANDLE clsHnd = sig->retTypeClass; if (clsHnd != NO_CLASS_HANDLE) { - eePrintType(printer, clsHnd, includeNamespaces, true); + eePrintType(printer, clsHnd, true); break; } } @@ -329,6 +346,29 @@ void Compiler::eePrintMethod(StringPrinter* printer, } } +//------------------------------------------------------------------------ +// eePrintField: +// Print a field name to a StringPrinter. +// +// Arguments: +// printer - the printer +// fld - The field +// includeType - Whether to prefix the string by : +// +void Compiler::eePrintField(StringPrinter* printer, CORINFO_FIELD_HANDLE fld, bool includeType) +{ + if (includeType) + { + CORINFO_CLASS_HANDLE cls = info.compCompHnd->getFieldClass(fld); + eePrintType(printer, cls, true); + printer->Append(':'); + } + + eeAppendPrint(printer, [&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { + return info.compCompHnd->printFieldName(fld, buffer, bufferSize, requiredBufferSize); + }); +} + //------------------------------------------------------------------------ // eeGetMethodFullName: // Get a string describing a method. @@ -337,27 +377,32 @@ void Compiler::eePrintMethod(StringPrinter* printer, // hnd - the method handle // includeReturnType - Whether to include the return type in the string // includeThisSpecifier - Whether to include a specifier for whether this is an instance method. +// buffer - Preexisting buffer to use (can be nullptr to allocate on heap). +// bufferSize - Size of preexisting buffer. +// +// Remarks: +// If the final string is larger than the preexisting buffer can contain then +// the string will be jit memory allocated. // // Returns: // The string. // -const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd, bool includeReturnType, bool includeThisSpecifier) +const char* Compiler::eeGetMethodFullName( + CORINFO_METHOD_HANDLE hnd, bool includeReturnType, bool includeThisSpecifier, char* buffer, size_t bufferSize) { - const char* className; - const char* methodName = eeGetMethodName(hnd, &className); - if ((eeGetHelperNum(hnd) != CORINFO_HELP_UNDEF) || eeIsNativeMethod(hnd)) + CorInfoHelpFunc helper = eeGetHelperNum(hnd); + if (helper != CORINFO_HELP_UNDEF) { - return methodName; + return s_jitHelperNames[helper]; } - StringPrinter p(getAllocator(CMK_DebugOnly)); + StringPrinter p(getAllocator(CMK_DebugOnly), buffer, bufferSize); CORINFO_CLASS_HANDLE clsHnd = NO_CLASS_HANDLE; bool success = eeRunFunctorWithSPMIErrorTrap([&]() { clsHnd = info.compCompHnd->getMethodClass(hnd); CORINFO_SIG_INFO sig; eeGetMethodSig(hnd, &sig); eePrintMethod(&p, clsHnd, hnd, &sig, - /* includeNamespaces */ true, /* includeClassInstantiation */ true, /* includeMethodInstantiation */ true, /* includeSignature */ true, includeReturnType, includeThisSpecifier); @@ -375,7 +420,6 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd, bool includ success = eeRunFunctorWithSPMIErrorTrap([&]() { eePrintMethod(&p, clsHnd, hnd, /* sig */ nullptr, - /* includeNamespaces */ true, /* includeClassInstantiation */ false, /* includeMethodInstantiation */ false, /* includeSignature */ false, @@ -394,7 +438,6 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd, bool includ success = eeRunFunctorWithSPMIErrorTrap([&]() { eePrintMethod(&p, nullptr, hnd, /* sig */ nullptr, - /* includeNamespaces */ true, /* includeClassInstantiation */ false, /* includeMethodInstantiation */ false, /* includeSignature */ false, @@ -408,10 +451,168 @@ const char* Compiler::eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd, bool includ } p.Truncate(0); - p.Append("hackishClassName:hackishMethodName(?)"); + p.Append(""); return p.GetBuffer(); } -#endif // defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) +//------------------------------------------------------------------------ +// eeGetMethodName: +// Get the name of a method. +// +// Arguments: +// hnd - the method handle +// buffer - Preexisting buffer to use (can be nullptr to allocate on heap). +// bufferSize - Size of preexisting buffer. +// +// Remarks: +// See eeGetMethodFullName for documentation about the buffer. +// +// Returns: +// The string. +// +const char* Compiler::eeGetMethodName(CORINFO_METHOD_HANDLE methHnd, char* buffer, size_t bufferSize) +{ + StringPrinter p(getAllocator(CMK_DebugOnly), buffer, bufferSize); + bool success = eeRunFunctorWithSPMIErrorTrap([&]() { + eePrintMethod(&p, NO_CLASS_HANDLE, methHnd, + /* sig */ nullptr, + /* includeClassInstantiation */ false, + /* includeMethodInstantiation */ false, + /* includeSignature */ false, + /* includeReturnType */ false, + /* includeThisSpecifier */ false); + + }); -/*****************************************************************************/ + if (!success) + { + p.Truncate(0); + p.Append(""); + } + + return p.GetBuffer(); +} + +//------------------------------------------------------------------------ +// eeGetFieldName: +// Get a string describing a field. +// +// Arguments: +// fldHnd - the field handle +// includeType - Whether to prefix the string with : +// buffer - Preexisting buffer to use (can be nullptr to allocate on heap). +// bufferSize - Size of preexisting buffer. +// +// Remarks: +// See eeGetMethodFullName for documentation about the buffer. +// +// Returns: +// The string. +// +const char* Compiler::eeGetFieldName(CORINFO_FIELD_HANDLE fldHnd, bool includeType, char* buffer, size_t bufferSize) +{ + StringPrinter p(getAllocator(CMK_DebugOnly), buffer, bufferSize); + bool success = eeRunFunctorWithSPMIErrorTrap([&]() { eePrintField(&p, fldHnd, includeType); }); + + if (success) + { + return p.GetBuffer(); + } + + p.Truncate(0); + + if (includeType) + { + p.Append(":"); + + success = eeRunFunctorWithSPMIErrorTrap([&]() { eePrintField(&p, fldHnd, false); }); + + if (success) + { + return p.GetBuffer(); + } + + p.Truncate(0); + } + + if (includeType) + { + p.Append(":"); + } + + p.Append(""); + return p.GetBuffer(); +} + +//------------------------------------------------------------------------ +// eeGetClassName: +// Get the name (including namespace and instantiation) of a type. +// If missing information (in SPMI), then return a placeholder string. +// +// Parameters: +// clsHnd - the handle of the class +// buffer - a buffer to use for scratch space, or null pointer to allocate a new string. +// bufferSize - the size of buffer. If the final class name is longer a new string will be allocated. +// +// Return value: +// The name string. +// +const char* Compiler::eeGetClassName(CORINFO_CLASS_HANDLE clsHnd, char* buffer, size_t bufferSize) +{ + StringPrinter printer(getAllocator(CMK_DebugOnly), buffer, bufferSize); + if (!eeRunFunctorWithSPMIErrorTrap([&]() { eePrintType(&printer, clsHnd, true); })) + { + printer.Truncate(0); + printer.Append(""); + } + + return printer.GetBuffer(); +} + +//------------------------------------------------------------------------ +// eeGetShortClassName: Returns class name with no instantiation. +// +// Arguments: +// clsHnd - the class handle to get the type name of +// +// Return value: +// String without instantiation. +// +const char* Compiler::eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd) +{ + StringPrinter printer(getAllocator(CMK_DebugOnly)); + if (!eeRunFunctorWithSPMIErrorTrap([&]() { eePrintType(&printer, clsHnd, false); })) + { + printer.Truncate(0); + printer.Append(""); + } + + return printer.GetBuffer(); +} + +void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle) +{ + const size_t maxStrSize = 64; + char str[maxStrSize]; + size_t actualLen = 0; + + // Ignore potential SPMI failures + bool success = eeRunFunctorWithSPMIErrorTrap( + [&]() { actualLen = this->info.compCompHnd->printObjectDescription(handle, str, maxStrSize); }); + + if (!success) + { + return; + } + + for (size_t i = 0; i < actualLen; i++) + { + // Replace \n and \r symbols with whitespaces + if (str[i] == '\n' || str[i] == '\r') + { + str[i] = ' '; + } + } + + printf("%s '%s'\n", prefix, str); +} diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index a7644c3bcbd0f..13dec732941d0 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3355,48 +3355,6 @@ emitter::instrDesc* emitter::emitNewInstrCallDir(int argCnt, } } -/*****************************************************************************/ -#ifdef DEBUG -/***************************************************************************** - * - * Return a string with the name of the given class field (blank string (not - * NULL) is returned when the name isn't available). - */ - -const char* emitter::emitFldName(CORINFO_FIELD_HANDLE fieldVal) -{ - if (emitComp->opts.varNames) - { - const char* memberName; - const char* className; - - const int TEMP_BUFFER_LEN = 1024; - static char buff[TEMP_BUFFER_LEN]; - - memberName = emitComp->eeGetFieldName(fieldVal, &className); - - sprintf_s(buff, TEMP_BUFFER_LEN, "'<%s>.%s'", className, memberName); - return buff; - } - else - { - return ""; - } -} - -/***************************************************************************** - * - * Return a string with the name of the given function (blank string (not - * NULL) is returned when the name isn't available). - */ - -const char* emitter::emitFncName(CORINFO_METHOD_HANDLE methHnd) -{ - return emitComp->eeGetMethodFullName(methHnd); -} - -#endif // DEBUG - /***************************************************************************** * * Be very careful, some instruction descriptors are allocated as "tiny" and @@ -4100,24 +4058,23 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag flag &= GTF_ICON_HDL_MASK; + char buffer[256]; + if (cookie != 0) { if (flag == GTF_ICON_FTN_ADDR) { - const char* className = nullptr; - const char* methName = - emitComp->eeGetMethodName(reinterpret_cast(cookie), &className); - printf("%s code for %s:%s", commentPrefix, className, methName); + const char* methName = emitComp->eeGetMethodFullName(reinterpret_cast(cookie), true, + true, buffer, sizeof(buffer)); + printf("%s code for %s", commentPrefix, methName); return; } if ((flag == GTF_ICON_STATIC_HDL) || (flag == GTF_ICON_STATIC_BOX_PTR)) { - const char* className = nullptr; const char* fieldName = - emitComp->eeGetFieldName(reinterpret_cast(cookie), &className); - printf("%s %s for %s%s%s", commentPrefix, flag == GTF_ICON_STATIC_HDL ? "data" : "box", className, - className != nullptr ? ":" : "", fieldName); + emitComp->eeGetFieldName(reinterpret_cast(cookie), true, buffer, sizeof(buffer)); + printf("%s %s for %s", commentPrefix, flag == GTF_ICON_STATIC_HDL ? "data" : "box", fieldName); return; } } @@ -4154,7 +4111,7 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag } else if (flag == GTF_ICON_FIELD_HDL) { - str = emitComp->eeGetFieldName(reinterpret_cast(handle)); + str = emitComp->eeGetFieldName(reinterpret_cast(handle), true, buffer, sizeof(buffer)); } else if (flag == GTF_ICON_STATIC_HDL) { @@ -4162,7 +4119,8 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag } else if (flag == GTF_ICON_METHOD_HDL) { - str = emitComp->eeGetMethodFullName(reinterpret_cast(handle)); + str = emitComp->eeGetMethodFullName(reinterpret_cast(handle), true, true, buffer, + sizeof(buffer)); } else if (flag == GTF_ICON_FTN_ADDR) { diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index dc4278a82e71e..0d915876dcd0a 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1729,9 +1729,6 @@ class emitter const char* emitRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); const char* emitFloatRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); - const char* emitFldName(CORINFO_FIELD_HANDLE fieldVal); - const char* emitFncName(CORINFO_METHOD_HANDLE callVal); - // GC Info changes are not readily available at each instruction. // We use debug-only sets to track the per-instruction state, and to remember // what the state was at the last time it was output (instruction or label). diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 5dacf783fa5df..b1b3c9db17ddc 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -9516,7 +9516,8 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel #ifdef DEBUG if (emitComp->opts.varNames && offs < 0) { - printf("'%s", emitComp->eeGetFieldName(fldHnd)); + char buffer[128]; + printf("'%s", emitComp->eeGetFieldName(fldHnd, true, buffer, sizeof(buffer))); if (offs) { printf("%+Id", offs); diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index 9922e2cec437c..762f0c66c97e6 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -240,13 +240,6 @@ class SubstitutePlaceholdersAndDevirtualizeWalker : public GenTreeVisitor", layout->GetShortClassName()); + printf("<%s>", layout->GetShortClassName()); } else { - printf("<%S, %u>", layout->GetShortClassName(), layout->GetSize()); + printf("<%s, %u>", layout->GetShortClassName(), layout->GetSize()); } } @@ -11501,8 +11501,8 @@ void Compiler::gtDispFieldSeq(FieldSeq* fieldSeq, ssize_t offset) return; } - printf(" Fseq["); - printf("%s", eeGetFieldName(fieldSeq->GetFieldHandle())); + char buffer[128]; + printf(" Fseq[%s", eeGetFieldName(fieldSeq->GetFieldHandle(), false, buffer, sizeof(buffer))); if (offset != 0) { printf(", %zd", offset); @@ -11532,6 +11532,7 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack) } bool isLclFld = false; + char buffer[256]; switch (tree->gtOper) { @@ -11595,7 +11596,7 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack) CORINFO_CLASS_HANDLE typeHnd = varDsc->GetStructHnd(); CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(typeHnd, fieldVarDsc->lvFldOrdinal); - fieldName = eeGetFieldName(fldHnd); + fieldName = eeGetFieldName(fldHnd, true, buffer, sizeof(buffer)); } printf("\n"); @@ -11632,11 +11633,8 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack) case GT_JMP: { - const char* methodName; - const char* className; - - methodName = eeGetMethodName((CORINFO_METHOD_HANDLE)tree->AsVal()->gtVal1, &className); - printf(" %s.%s\n", className, methodName); + printf(" %s", eeGetMethodFullName((CORINFO_METHOD_HANDLE)tree->AsVal()->gtVal1, true, true, buffer, + sizeof(buffer))); } break; @@ -11649,11 +11647,8 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack) case GT_FTN_ADDR: { - const char* methodName; - const char* className; - - methodName = eeGetMethodName((CORINFO_METHOD_HANDLE)tree->AsFptrVal()->gtFptrMethod, &className); - printf(" %s.%s\n", className, methodName); + printf(" %s\n", eeGetMethodFullName((CORINFO_METHOD_HANDLE)tree->AsFptrVal()->gtFptrMethod, true, true, + buffer, sizeof(buffer))); } break; @@ -11942,7 +11937,11 @@ void Compiler::gtDispTree(GenTree* tree, if (tree->OperIs(GT_FIELD, GT_FIELD_ADDR)) { - printf(" %s", eeGetFieldName(tree->AsField()->gtFldHnd), 0); + auto disp = [&]() { + char buffer[256]; + printf(" %s", eeGetFieldName(tree->AsField()->gtFldHnd, true, buffer, sizeof(buffer))); + }; + disp(); } if (tree->gtOper == GT_INTRINSIC) @@ -12147,12 +12146,11 @@ void Compiler::gtDispTree(GenTree* tree, if (call->gtCallType != CT_INDIRECT) { - const char* methodName; - const char* className; - - methodName = eeGetMethodName(call->gtCallMethHnd, &className); - - printf(" %s.%s", className, methodName); + auto disp = [&]() { + char buffer[256]; + printf(" %s", eeGetMethodFullName(call->gtCallMethHnd, true, true, buffer, sizeof(buffer))); + }; + disp(); } if ((call->gtFlags & GTF_CALL_UNMANAGED) && (call->gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH)) @@ -18303,12 +18301,12 @@ CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldH if (queryForCurrentClass) { - #if DEBUG - const char* fieldClassName = nullptr; - const char* fieldName = eeGetFieldName(fieldHnd, &fieldClassName); - JITDUMP("Querying runtime about current class of field %s.%s (declared as %s)\n", fieldClassName, fieldName, - eeGetClassName(fieldClass)); + char fieldNameBuffer[128]; + char classNameBuffer[128]; + JITDUMP("Querying runtime about current class of field %s (declared as %s)\n", + eeGetFieldName(fieldHnd, true, fieldNameBuffer, sizeof(fieldNameBuffer)), + eeGetClassName(fieldClass, classNameBuffer, sizeof(classNameBuffer))); #endif // DEBUG // Is this a fully initialized init-only static field? @@ -18322,8 +18320,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldH fieldClass = currentClass; *pIsExact = true; *pIsNonNull = true; +#ifdef DEBUG + char buffer[128]; JITDUMP("Runtime reports field is init-only and initialized and has class %s\n", - eeGetClassName(fieldClass)); + eeGetClassName(fieldClass, buffer, sizeof(buffer))); +#endif } else { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 19e2c842393b5..6185804f898ff 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3622,8 +3622,6 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken, info.compCompHnd->getFieldInClass(nullableCls, 0); assert(info.compCompHnd->getFieldOffset(hasValueFldHnd) == 0); - assert(!strcmp(info.compCompHnd->getFieldName(hasValueFldHnd, nullptr), - "hasValue")); GenTree* objToBox = impPopStack().val; diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index b2cbc6965f578..eb2408c604ff0 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -209,12 +209,13 @@ var_types Compiler::impImportCall(OPCODE opcode, // This recognition should really be done by knowing the methHnd of the relevant Mark method(s). // These should be in corelib.h, and available through a JIT/EE interface call. - const char* modName; + const char* namespaceName; const char* className; - const char* methodName; - if ((className = eeGetClassName(clsHnd)) != nullptr && - strcmp(className, "System.Runtime.CompilerServices.JitTestLabel") == 0 && - (methodName = eeGetMethodName(methHnd, &modName)) != nullptr && strcmp(methodName, "Mark") == 0) + const char* methodName = + info.compCompHnd->getMethodNameFromMetadata(methHnd, &className, &namespaceName, nullptr); + if ((namespaceName != nullptr) && (className != nullptr) && (methodName != nullptr) && + (strcmp(namespaceName, "System.Runtime.CompilerServices") == 0) && + (strcmp(className, "JitTestLabel") == 0) && (strcmp(methodName, "Mark") == 0)) { return impImportJitTestLabelMark(sig->numArgs); } @@ -5018,9 +5019,12 @@ void Compiler::considerGuardedDevirtualization(GenTreeCall* call, } } +#ifdef DEBUG + char buffer[256]; JITDUMP("%s call would invoke method %s\n", isInterface ? "interface" : call->IsDelegateInvoke() ? "delegate" : "virtual", - eeGetMethodName(likelyMethod, nullptr)); + eeGetMethodFullName(likelyMethod, true, true, buffer, sizeof(buffer))); +#endif // Add this as a potential candidate. // @@ -5777,7 +5781,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, objClassNote = isExact ? " [exact]" : objClassIsFinal ? " [final]" : ""; objClassName = eeGetClassName(objClass); baseClassName = eeGetClassName(baseClass); - baseMethodName = eeGetMethodName(baseMethod, nullptr); + baseMethodName = eeGetMethodName(baseMethod); if (verbose) { @@ -5883,7 +5887,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, if (verbose || doPrint) { - derivedMethodName = eeGetMethodName(derivedMethod, nullptr); + derivedMethodName = eeGetMethodName(derivedMethod); derivedClassName = eeGetClassName(derivedClass); if (verbose) { diff --git a/src/coreclr/jit/jitconfig.cpp b/src/coreclr/jit/jitconfig.cpp index 7e055f0726bb9..3c85031cee6cd 100644 --- a/src/coreclr/jit/jitconfig.cpp +++ b/src/coreclr/jit/jitconfig.cpp @@ -166,7 +166,6 @@ bool JitConfigValues::MethodSet::contains(CORINFO_METHOD_HANDLE methodHnd, bool success = comp->eeRunFunctorWithSPMIErrorTrap([&]() { comp->eePrintMethod(&printer, name->m_containsClassName ? classHnd : NO_CLASS_HANDLE, methodHnd, sigInfo, - /* includeNamespaces */ true, /* includeClassInstantiation */ name->m_classNameContainsInstantiation, /* includeMethodInstantiation */ name->m_methodNameContainsInstantiation, /* includeSignature */ name->m_containsSignature, diff --git a/src/coreclr/jit/layout.cpp b/src/coreclr/jit/layout.cpp index be1fe4ec4f583..26c77f9dfbcff 100644 --- a/src/coreclr/jit/layout.cpp +++ b/src/coreclr/jit/layout.cpp @@ -337,7 +337,7 @@ ClassLayout* ClassLayout::Create(Compiler* compiler, CORINFO_CLASS_HANDLE classH var_types type = compiler->impNormStructType(classHandle); INDEBUG(const char* className = compiler->eeGetClassName(classHandle);) - INDEBUG(const char16_t* shortClassName = compiler->eeGetShortClassName(classHandle);) + INDEBUG(const char* shortClassName = compiler->eeGetShortClassName(classHandle);) ClassLayout* layout = new (compiler, CMK_ClassLayout) ClassLayout(classHandle, isValueClass, size, type DEBUGARG(className) DEBUGARG(shortClassName)); diff --git a/src/coreclr/jit/layout.h b/src/coreclr/jit/layout.h index 01040f8eede39..b444a9aa63b41 100644 --- a/src/coreclr/jit/layout.h +++ b/src/coreclr/jit/layout.h @@ -42,7 +42,7 @@ class ClassLayout INDEBUG(const char* m_className;) // Shortened class name as constructed by Compiler::eeGetShortClassName() - INDEBUG(const char16_t* m_shortClassName;) + INDEBUG(const char* m_shortClassName;) // ClassLayout instances should only be obtained via ClassLayoutTable. friend class ClassLayoutTable; @@ -59,7 +59,7 @@ class ClassLayout , m_type(TYP_STRUCT) #ifdef DEBUG , m_className("block") - , m_shortClassName(u"block") + , m_shortClassName("block") #endif { } @@ -69,7 +69,7 @@ class ClassLayout ClassLayout(CORINFO_CLASS_HANDLE classHandle, bool isValueClass, unsigned size, - var_types type DEBUGARG(const char* className) DEBUGARG(const char16_t* shortClassName)) + var_types type DEBUGARG(const char* className) DEBUGARG(const char* shortClassName)) : m_classHandle(classHandle) , m_size(size) , m_isValueClass(isValueClass) @@ -107,7 +107,7 @@ class ClassLayout return m_className; } - const char16_t* GetShortClassName() const + const char* GetShortClassName() const { return m_shortClassName; } diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 3a28914e956b6..3f0809e782ebb 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -2415,9 +2415,11 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum) // Now grab the temp for the field local. #ifdef DEBUG + char fieldNameBuffer[128]; + const char* fieldName = + compiler->eeGetFieldName(pFieldInfo->fldHnd, false, fieldNameBuffer, sizeof(fieldNameBuffer)); char buf[200]; - sprintf_s(buf, sizeof(buf), "%s V%02u.%s (fldOffset=0x%x)", "field", lclNum, - compiler->eeGetFieldName(pFieldInfo->fldHnd), pFieldInfo->fldOffset); + sprintf_s(buf, sizeof(buf), "field V%02u.%s (fldOffset=0x%x)", lclNum, fieldName, pFieldInfo->fldOffset); // We need to copy 'buf' as lvaGrabTemp() below caches a copy to its argument. size_t len = strlen(buf) + 1; @@ -7830,7 +7832,9 @@ void Compiler::lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t r CORINFO_CLASS_HANDLE typeHnd = parentvarDsc->GetStructHnd(); CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(typeHnd, varDsc->lvFldOrdinal); - printf(" V%02u.%s(offs=0x%02x)", varDsc->lvParentLcl, eeGetFieldName(fldHnd), varDsc->lvFldOffset); + char buffer[128]; + printf(" V%02u.%s(offs=0x%02x)", varDsc->lvParentLcl, eeGetFieldName(fldHnd, false, buffer, sizeof(buffer)), + varDsc->lvFldOffset); lvaPromotionType promotionType = lvaGetPromotionType(parentvarDsc); switch (promotionType) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 2ea9f1225e341..1bfa32023bb77 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -5458,7 +5458,7 @@ GenTree* Compiler::fgMorphExpandStaticField(GenTree* tree) } else if (isStaticReadOnlyInited) { - JITDUMP("Marking initialized static read-only field '%s' as invariant.\n", eeGetFieldName(fieldHandle)); + JITDUMP("Marking initialized static read-only field '%s' as invariant.\n", eeGetFieldName(fieldHandle, false)); // Static readonly field is not null at this point (see getStaticFieldCurrentClass impl). tree->gtFlags |= (GTF_IND_INVARIANT | GTF_IND_NONFAULTING | GTF_IND_NONNULL); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index e80b667da6e6d..f6362b04bcac8 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2974,9 +2974,11 @@ ValueNum ValueNumStore::VNForFieldSelector(CORINFO_FIELD_HANDLE fieldHnd, var_ty #ifdef DEBUG if (m_pComp->verbose) { - const char* modName; - const char* fldName = m_pComp->eeGetFieldName(fieldHnd, &modName); + char buffer[128]; + const char* fldName = m_pComp->eeGetFieldName(fieldHnd, false, buffer, sizeof(buffer)); + printf(" VNForHandle(%s) is " FMT_VN ", fieldType is %s", fldName, fldHndVN, varTypeName(fieldType)); + if (size != 0) { printf(", size = %u", size); @@ -8041,8 +8043,8 @@ ValueNum Compiler::fgMemoryVNForLoopSideEffects(MemoryKind memoryKind, #ifdef DEBUG if (verbose) { - const char* modName; - const char* fldName = eeGetFieldName(fldHnd, &modName); + char buffer[128]; + const char* fldName = eeGetFieldName(fldHnd, false, buffer, sizeof(buffer)); printf(" VNForHandle(%s) is " FMT_VN "\n", fldName, fldHndVN); } #endif // DEBUG diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 7b1ce731f2563..90e65c1cd0728 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -1863,22 +1864,36 @@ private int getStringLiteral(CORINFO_MODULE_STRUCT_* module, uint metaTOK, char* private nuint printObjectDescription(CORINFO_OBJECT_STRUCT_* handle, byte* buffer, nuint bufferSize, nuint* pRequiredBufferSize) { - Debug.Assert(bufferSize > 0 && handle != null && buffer != null); + Debug.Assert(handle != null); - int bufferSize32 = checked((int)bufferSize); - ReadOnlySpan objStr = HandleToObject(handle).ToString(); + return PrintFromUtf16(HandleToObject(handle).ToString(), buffer, bufferSize, pRequiredBufferSize); + } + private nuint PrintFromUtf16(ReadOnlySpan utf16, byte* buffer, nuint bufferSize, nuint* pRequiredBufferSize) + { int written = 0; if (bufferSize > 0) { - Utf8.FromUtf16(objStr, new Span(buffer, checked((int)(bufferSize - 1))), out _, out written); + OperationStatus status = Utf8.FromUtf16(utf16, new Span(buffer, checked((int)(bufferSize - 1))), out _, out written); // Always null-terminate buffer[written] = 0; + + if (status == OperationStatus.Done) + { + if (pRequiredBufferSize != null) + { + *pRequiredBufferSize = (nuint)written + 1; + } + + return (nuint)written; + } } + if (pRequiredBufferSize != null) { - *pRequiredBufferSize = (nuint)Encoding.UTF8.GetByteCount(objStr) + 1; + *pRequiredBufferSize = (nuint)Encoding.UTF8.GetByteCount(utf16) + 1; } + return (nuint)written; } @@ -1888,14 +1903,6 @@ private CorInfoType asCorInfoType(CORINFO_CLASS_STRUCT_* cls) return asCorInfoType(type); } - private byte* getClassName(CORINFO_CLASS_STRUCT_* cls) - { - var type = HandleToObject(cls); - StringBuilder nameBuilder = new StringBuilder(); - TypeString.Instance.AppendName(nameBuilder, type); - return (byte*)GetPin(StringToUTF8(nameBuilder.ToString())); - } - private byte* getClassNameFromMetadata(CORINFO_CLASS_STRUCT_* cls, byte** namespaceName) { var type = HandleToObject(cls) as MetadataType; @@ -1920,37 +1927,11 @@ private CorInfoType asCorInfoType(CORINFO_CLASS_STRUCT_* cls) } - private int appendClassName(char** ppBuf, ref int pnBufLen, CORINFO_CLASS_STRUCT_* cls, bool fNamespace, bool fFullInst, bool fAssembly) + private nuint printClassName(CORINFO_CLASS_STRUCT_* cls, byte* buffer, nuint bufferSize, nuint* pRequiredBufferSize) { - // We support enough of this to make SIMD work, but not much else. - - Debug.Assert(fNamespace && !fFullInst && !fAssembly); - - var type = HandleToObject(cls); - string name = TypeString.Instance.FormatName(type); - - int length = name.Length; - if (pnBufLen > 0) - { - char* buffer = *ppBuf; - int lengthToCopy = Math.Min(name.Length, pnBufLen); - for (int i = 0; i < lengthToCopy; i++) - buffer[i] = name[i]; - if (name.Length < pnBufLen) - { - buffer[name.Length] = (char)0; - } - else - { - buffer[pnBufLen - 1] = (char)0; - lengthToCopy -= 1; - } - - pnBufLen -= lengthToCopy; - *ppBuf = buffer + lengthToCopy; - } - - return length; + TypeDesc type = HandleToObject(cls); + string name = JitTypeNameFormatter.Instance.FormatName(type); + return PrintFromUtf16(name, buffer, bufferSize, pRequiredBufferSize); } private bool isValueClass(CORINFO_CLASS_STRUCT_* cls) @@ -2379,11 +2360,6 @@ private CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_STRUCT_* cls) return type.IsNullable ? CorInfoHelpFunc.CORINFO_HELP_UNBOX_NULLABLE : CorInfoHelpFunc.CORINFO_HELP_UNBOX; } - private byte* getHelperName(CorInfoHelpFunc helpFunc) - { - return (byte*)GetPin(StringToUTF8(helpFunc.ToString())); - } - private CorInfoInitClassResult initClass(CORINFO_FIELD_STRUCT_* field, CORINFO_METHOD_STRUCT_* method, CORINFO_CONTEXT_STRUCT* context) { FieldDesc fd = field == null ? null : HandleToObject(field); @@ -2862,19 +2838,10 @@ private CorInfoIsAccessAllowedResult canAccessClass(ref CORINFO_RESOLVED_TOKEN p return CorInfoIsAccessAllowedResult.CORINFO_ACCESS_ALLOWED; } - private byte* getFieldName(CORINFO_FIELD_STRUCT_* ftn, byte** moduleName) + private nuint printFieldName(CORINFO_FIELD_STRUCT_* fld, byte* buffer, nuint bufferSize, nuint* requiredBufferSize) { - var field = HandleToObject(ftn); - if (moduleName != null) - { - MetadataType typeDef = field.OwningType.GetTypeDefinition() as MetadataType; - if (typeDef != null) - *moduleName = (byte*)GetPin(StringToUTF8(typeDef.GetFullName())); - else - *moduleName = (byte*)GetPin(StringToUTF8("unknown")); - } - - return (byte*)GetPin(StringToUTF8(field.Name)); + FieldDesc field = HandleToObject(fld); + return PrintFromUtf16(field.Name, buffer, bufferSize, requiredBufferSize); } private CORINFO_CLASS_STRUCT_* getFieldClass(CORINFO_FIELD_STRUCT_* field) @@ -3158,20 +3125,10 @@ private static byte[] StringToUTF8(string s) return bytes; } - private byte* getMethodName(CORINFO_METHOD_STRUCT_* ftn, byte** moduleName) + private nuint printMethodName(CORINFO_METHOD_STRUCT_* ftn, byte* buffer, nuint bufferSize, nuint* requiredBufferSize) { MethodDesc method = HandleToObject(ftn); - - if (moduleName != null) - { - MetadataType typeDef = method.OwningType.GetTypeDefinition() as MetadataType; - if (typeDef != null) - *moduleName = (byte*)GetPin(StringToUTF8(typeDef.GetFullName())); - else - *moduleName = (byte*)GetPin(StringToUTF8("unknown")); - } - - return (byte*)GetPin(StringToUTF8(method.Name)); + return PrintFromUtf16(method.Name, buffer, bufferSize, requiredBufferSize); } private static string getMethodNameFromMetadataImpl(MethodDesc method, out string className, out string namespaceName, out string enclosingClassName) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 40218af44e79a..65c17d7017293 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -583,21 +583,6 @@ private static CorInfoType _asCorInfoType(IntPtr thisHandle, IntPtr* ppException } } - [UnmanagedCallersOnly] - private static byte* _getClassName(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassName(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static byte* _getClassNameFromMetadata(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, byte** namespaceName) { @@ -629,12 +614,12 @@ private static CorInfoType _asCorInfoType(IntPtr thisHandle, IntPtr* ppException } [UnmanagedCallersOnly] - private static int _appendClassName(IntPtr thisHandle, IntPtr* ppException, char** ppBuf, int* pnBufLen, CORINFO_CLASS_STRUCT_* cls, byte fNamespace, byte fFullInst, byte fAssembly) + private static UIntPtr _printClassName(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) { var _this = GetThis(thisHandle); try { - return _this.appendClassName(ppBuf, ref *pnBufLen, cls, fNamespace != 0, fFullInst != 0, fAssembly != 0); + return _this.printClassName(cls, buffer, bufferSize, pRequiredBufferSize); } catch (Exception ex) { @@ -1076,21 +1061,6 @@ private static void _getReadyToRunDelegateCtorHelper(IntPtr thisHandle, IntPtr* } } - [UnmanagedCallersOnly] - private static byte* _getHelperName(IntPtr thisHandle, IntPtr* ppException, CorInfoHelpFunc helpFunc) - { - var _this = GetThis(thisHandle); - try - { - return _this.getHelperName(helpFunc); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static CorInfoInitClassResult _initClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, CORINFO_METHOD_STRUCT_* method, CORINFO_CONTEXT_STRUCT* context) { @@ -1391,12 +1361,12 @@ private static CorInfoIsAccessAllowedResult _canAccessClass(IntPtr thisHandle, I } [UnmanagedCallersOnly] - private static byte* _getFieldName(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* ftn, byte** moduleName) + private static UIntPtr _printFieldName(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) { var _this = GetThis(thisHandle); try { - return _this.getFieldName(ftn, moduleName); + return _this.printFieldName(field, buffer, bufferSize, pRequiredBufferSize); } catch (Exception ex) { @@ -1816,12 +1786,12 @@ private static mdToken _getMethodDefFromMethod(IntPtr thisHandle, IntPtr* ppExce } [UnmanagedCallersOnly] - private static byte* _getMethodName(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, byte** moduleName) + private static UIntPtr _printMethodName(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) { var _this = GetThis(thisHandle); try { - return _this.getMethodName(ftn, moduleName); + return _this.printMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); } catch (Exception ex) { @@ -2700,7 +2670,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 182); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 180); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2741,149 +2711,147 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[36] = (delegate* unmanaged)&_getStringLiteral; callbacks[37] = (delegate* unmanaged)&_printObjectDescription; callbacks[38] = (delegate* unmanaged)&_asCorInfoType; - callbacks[39] = (delegate* unmanaged)&_getClassName; - callbacks[40] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[41] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[42] = (delegate* unmanaged)&_appendClassName; - callbacks[43] = (delegate* unmanaged)&_isValueClass; - callbacks[44] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[45] = (delegate* unmanaged)&_getClassAttribs; - callbacks[46] = (delegate* unmanaged)&_getClassModule; - callbacks[47] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[48] = (delegate* unmanaged)&_getAssemblyName; - callbacks[49] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[50] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[51] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[52] = (delegate* unmanaged)&_getClassSize; - callbacks[53] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[54] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[55] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[56] = (delegate* unmanaged)&_getClassGClayout; - callbacks[57] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[58] = (delegate* unmanaged)&_getFieldInClass; - callbacks[59] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[60] = (delegate* unmanaged)&_getNewHelper; - callbacks[61] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[62] = (delegate* unmanaged)&_getCastingHelper; - callbacks[63] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[64] = (delegate* unmanaged)&_getTypeForBox; - callbacks[65] = (delegate* unmanaged)&_getBoxHelper; - callbacks[66] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[67] = (delegate* unmanaged)&_getRuntimeTypePointer; - callbacks[68] = (delegate* unmanaged)&_isObjectImmutable; - callbacks[69] = (delegate* unmanaged)&_getObjectType; - callbacks[70] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[71] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[72] = (delegate* unmanaged)&_getHelperName; - callbacks[73] = (delegate* unmanaged)&_initClass; - callbacks[74] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[75] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[76] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[77] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[78] = (delegate* unmanaged)&_canCast; - callbacks[79] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[80] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[82] = (delegate* unmanaged)&_mergeClasses; - callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[84] = (delegate* unmanaged)&_isEnum; - callbacks[85] = (delegate* unmanaged)&_getParentType; - callbacks[86] = (delegate* unmanaged)&_getChildType; - callbacks[87] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[88] = (delegate* unmanaged)&_isSDArray; - callbacks[89] = (delegate* unmanaged)&_getArrayRank; - callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[92] = (delegate* unmanaged)&_canAccessClass; - callbacks[93] = (delegate* unmanaged)&_getFieldName; - callbacks[94] = (delegate* unmanaged)&_getFieldClass; - callbacks[95] = (delegate* unmanaged)&_getFieldType; - callbacks[96] = (delegate* unmanaged)&_getFieldOffset; - callbacks[97] = (delegate* unmanaged)&_getFieldInfo; - callbacks[98] = (delegate* unmanaged)&_isFieldStatic; - callbacks[99] = (delegate* unmanaged)&_getArrayOrStringLength; - callbacks[100] = (delegate* unmanaged)&_getBoundaries; - callbacks[101] = (delegate* unmanaged)&_setBoundaries; - callbacks[102] = (delegate* unmanaged)&_getVars; - callbacks[103] = (delegate* unmanaged)&_setVars; - callbacks[104] = (delegate* unmanaged)&_reportRichMappings; - callbacks[105] = (delegate* unmanaged)&_allocateArray; - callbacks[106] = (delegate* unmanaged)&_freeArray; - callbacks[107] = (delegate* unmanaged)&_getArgNext; - callbacks[108] = (delegate* unmanaged)&_getArgType; - callbacks[109] = (delegate* unmanaged)&_getExactClasses; - callbacks[110] = (delegate* unmanaged)&_getArgClass; - callbacks[111] = (delegate* unmanaged)&_getHFAType; - callbacks[112] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[113] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[114] = (delegate* unmanaged)&_FilterException; - callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[116] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[117] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[118] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[119] = (delegate* unmanaged)&_getEEInfo; - callbacks[120] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[121] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[122] = (delegate* unmanaged)&_getMethodName; - callbacks[123] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[124] = (delegate* unmanaged)&_getMethodHash; - callbacks[125] = (delegate* unmanaged)&_findNameOfToken; - callbacks[126] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[127] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[128] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[129] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[130] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[131] = (delegate* unmanaged)&_getHelperFtn; - callbacks[132] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[133] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[134] = (delegate* unmanaged)&_getMethodSync; - callbacks[135] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[136] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[137] = (delegate* unmanaged)&_embedClassHandle; - callbacks[138] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[139] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[140] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[141] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[142] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[143] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[144] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[145] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[146] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[147] = (delegate* unmanaged)&_getCallInfo; - callbacks[148] = (delegate* unmanaged)&_canAccessFamily; - callbacks[149] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[150] = (delegate* unmanaged)&_getClassDomainID; - callbacks[151] = (delegate* unmanaged)&_getFieldAddress; - callbacks[152] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; - callbacks[153] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[154] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[155] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[156] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[157] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[158] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[159] = (delegate* unmanaged)&_addActiveDependency; - callbacks[160] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[161] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[162] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[163] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[164] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[165] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[166] = (delegate* unmanaged)&_allocMem; - callbacks[167] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[168] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[169] = (delegate* unmanaged)&_allocGCInfo; - callbacks[170] = (delegate* unmanaged)&_setEHcount; - callbacks[171] = (delegate* unmanaged)&_setEHinfo; - callbacks[172] = (delegate* unmanaged)&_logMsg; - callbacks[173] = (delegate* unmanaged)&_doAssert; - callbacks[174] = (delegate* unmanaged)&_reportFatalError; - callbacks[175] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[176] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[177] = (delegate* unmanaged)&_recordCallSite; - callbacks[178] = (delegate* unmanaged)&_recordRelocation; - callbacks[179] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[180] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[181] = (delegate* unmanaged)&_getJitFlags; + callbacks[39] = (delegate* unmanaged)&_getClassNameFromMetadata; + callbacks[40] = (delegate* unmanaged)&_getTypeInstantiationArgument; + callbacks[41] = (delegate* unmanaged)&_printClassName; + callbacks[42] = (delegate* unmanaged)&_isValueClass; + callbacks[43] = (delegate* unmanaged)&_canInlineTypeCheck; + callbacks[44] = (delegate* unmanaged)&_getClassAttribs; + callbacks[45] = (delegate* unmanaged)&_getClassModule; + callbacks[46] = (delegate* unmanaged)&_getModuleAssembly; + callbacks[47] = (delegate* unmanaged)&_getAssemblyName; + callbacks[48] = (delegate* unmanaged)&_LongLifetimeMalloc; + callbacks[49] = (delegate* unmanaged)&_LongLifetimeFree; + callbacks[50] = (delegate* unmanaged)&_getClassModuleIdForStatics; + callbacks[51] = (delegate* unmanaged)&_getClassSize; + callbacks[52] = (delegate* unmanaged)&_getHeapClassSize; + callbacks[53] = (delegate* unmanaged)&_canAllocateOnStack; + callbacks[54] = (delegate* unmanaged)&_getClassAlignmentRequirement; + callbacks[55] = (delegate* unmanaged)&_getClassGClayout; + callbacks[56] = (delegate* unmanaged)&_getClassNumInstanceFields; + callbacks[57] = (delegate* unmanaged)&_getFieldInClass; + callbacks[58] = (delegate* unmanaged)&_checkMethodModifier; + callbacks[59] = (delegate* unmanaged)&_getNewHelper; + callbacks[60] = (delegate* unmanaged)&_getNewArrHelper; + callbacks[61] = (delegate* unmanaged)&_getCastingHelper; + callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper; + callbacks[63] = (delegate* unmanaged)&_getTypeForBox; + callbacks[64] = (delegate* unmanaged)&_getBoxHelper; + callbacks[65] = (delegate* unmanaged)&_getUnBoxHelper; + callbacks[66] = (delegate* unmanaged)&_getRuntimeTypePointer; + callbacks[67] = (delegate* unmanaged)&_isObjectImmutable; + callbacks[68] = (delegate* unmanaged)&_getObjectType; + callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[71] = (delegate* unmanaged)&_initClass; + callbacks[72] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; + callbacks[73] = (delegate* unmanaged)&_getBuiltinClass; + callbacks[74] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; + callbacks[75] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; + callbacks[76] = (delegate* unmanaged)&_canCast; + callbacks[77] = (delegate* unmanaged)&_areTypesEquivalent; + callbacks[78] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[79] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[80] = (delegate* unmanaged)&_mergeClasses; + callbacks[81] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[82] = (delegate* unmanaged)&_isEnum; + callbacks[83] = (delegate* unmanaged)&_getParentType; + callbacks[84] = (delegate* unmanaged)&_getChildType; + callbacks[85] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[86] = (delegate* unmanaged)&_isSDArray; + callbacks[87] = (delegate* unmanaged)&_getArrayRank; + callbacks[88] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[89] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[90] = (delegate* unmanaged)&_canAccessClass; + callbacks[91] = (delegate* unmanaged)&_printFieldName; + callbacks[92] = (delegate* unmanaged)&_getFieldClass; + callbacks[93] = (delegate* unmanaged)&_getFieldType; + callbacks[94] = (delegate* unmanaged)&_getFieldOffset; + callbacks[95] = (delegate* unmanaged)&_getFieldInfo; + callbacks[96] = (delegate* unmanaged)&_isFieldStatic; + callbacks[97] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[98] = (delegate* unmanaged)&_getBoundaries; + callbacks[99] = (delegate* unmanaged)&_setBoundaries; + callbacks[100] = (delegate* unmanaged)&_getVars; + callbacks[101] = (delegate* unmanaged)&_setVars; + callbacks[102] = (delegate* unmanaged)&_reportRichMappings; + callbacks[103] = (delegate* unmanaged)&_allocateArray; + callbacks[104] = (delegate* unmanaged)&_freeArray; + callbacks[105] = (delegate* unmanaged)&_getArgNext; + callbacks[106] = (delegate* unmanaged)&_getArgType; + callbacks[107] = (delegate* unmanaged)&_getExactClasses; + callbacks[108] = (delegate* unmanaged)&_getArgClass; + callbacks[109] = (delegate* unmanaged)&_getHFAType; + callbacks[110] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[111] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[112] = (delegate* unmanaged)&_FilterException; + callbacks[113] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[115] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[116] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[117] = (delegate* unmanaged)&_getEEInfo; + callbacks[118] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[119] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[120] = (delegate* unmanaged)&_printMethodName; + callbacks[121] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[122] = (delegate* unmanaged)&_getMethodHash; + callbacks[123] = (delegate* unmanaged)&_findNameOfToken; + callbacks[124] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[125] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[126] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[127] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[128] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[129] = (delegate* unmanaged)&_getHelperFtn; + callbacks[130] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[131] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[132] = (delegate* unmanaged)&_getMethodSync; + callbacks[133] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[134] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[135] = (delegate* unmanaged)&_embedClassHandle; + callbacks[136] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[137] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[138] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[139] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[140] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[141] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[142] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[143] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[144] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[145] = (delegate* unmanaged)&_getCallInfo; + callbacks[146] = (delegate* unmanaged)&_canAccessFamily; + callbacks[147] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[148] = (delegate* unmanaged)&_getClassDomainID; + callbacks[149] = (delegate* unmanaged)&_getFieldAddress; + callbacks[150] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[151] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[152] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[153] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[154] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[155] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[156] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[157] = (delegate* unmanaged)&_addActiveDependency; + callbacks[158] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[159] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[160] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[161] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[162] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[163] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[164] = (delegate* unmanaged)&_allocMem; + callbacks[165] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[166] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[167] = (delegate* unmanaged)&_allocGCInfo; + callbacks[168] = (delegate* unmanaged)&_setEHcount; + callbacks[169] = (delegate* unmanaged)&_setEHinfo; + callbacks[170] = (delegate* unmanaged)&_logMsg; + callbacks[171] = (delegate* unmanaged)&_doAssert; + callbacks[172] = (delegate* unmanaged)&_reportFatalError; + callbacks[173] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[174] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[175] = (delegate* unmanaged)&_recordCallSite; + callbacks[176] = (delegate* unmanaged)&_recordRelocation; + callbacks[177] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[178] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[179] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/JitTypeNameFormatter.cs b/src/coreclr/tools/Common/JitInterface/JitTypeNameFormatter.cs new file mode 100644 index 0000000000000..aa4a01615953b --- /dev/null +++ b/src/coreclr/tools/Common/JitInterface/JitTypeNameFormatter.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Text; + +using Internal.TypeSystem; + +namespace Internal.JitInterface +{ + // This is a very rough equivalent of typestring.cpp in the CLR used with + // FormatNamespace|FormatNoInst, with some adjustments related to generic + // instantiations. This is currently only used for printClassName in the + // JIT-EE interface that is used for the various method set JIT variables + // (JitDisasm for example). + internal sealed class JitTypeNameFormatter : TypeNameFormatter + { + public static JitTypeNameFormatter Instance { get; } = new JitTypeNameFormatter(); + + public override void AppendName(StringBuilder sb, PointerType type) + { + AppendName(sb, type.ParameterType); + sb.Append('*'); + } + + public override void AppendName(StringBuilder sb, GenericParameterDesc type) + { + Debug.Fail("Unexpected generic parameter type in JitTypeNameFormatter"); + } + + public override void AppendName(StringBuilder sb, SignatureTypeVariable type) + { + Debug.Fail("Unexpected signature type variable in JitTypeNameFormatter"); + } + + public override void AppendName(StringBuilder sb, SignatureMethodVariable type) + { + Debug.Fail("Unexpected signature method variable in JitTypeNameFormatter"); + } + + public override void AppendName(StringBuilder sb, FunctionPointerType type) + { + MethodSignature signature = type.Signature; + + AppendName(sb, signature.ReturnType); + + sb.Append(" ("); + for (int i = 0; i < signature.Length; i++) + { + if (i > 0) + sb.Append(", "); + AppendName(sb, signature[i]); + } + + sb.Append(')'); + } + + public override void AppendName(StringBuilder sb, ByRefType type) + { + AppendName(sb, type.ParameterType); + sb.Append('&'); + } + + public override void AppendName(StringBuilder sb, ArrayType type) + { + AppendName(sb, type.ElementType); + sb.Append('['); + sb.Append(',', type.Rank - 1); + sb.Append(']'); + } + + protected override void AppendNameForInstantiatedType(StringBuilder sb, DefType type) + { + AppendName(sb, type.GetTypeDefinition()); + // Type name intentionally excludes instantiations. + } + + protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type) + { + string ns = type.Namespace; + if (ns.Length > 0) + { + sb.Append(ns); + sb.Append('.'); + } + sb.Append(type.Name); + } + + protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) + { + AppendName(sb, containingType); + sb.Append('+'); + sb.Append(nestedType.Name); + } + } +} diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index d33bea88a4c5d..f8ec02914b2eb 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -195,10 +195,9 @@ FUNCTIONS int getStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex) size_t printObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) CorInfoType asCorInfoType(CORINFO_CLASS_HANDLE cls) - const char* getClassName(CORINFO_CLASS_HANDLE cls) const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char **namespaceName) CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index) - int appendClassName(char16_t** ppBuf, int* pnBufLen, CORINFO_CLASS_HANDLE cls, bool fNamespace, bool fFullInst, bool fAssembly) + size_t printClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) bool isValueClass(CORINFO_CLASS_HANDLE cls) CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) uint32_t getClassAttribs(CORINFO_CLASS_HANDLE cls) @@ -228,7 +227,6 @@ FUNCTIONS CORINFO_CLASS_HANDLE getObjectType(CORINFO_OBJECT_HANDLE objPtr) bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP *pLookup) void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN * pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP *pLookup) - const char* getHelperName(CorInfoHelpFunc helpFunc) CorInfoInitClassResult initClass(CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context) void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls) CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId) @@ -249,7 +247,7 @@ FUNCTIONS CorInfoArrayIntrinsic getArrayIntrinsicID(CORINFO_METHOD_HANDLE ftn) void* getArrayInitializationData(CORINFO_FIELD_HANDLE field, uint32_t size) CorInfoIsAccessAllowedResult canAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_HELPER_DESC* pAccessHelper) - const char* getFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName) + size_t printFieldName(CORINFO_FIELD_HANDLE field, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) CORINFO_CLASS_HANDLE getFieldClass(CORINFO_FIELD_HANDLE field) CorInfoType getFieldType(CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType, CORINFO_CLASS_HANDLE memberParent) unsigned getFieldOffset(CORINFO_FIELD_HANDLE field) @@ -278,7 +276,7 @@ FUNCTIONS void getEEInfo(CORINFO_EE_INFO* pEEInfoOut); const char16_t * getJitTimeLogFilename(); mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod); - const char* getMethodName(CORINFO_METHOD_HANDLE ftn, const char **moduleName); + size_t printMethodName(CORINFO_METHOD_HANDLE ftn, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) const char* getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, const char **className, const char **namespaceName, const char **enclosingClassName); unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn); size_t findNameOfToken(CORINFO_MODULE_HANDLE moduleHandle,mdToken token, char * szFQName,size_t FQNameCapacity); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index ea9930f54e39f..0f093992feee5 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -228,6 +228,7 @@ + @@ -265,8 +266,8 @@ IL\HelperExtensions.cs - - JitInterface\TypeString.cs + + JitInterface\JitTypeNameFormatter.cs JitInterface\CorInfoImpl_generated.cs diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs index 21f9169f294a7..4ffd41349451f 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs @@ -182,7 +182,7 @@ public bool FindSymbol(OutputItem item, out int index) public IEnumerable EnumerateMethods() { DebugNameFormatter nameFormatter = new DebugNameFormatter(); - TypeNameFormatter typeNameFormatter = new TypeString(); + TypeNameFormatter typeNameFormatter = TypeString.Instance; foreach (KeyValuePair symbolMethodPair in _methodSymbolMap) { MethodInfo methodInfo = new MethodInfo(); diff --git a/src/coreclr/tools/Common/JitInterface/TypeString.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TypeString.cs similarity index 93% rename from src/coreclr/tools/Common/JitInterface/TypeString.cs rename to src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TypeString.cs index 7bdb02e08107f..a0644eea58b06 100644 --- a/src/coreclr/tools/Common/JitInterface/TypeString.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/TypeString.cs @@ -5,11 +5,11 @@ using Internal.TypeSystem; -namespace Internal.JitInterface +namespace ILCompiler.PEWriter { - // This is a very rough equivalent of typestring.cpp in the CLR. - // There's way more rules to capture. Hopefully, we'll only ever need this in the code to recognize SIMD intrisics - // and we won't need to replicate all the details around escaping and such. + // This is a very rough equivalent of typestring.cpp in the CLR with only + // basic formatting options. Only used to format type names for map + // files/symbol files. internal sealed class TypeString : TypeNameFormatter { public static TypeString Instance { get; } = new TypeString(); diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj b/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj index 1e7820302cc89..9eeeab38d17ab 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj @@ -64,8 +64,8 @@ JitInterface\JitConfigProvider.cs - - JitInterface\TypeString.cs + + JitInterface\JitTypeNameFormatter.cs JitInterface\CorInfoImpl_generated.cs diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 4f2f5944d2d6d..0688b6a9fa282 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -50,10 +50,9 @@ struct JitInterfaceCallbacks int (* getStringLiteral)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex); size_t (* printObjectDescription)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); CorInfoType (* asCorInfoType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); - const char* (* getClassName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); const char* (* getClassNameFromMetadata)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, const char** namespaceName); CORINFO_CLASS_HANDLE (* getTypeInstantiationArgument)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, unsigned index); - int (* appendClassName)(void * thisHandle, CorInfoExceptionClass** ppException, char16_t** ppBuf, int* pnBufLen, CORINFO_CLASS_HANDLE cls, bool fNamespace, bool fFullInst, bool fAssembly); + size_t (* printClassName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); bool (* isValueClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoInlineTypeCheck (* canInlineTypeCheck)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source); uint32_t (* getClassAttribs)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); @@ -83,7 +82,6 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* getObjectType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objPtr); bool (* getReadyToRunHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP* pLookup); void (* getReadyToRunDelegateCtorHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, unsigned int targetConstraint, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup); - const char* (* getHelperName)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoHelpFunc helpFunc); CorInfoInitClassResult (* initClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context); void (* classMustBeLoadedBeforeCodeIsRun)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CORINFO_CLASS_HANDLE (* getBuiltinClass)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoClassId classId); @@ -104,7 +102,7 @@ struct JitInterfaceCallbacks CorInfoArrayIntrinsic (* getArrayIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn); void* (* getArrayInitializationData)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint32_t size); CorInfoIsAccessAllowedResult (* canAccessClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_HELPER_DESC* pAccessHelper); - const char* (* getFieldName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE ftn, const char** moduleName); + size_t (* printFieldName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); CORINFO_CLASS_HANDLE (* getFieldClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field); CorInfoType (* getFieldType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType, CORINFO_CLASS_HANDLE memberParent); unsigned (* getFieldOffset)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field); @@ -133,7 +131,7 @@ struct JitInterfaceCallbacks void (* getEEInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_EE_INFO* pEEInfoOut); const char16_t* (* getJitTimeLogFilename)(void * thisHandle, CorInfoExceptionClass** ppException); mdMethodDef (* getMethodDefFromMethod)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE hMethod); - const char* (* getMethodName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, const char** moduleName); + size_t (* printMethodName)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); const char* (* getMethodNameFromMetadata)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, const char** className, const char** namespaceName, const char** enclosingClassName); unsigned (* getMethodHash)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn); size_t (* findNameOfToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE moduleHandle, unsigned int token, char* szFQName, size_t FQNameCapacity); @@ -592,15 +590,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual const char* getClassName( - CORINFO_CLASS_HANDLE cls) -{ - CorInfoExceptionClass* pException = nullptr; - const char* temp = _callbacks->getClassName(_thisHandle, &pException, cls); - if (pException != nullptr) throw pException; - return temp; -} - virtual const char* getClassNameFromMetadata( CORINFO_CLASS_HANDLE cls, const char** namespaceName) @@ -621,16 +610,14 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual int appendClassName( - char16_t** ppBuf, - int* pnBufLen, + virtual size_t printClassName( CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { CorInfoExceptionClass* pException = nullptr; - int temp = _callbacks->appendClassName(_thisHandle, &pException, ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); + size_t temp = _callbacks->printClassName(_thisHandle, &pException, cls, buffer, bufferSize, pRequiredBufferSize); if (pException != nullptr) throw pException; return temp; } @@ -911,15 +898,6 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; } - virtual const char* getHelperName( - CorInfoHelpFunc helpFunc) -{ - CorInfoExceptionClass* pException = nullptr; - const char* temp = _callbacks->getHelperName(_thisHandle, &pException, helpFunc); - if (pException != nullptr) throw pException; - return temp; -} - virtual CorInfoInitClassResult initClass( CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, @@ -1112,12 +1090,14 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual const char* getFieldName( - CORINFO_FIELD_HANDLE ftn, - const char** moduleName) + virtual size_t printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { CorInfoExceptionClass* pException = nullptr; - const char* temp = _callbacks->getFieldName(_thisHandle, &pException, ftn, moduleName); + size_t temp = _callbacks->printFieldName(_thisHandle, &pException, field, buffer, bufferSize, pRequiredBufferSize); if (pException != nullptr) throw pException; return temp; } @@ -1371,12 +1351,14 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual const char* getMethodName( + virtual size_t printMethodName( CORINFO_METHOD_HANDLE ftn, - const char** moduleName) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { CorInfoExceptionClass* pException = nullptr; - const char* temp = _callbacks->getMethodName(_thisHandle, &pException, ftn, moduleName); + size_t temp = _callbacks->printMethodName(_thisHandle, &pException, ftn, buffer, bufferSize, pRequiredBufferSize); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp b/src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp index 2ff9b3cbe3690..9e4bd15f2f0ce 100644 --- a/src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp @@ -29,9 +29,10 @@ void DumpMap(int index, MethodContext* mc) mc->repCompileMethod(&cmi, &flags, &os); - const char* moduleName = nullptr; - const char* methodName = mc->repGetMethodName(cmi.ftn, &moduleName); - const char* className = mc->repGetClassName(mc->repGetMethodClass(cmi.ftn)); + char methodName[256]; + mc->repPrintMethodName(cmi.ftn, methodName, sizeof(methodName)); + char className[256]; + mc->repPrintClassName(mc->repGetMethodClass(cmi.ftn), className, sizeof(className)); printf("%d,", index); // printf("\"%s\",", mc->cr->repProcessName()); @@ -53,7 +54,7 @@ void DumpMap(int index, MethodContext* mc) for (unsigned i = 0; i < classInst; i++) { CORINFO_CLASS_HANDLE ci = sig.sigInst.classInst[i]; - className = mc->repGetClassName(ci); + mc->repPrintClassName(ci, className, sizeof(className)); printf("%s%s%s%s", i == 0 ? "[" : "", @@ -69,7 +70,7 @@ void DumpMap(int index, MethodContext* mc) for (unsigned i = 0; i < methodInst; i++) { CORINFO_CLASS_HANDLE ci = sig.sigInst.methInst[i]; - className = mc->repGetClassName(ci); + mc->repPrintClassName(ci, className, sizeof(className)); printf("%s%s%s%s", i == 0 ? "[" : "", diff --git a/src/coreclr/tools/superpmi/mcs/verbildump.cpp b/src/coreclr/tools/superpmi/mcs/verbildump.cpp index 506d14e587f99..5bb53c6281faa 100644 --- a/src/coreclr/tools/superpmi/mcs/verbildump.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbildump.cpp @@ -65,11 +65,17 @@ void DumpPrimToConsoleBare(MethodContext* mc, CorInfoType prim, DWORDLONG classH printf("byref"); return; case CORINFO_TYPE_VALUECLASS: - printf("valueclass %s", mc->repGetClassName((CORINFO_CLASS_HANDLE)classHandle)); - return; case CORINFO_TYPE_CLASS: - printf("class %s", mc->repGetClassName((CORINFO_CLASS_HANDLE)classHandle)); + { + char className[256]; + mc->repPrintClassName((CORINFO_CLASS_HANDLE)classHandle, className, sizeof(className)); + + printf( + "%s %s", + prim == CORINFO_TYPE_VALUECLASS ? "valueclass" : "class", + className); return; + } case CORINFO_TYPE_REFANY: printf("refany"); return; @@ -931,19 +937,15 @@ void DumpIL(MethodContext* mc) mc->repCompileMethod(&cmi, &flags, &os); - const char* moduleName = nullptr; - const char* methodName = mc->repGetMethodName(cmi.ftn, &moduleName); - const char* className = mc->repGetClassName(mc->repGetMethodClass(cmi.ftn)); - printf("// ProcessName - '%s'\n", mc->cr->repProcessName()); printf(".assembly extern mscorlib{}\n"); - printf(".assembly %s{}\n", moduleName); - printf(".class %s\n", className); + printf(".assembly dumped_asm\n"); + printf(".class %s\n", getClassName(mc, mc->repGetMethodClass(cmi.ftn)).c_str()); printf("{\n"); printf(" .method "); DumpAttributeToConsoleBare(mc->repGetMethodAttribs(cmi.ftn)); DumpPrimToConsoleBare(mc, cmi.args.retType, CastHandle(cmi.args.retTypeClass)); - printf(" %s(", methodName); + printf(" %s(", getMethodName(mc, cmi.ftn).c_str()); DumpSigToConsoleBare(mc, &cmi.args); printf(")\n"); printf(" {\n"); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index b4e16e8770393..dd66096a5eded 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -395,9 +395,6 @@ struct Agnostic_AppendClassNameIn { DWORD nBufLenIsZero; DWORDLONG classHandle; - DWORD fNamespace; - DWORD fFullInst; - DWORD fAssembly; }; struct Agnostic_AppendClassNameOut @@ -776,11 +773,16 @@ struct Agnostic_RecordCallSite DWORDLONG methodHandle; }; -struct Agnostic_PrintObjectDescriptionResult +struct Agnostic_PrintResult { - DWORDLONG bytesWritten; - DWORDLONG requiredBufferSize; - DWORD buffer; + // Required size of a buffer to contain everything including null terminator. + // UINT_MAX if it was not determined during recording. + DWORD requiredBufferSize; + // Index of stored string buffer. We always store this without null terminator. + // May be UINT_MAX if no buffer was stored. + DWORD stringBuffer; + // The size of the buffer stored by stringBuffer. + DWORD stringBufferSize; }; #pragma pack(pop) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp index b524addc2d383..9f7c5d8485c30 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp @@ -19,8 +19,9 @@ void ASMDumper::DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr) ZeroMemory(buff, bufflen * sizeof(char)); buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, ";;Generated from SuperPMI on original input '%s'", cr->repProcessName()); + buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, "\r\n Method Name \"%s\"", - mc->repGetMethodName(info.ftn, nullptr)); + getMethodName(mc, info.ftn).c_str()); WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr); ULONG hotCodeSize; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h index e1f6cd0952276..90af3ef16febf 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h @@ -6,6 +6,7 @@ #include "methodcontext.h" #include "compileresult.h" +#include "spmiutil.h" class ASMDumper { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp b/src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp index 75bbf2a55c76e..79778bf508493 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp @@ -215,28 +215,6 @@ CallType CallUtils::GetDirectCallSiteInfo(MethodContext* mc, // SuperPMI's method context replaying instead of directly making calls into the JIT/EE interface. //------------------------------------------------------------------------------------------------- -// Originally from src/jit/ee_il_dll.cpp -const char* CallUtils::GetMethodName(MethodContext* mc, CORINFO_METHOD_HANDLE method, const char** classNamePtr) -{ - if (GetHelperNum(method)) - { - if (classNamePtr != nullptr) - *classNamePtr = "HELPER"; - - // The JIT version uses the getHelperName JIT/EE interface call, but this is easier for us - return kHelperName[GetHelperNum(method)]; - } - - if (IsNativeMethod(method)) - { - if (classNamePtr != nullptr) - *classNamePtr = "NATIVE"; - method = GetMethodHandleForNative(method); - } - - return (mc->repGetMethodName(method, classNamePtr)); -} - // Originally from src/jit/eeinterface.cpp // If `ignoreMethodName` is `true`, we construct the function signature with a dummy method name that will be the // same for all methods. @@ -244,14 +222,22 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL { const char* returnType = NULL; - const char* className = ignoreMethodName ? "CLASS" : nullptr; - const char* methodName = ignoreMethodName ? "METHOD" : GetMethodName(mc, hnd, &className); - if ((GetHelperNum(hnd) != CORINFO_HELP_UNDEF) || IsNativeMethod(hnd)) + if ((GetHelperNum(hnd) != CORINFO_HELP_UNDEF)) + { + return kHelperName[GetHelperNum(hnd)]; + } + + std::string className = "CLASS"; + std::string methodName = "METHOD"; + + if (!ignoreMethodName) { - return methodName; + className = getClassName(mc, mc->repGetMethodClass(hnd)); + methodName = getMethodName(mc, hnd); } - size_t length = 0; + // Class name and colon + size_t length = className.size() + 1; unsigned i; /* Generating the full signature is a two-pass process. First we have to walk @@ -263,17 +249,8 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL /* initialize length with length of className and '.' */ - if (className != nullptr) - length = strlen(className) + 1; - else - { - // Tweaked to avoid using CRT assertions - Assert(strlen(".") == 7); - length = 7; - } - /* add length of methodName and opening bracket */ - length += strlen(methodName) + 1; + length += methodName.size() + 1; CORINFO_ARG_LIST_HANDLE argList = sig.args; @@ -317,17 +294,10 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL /* Now generate the full signature string in the allocated buffer */ - if (className) - { - strcpy_s(retName, length, className); - strcat_s(retName, length, ":"); - } - else - { - strcpy_s(retName, length, "."); - } + strcpy_s(retName, length, className.c_str()); + strcat_s(retName, length, ":"); - strcat_s(retName, length, methodName); + strcat_s(retName, length, methodName.c_str()); // append the signature strcat_s(retName, length, "("); @@ -376,17 +346,3 @@ inline CorInfoHelpFunc CallUtils::GetHelperNum(CORINFO_METHOD_HANDLE method) return (CORINFO_HELP_UNDEF); return ((CorInfoHelpFunc)(((size_t)method) >> 2)); } - -// Originally from jit/compiler.hpp -inline bool CallUtils::IsNativeMethod(CORINFO_METHOD_HANDLE method) -{ - return ((((size_t)method) & 0x2) == 0x2); -} - -// Originally from jit/compiler.hpp -inline CORINFO_METHOD_HANDLE CallUtils::GetMethodHandleForNative(CORINFO_METHOD_HANDLE method) -{ - // Tweaked to avoid using CRT assertions - Assert((((size_t)method) & 0x3) == 0x2); - return (CORINFO_METHOD_HANDLE)(((size_t)method) & ~0x3); -} diff --git a/src/coreclr/tools/superpmi/superpmi-shared/callutils.h b/src/coreclr/tools/superpmi/superpmi-shared/callutils.h index b0b04cb59bb4d..7d29de3d0b789 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/callutils.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/callutils.h @@ -29,9 +29,6 @@ class CallUtils /*out*/ CORINFO_SIG_INFO* outSigInfo, /*out*/ char** outCallTargetSymbol); static CorInfoHelpFunc GetHelperNum(CORINFO_METHOD_HANDLE method); - static bool IsNativeMethod(CORINFO_METHOD_HANDLE method); - static CORINFO_METHOD_HANDLE GetMethodHandleForNative(CORINFO_METHOD_HANDLE method); - static const char* GetMethodName(MethodContext* mc, CORINFO_METHOD_HANDLE method, const char** classNamePtr); static const char* GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDLE hnd, CORINFO_SIG_INFO sig, bool ignoreMethodName = false); }; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 588d96884df20..70361a38b29c5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -18,7 +18,6 @@ LWM(AllocPgoInstrumentationBySchema, DWORDLONG, Agnostic_AllocPgoInstrumentationBySchema) LWM(GetPgoInstrumentationResults, DWORDLONG, Agnostic_GetPgoInstrumentationResults) -LWM(AppendClassName, Agnostic_AppendClassNameIn, Agnostic_AppendClassNameOut) LWM(AreTypesEquivalent, DLDL, DWORD) LWM(AsCorInfoType, DWORDLONG, DWORD) LWM(CanAccessClass, Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut) @@ -66,7 +65,6 @@ LWM(GetClassAttribs, DWORDLONG, DWORD) LWM(GetClassDomainID, DWORDLONG, DLD) LWM(GetClassGClayout, DWORDLONG, Agnostic_GetClassGClayout) LWM(GetClassModuleIdForStatics, DWORDLONG, Agnostic_GetClassModuleIdForStatics) -LWM(GetClassName, DWORDLONG, DWORD) LWM(GetClassNameFromMetadata, DLD, DD) LWM(GetTypeInstantiationArgument, DLD, DWORDLONG) LWM(GetClassNumInstanceFields, DWORDLONG, DWORD) @@ -85,7 +83,6 @@ LWM(GetStaticFieldCurrentClass, DWORDLONG, Agnostic_GetStaticFieldCurrentClass) LWM(GetFieldClass, DWORDLONG, DWORDLONG) LWM(GetFieldInClass, DLD, DWORDLONG) LWM(GetFieldInfo, Agnostic_GetFieldInfo, Agnostic_CORINFO_FIELD_INFO) -LWM(GetFieldName, DWORDLONG, DD) LWM(GetFieldOffset, DWORDLONG, DWORD) LWM(GetFieldThreadLocalStoreID, DWORDLONG, DLD) LWM(GetFieldType, DLDL, DLD) @@ -93,7 +90,6 @@ LWM(GetFunctionEntryPoint, DLD, DLD) LWM(GetFunctionFixedEntryPoint, DWORDLONG, Agnostic_CORINFO_CONST_LOOKUP) LWM(GetGSCookie, DWORD, DLDL) LWM(GetHelperFtn, DWORD, DLDL) -LWM(GetHelperName, DWORD, DWORD) LWM(GetHFAType, DWORDLONG, DWORD) LWM(GetInlinedCallFrameVptr, DWORD, DLDL) LWM(GetIntConfigValue, Agnostic_ConfigIntInfo, DWORD) @@ -112,7 +108,6 @@ LWM(GetMethodModule, DWORDLONG, DWORDLONG) LWM(GetMethodDefFromMethod, DWORDLONG, DWORD) LWM(GetMethodHash, DWORDLONG, DWORD) LWM(GetMethodInfo, DWORDLONG, Agnostic_GetMethodInfo) -LWM(GetMethodName, DLD, DD) LWM(GetMethodNameFromMetadata, Agnostic_CORINFO_METHODNAME_TOKENin, Agnostic_CORINFO_METHODNAME_TOKENout) LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO) LWM(GetMethodSync, DWORDLONG, DLDL) @@ -154,7 +149,10 @@ LWM(IsIntrinsicType, DWORDLONG, DWORD) LWM(IsSDArray, DWORDLONG, DWORD) LWM(IsValidStringRef, DLD, DWORD) LWM(GetStringLiteral, DLDDD, DD) -LWM(PrintObjectDescription, DLDL, Agnostic_PrintObjectDescriptionResult) +LWM(PrintObjectDescription, DWORDLONG, Agnostic_PrintResult) +LWM(PrintClassName, DWORDLONG, Agnostic_PrintResult) +LWM(PrintFieldName, DWORDLONG, Agnostic_PrintResult) +LWM(PrintMethodName, DWORDLONG, Agnostic_PrintResult) LWM(IsValidToken, DLD, DWORD) LWM(IsValueClass, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index cb6db7560e21f..e3267b4d0257c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -1063,65 +1063,6 @@ CorInfoInitClassResult MethodContext::repInitClass(CORINFO_FIELD_HANDLE field, return result; } -void MethodContext::recGetMethodName(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName) -{ - if (GetMethodName == nullptr) - GetMethodName = new LightWeightMap(); - DD value; - DLD key; - key.A = CastHandle(ftn); - key.B = (moduleName != nullptr); - - if (methodname != nullptr) - value.A = GetMethodName->AddBuffer((unsigned char*)methodname, (DWORD)strlen(methodname) + 1); - else - value.A = (DWORD)-1; - - if ((moduleName != nullptr) && (*moduleName != nullptr)) - value.B = GetMethodName->AddBuffer((unsigned char*)*moduleName, (DWORD)strlen(*moduleName) + 1); - else - value.B = (DWORD)-1; - - GetMethodName->Add(key, value); - DEBUG_REC(dmpGetMethodName(key, value)); -} -void MethodContext::dmpGetMethodName(DLD key, DD value) -{ - unsigned char* methodName = (unsigned char*)GetMethodName->GetBuffer(value.A); - unsigned char* moduleName = (unsigned char*)GetMethodName->GetBuffer(value.B); - printf("GetMethodName key - ftn-%016llX modNonNull-%u, value meth-'%s', mod-'%s'", key.A, key.B, methodName, - moduleName); - GetMethodName->Unlock(); -} - -const char* MethodContext::repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName) -{ - const char* result = "hackishMethodName"; - DD value; - DLD key; - key.A = CastHandle(ftn); - key.B = (moduleName != nullptr); - - int itemIndex = -1; - if (GetMethodName != nullptr) - itemIndex = GetMethodName->GetIndex(key); - if (itemIndex < 0) - { - if (moduleName != nullptr) - *moduleName = "hackishModuleName"; - } - else - { - value = GetMethodName->Get(key); - DEBUG_REP(dmpGetMethodName(key, value)); - - if (moduleName != nullptr) - *moduleName = (const char*)GetMethodName->GetBuffer(value.B); - result = (const char*)GetMethodName->GetBuffer(value.A); - } - return result; -} - void MethodContext::recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, char* methodName, const char** className, @@ -4742,52 +4683,6 @@ CorInfoType MethodContext::repGetFieldType(CORINFO_FIELD_HANDLE field, return (CorInfoType)value.B; } -void MethodContext::recGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName, const char* result) -{ - if (GetFieldName == nullptr) - GetFieldName = new LightWeightMap(); - - DD value; - - if (result != nullptr) - value.A = GetFieldName->AddBuffer((unsigned char*)result, (DWORD)strlen(result) + 1); - else - value.A = (DWORD)-1; - - if ((moduleName != nullptr) && (*moduleName != nullptr)) // protect strlen - value.B = (DWORD)GetFieldName->AddBuffer((unsigned char*)*moduleName, (DWORD)strlen(*moduleName) + 1); - else - value.B = (DWORD)-1; - - DWORDLONG key = CastHandle(ftn); - GetFieldName->Add(key, value); - DEBUG_REC(dmpGetFieldName(key, value)); -} -void MethodContext::dmpGetFieldName(DWORDLONG key, DD value) -{ - unsigned char* fieldName = (unsigned char*)GetFieldName->GetBuffer(value.A); - unsigned char* moduleName = (unsigned char*)GetFieldName->GetBuffer(value.B); - printf("GetFieldName key - ftn-%016llX, value fld-'%s', mod-'%s'", key, fieldName, moduleName); - GetFieldName->Unlock(); -} -const char* MethodContext::repGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName) -{ - if (GetFieldName == nullptr) - { - if (moduleName != nullptr) - *moduleName = "hackishModuleName"; - return "hackishFieldName"; - } - - DWORDLONG key = CastHandle(ftn); - DD value = GetFieldName->Get(key); - DEBUG_REP(dmpGetFieldName(key, value)); - - if (moduleName != nullptr) - *moduleName = (const char*)GetFieldName->GetBuffer(value.B); - return (const char*)GetFieldName->GetBuffer(value.A); -} - void MethodContext::recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source, CorInfoInlineTypeCheck result) @@ -4946,103 +4841,6 @@ int MethodContext::repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned me return srcBufferLength; } -void MethodContext::recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) -{ - if (PrintObjectDescription == nullptr) - PrintObjectDescription = new LightWeightMap(); - - DLDL key; - key.A = CastHandle(handle); - key.B = (DWORDLONG)bufferSize; - - DWORD strBuf = (DWORD)-1; - if (buffer != nullptr && bytesWritten > 0) - { - size_t bufferRealSize = min(bytesWritten, bufferSize - 1); - strBuf = (DWORD)PrintObjectDescription->AddBuffer((unsigned char*)buffer, (DWORD)bufferRealSize); - } - - Agnostic_PrintObjectDescriptionResult value; - value.bytesWritten = (DWORDLONG)bytesWritten; - value.requiredBufferSize = (DWORDLONG)(pRequiredBufferSize == nullptr ? 0 : *pRequiredBufferSize); - value.buffer = (DWORD)strBuf; - - PrintObjectDescription->Add(key, value); - DEBUG_REC(dmpPrintObjectDescription(key, value)); -} -void MethodContext::dmpPrintObjectDescription(DLDL key, Agnostic_PrintObjectDescriptionResult value) -{ - printf("PrintObjectDescription key hnd-%016llX bufSize-%u, bytesWritten-%u, pRequiredBufferSize-%u", key.A, (unsigned)key.B, (unsigned)value.bytesWritten, (unsigned)value.requiredBufferSize); - PrintObjectDescription->Unlock(); -} -size_t MethodContext::repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) -{ - DLDL key; - key.A = CastHandle(handle); - key.B = (DWORDLONG)bufferSize; - - AssertMapAndKeyExist(PrintObjectDescription, key, ": key handle-%016llX bufferSize-%016llX", key.A, key.B); - - Agnostic_PrintObjectDescriptionResult value = PrintObjectDescription->Get(key); - DEBUG_REP(dmpPrintObjectDescription(key, value)); - if (pRequiredBufferSize != nullptr) - { - *pRequiredBufferSize = (size_t)value.requiredBufferSize; - } - - size_t bytesWritten = 0; - - BYTE* srcBuffer = (BYTE*)PrintObjectDescription->GetBuffer(value.buffer); - if (bufferSize > 0) - { - bytesWritten = min(bufferSize - 1, (size_t)value.bytesWritten); - memcpy(buffer, srcBuffer, bytesWritten); - - // Always null-terminate - buffer[bytesWritten] = 0; - } - return bytesWritten; -} - -void MethodContext::recGetHelperName(CorInfoHelpFunc funcNum, const char* result) -{ - if (GetHelperName == nullptr) - GetHelperName = new LightWeightMap(); - - DWORD value = (DWORD)-1; - if (result != nullptr) - value = (DWORD)GetHelperName->AddBuffer((unsigned char*)result, (DWORD)strlen(result) + 1); - - DWORD key = (DWORD)funcNum; - GetHelperName->Add(key, value); - DEBUG_REC(dmpGetHelperName(key, value)); -} -void MethodContext::dmpGetHelperName(DWORD key, DWORD value) -{ - printf("GetHelperName key ftn-%u, value '%s'", key, (const char*)GetHelperName->GetBuffer(value)); - GetHelperName->Unlock(); -} -const char* MethodContext::repGetHelperName(CorInfoHelpFunc funcNum) -{ - if (GetHelperName == nullptr) - return "Yickish helper name"; - - DWORD key = (DWORD)funcNum; - - int itemIndex = GetHelperName->GetIndex(key); - if (itemIndex < 0) - { - return "hackishHelperName"; - } - else - { - DWORD value = GetHelperName->Get(key); - DEBUG_REP(dmpGetHelperName(key, value)); - unsigned int buffIndex = (unsigned int)value; - return (const char*)GetHelperName->GetBuffer(buffIndex); - } -} - void MethodContext::recCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent, bool result) { if (CanCast == nullptr) @@ -5911,7 +5709,7 @@ bool MethodContext::repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return value != 0; } -void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType, TypeCompareState result) +void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result) { if (IsEnum == nullptr) IsEnum = new LightWeightMap(); @@ -5920,10 +5718,7 @@ void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* un DLD value; ZeroMemory(&value, sizeof(value)); - if (underlyingType != nullptr) - value.A = CastHandle(*underlyingType); - else - value.A = 0; + value.A = CastHandle(underlyingType); value.B = (DWORD)result; IsEnum->Add(key, value); @@ -6537,41 +6332,6 @@ bool MethodContext::repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaT return value != 0; } -void MethodContext::recGetClassName(CORINFO_CLASS_HANDLE cls, const char* result) -{ - if (GetClassName == nullptr) - GetClassName = new LightWeightMap(); - - DWORD value = (DWORD)-1; - if (result != nullptr) - value = (DWORD)GetClassName->AddBuffer((unsigned char*)result, (unsigned int)strlen(result) + 1); - - DWORDLONG key = CastHandle(cls); - GetClassName->Add(key, value); - DEBUG_REC(dmpGetClassName(key, value)); -} -void MethodContext::dmpGetClassName(DWORDLONG key, DWORD value) -{ - printf("GetClassName key %016llX, value %s", key, GetClassName->GetBuffer(value)); - GetClassName->Unlock(); -} -const char* MethodContext::repGetClassName(CORINFO_CLASS_HANDLE cls) -{ - DWORDLONG key = CastHandle(cls); - - if (GetClassName == nullptr) - return "hackishClassName"; - int index = GetClassName->GetIndex(key); - if (index == -1) - return "hackishClassName"; - - int offset = GetClassName->Get(key); - DEBUG_REP(dmpGetClassName(key, (DWORD)offset)); - - const char* name = (const char*)GetClassName->GetBuffer(offset); - return name; -} - void MethodContext::recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, char* className, const char** namespaceName) { if (GetClassNameFromMetadata == nullptr) @@ -6683,117 +6443,183 @@ CORINFO_CLASS_HANDLE MethodContext::repGetTypeInstantiationArgument(CORINFO_CLAS return result; } -void MethodContext::recAppendClassName( - int nBufLenIn, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly, - int nLenOut, - const char16_t* result) -{ - if (AppendClassName == nullptr) - AppendClassName = new LightWeightMap(); - - // The API has two different behaviors depending on whether the input specified length is zero or non-zero: - // (1) zero: returns the length of the string (which the caller can use to allocate a buffer) - // (2) non-zero: fill as much of the buffer with the name as there is space available. - // We don't want the input length to be part of the key, since the caller could potentially pass in a smaller - // or larger buffer, and we'll fill in as much of the buffer as possible. We do need to handle both the zero - // and non-zero cases, though, so we'll get one record for first call using zero (with the correct buffer size result), - // and another for the second call with a big-enough buffer. We could presumably just store the second case - // (and overwrite the first record), since it contains the same output length, but it is useful to store - // (and see) all the JIT-EE interface calls. - - Agnostic_AppendClassNameIn key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.nBufLenIsZero = (nBufLenIn == 0) ? 1 : 0; - key.classHandle = CastHandle(cls); - key.fNamespace = fNamespace; - key.fFullInst = fFullInst; - key.fAssembly = fAssembly; +void MethodContext::recPrint( + const char* name, + LightWeightMap*& map, + DWORDLONG handle, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize, + size_t bytesWritten) +{ + if (map == nullptr) + map = new LightWeightMap(); + + // Required size of a buffer that contains all data and null terminator. + UINT requiredBufferSize = UINT_MAX; + if (pRequiredBufferSize != nullptr) + { + requiredBufferSize = (UINT)(*pRequiredBufferSize); + } + else if (bytesWritten + 1 < bufferSize) + { + requiredBufferSize = (UINT)(bytesWritten + 1); + } + + Agnostic_PrintResult res; + int index = map->GetIndex(handle); + if (index != -1) + { + // Merge with existing entry + + res = map->GetItem(index); + + if (requiredBufferSize != UINT_MAX) + { + res.requiredBufferSize = requiredBufferSize; + } + + if (bytesWritten > res.stringBufferSize) + { + // Always stored without null terminator. + res.stringBuffer = map->AddBuffer((unsigned char*)buffer, static_cast(bytesWritten)); + res.stringBufferSize = (UINT)bytesWritten; + } - Agnostic_AppendClassNameOut value; - value.nLen = nLenOut; - value.name_index = (DWORD)-1; + map->Update(index, res); - // Don't save the string buffer if the incoming buffer length is zero, even if the string buffer is non-null. - // In that case, the EE/crossgen2 don't zero-terminate the buffer (since they assume it is zero sized). - if ((result != nullptr) && (nBufLenIn > 0)) + DEBUG_REC(dmpPrint(name, map, handle, res)); + return; + } + + if (buffer != nullptr) + { + res.stringBuffer = map->AddBuffer((unsigned char*)buffer, static_cast(bytesWritten)); + } + else { - value.name_index = (DWORD)AppendClassName->AddBuffer( - (unsigned char*)result, - (unsigned int)((wcslen((LPCWSTR)result) + 1) * sizeof(char16_t))); + res.stringBuffer = UINT_MAX; } - AppendClassName->Add(key, value); - DEBUG_REC(dmpAppendClassName(key, value)); + res.stringBufferSize = (UINT)bytesWritten; + res.requiredBufferSize = requiredBufferSize; + + map->Add(handle, res); + DEBUG_REC(dmpPrint(name, map, handle, res)); } -void MethodContext::dmpAppendClassName(const Agnostic_AppendClassNameIn& key, const Agnostic_AppendClassNameOut& value) +void MethodContext::dmpPrint( + const char* name, + LightWeightMapBuffer* buffer, + DWORDLONG key, + const Agnostic_PrintResult& value) { - const char16_t* name = (const char16_t*)AppendClassName->GetBuffer(value.name_index); - printf("AppendClassName key lenzero-%s cls-%016llX ns-%u fi-%u as-%u, value len-%u ni-%u name-%S", - key.nBufLenIsZero ? "true" : "false", key.classHandle, key.fNamespace, key.fFullInst, key.fAssembly, - value.nLen, value.name_index, (const WCHAR*)name); - AppendClassName->Unlock(); + printf("%s key hnd-%016llX, stringBufferSize-%u, requiredBufferSize-%u", name, key, value.stringBufferSize, value.requiredBufferSize); + buffer->Unlock(); } -int MethodContext::repAppendClassName(char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) +size_t MethodContext::repPrint( + const char* name, + LightWeightMap*& map, + DWORDLONG handle, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - static const char16_t unknownClass[] = u"hackishClassName"; - static const int unknownClassLength = (int)(ArrLen(unknownClass) - 1); // Don't include null terminator in length. + AssertMapAndKeyExist(map, handle, ": map %s key %016llx", name, handle); - // By default, at least return something. - const char16_t* name = unknownClass; - int nLen = unknownClassLength; + Agnostic_PrintResult res = map->Get(handle); + DEBUG_REP(dmpPrint(name, buffer, handle, res)); - if (AppendClassName != nullptr) + if (pRequiredBufferSize != nullptr) { - Agnostic_AppendClassNameIn key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.nBufLenIsZero = (*pnBufLen == 0) ? 1 : 0; - key.classHandle = CastHandle(cls); - key.fNamespace = fNamespace; - key.fFullInst = fFullInst; - key.fAssembly = fAssembly; - - // First, see if we have an entry for this query. - int index = AppendClassName->GetIndex(key); - if (index != -1) + if (res.requiredBufferSize == UINT_MAX) { - // Then, actually get the value. - Agnostic_AppendClassNameOut value = AppendClassName->Get(key); - DEBUG_REP(dmpAppendClassName(key, value)); - - nLen = value.nLen; - name = (const char16_t*)AppendClassName->GetBuffer(value.name_index); + LogException(EXCEPTIONCODE_MC, "SuperPMI assertion failed (missing requiredBufferSize for %s key %016llx)", name, handle); } + + *pRequiredBufferSize = res.requiredBufferSize; + } + + // requiredBufferSize is with null terminator, but buffer is stored without + // null terminator. Determine if we have enough data to answer the query + // losslessly. + // Note that requiredBufferSize is always set by recording side if we had + // enough information to determine it. + bool haveFullBuffer = (res.requiredBufferSize != UINT_MAX) && ((res.stringBufferSize + 1) >= res.requiredBufferSize); + if (!haveFullBuffer && (bufferSize > static_cast(res.stringBufferSize) + 1)) + { + LogException(EXCEPTIONCODE_MC, "SuperPMI assertion failed (not enough buffer data for %s key %016llx)", name, handle); } - if ((ppBuf != nullptr) && (*ppBuf != nullptr) && (*pnBufLen > 0) && (name != nullptr)) + size_t bytesWritten = 0; + if ((buffer != nullptr) && (bufferSize > 0)) { - // Copy as much as will fit. - char16_t* pBuf = *ppBuf; - int nLenToCopy = min(*pnBufLen, nLen + /* null terminator */ 1); - for (int i = 0; i < nLenToCopy - 1; i++) + bytesWritten = min(bufferSize - 1, res.stringBufferSize); + if (bytesWritten > 0) { - pBuf[i] = name[i]; + // The "full buffer" check above ensures this given that + // res.stringBuffer == UINT_MAX implies res.stringBufferSize == 0. + Assert(res.stringBuffer != UINT_MAX); + char* storedBuffer = (char*)map->GetBuffer(res.stringBuffer); + memcpy(buffer, storedBuffer, bytesWritten); } - pBuf[nLenToCopy - 1] = 0; // null terminate the string if it wasn't already - - // Update the buffer pointer and buffer size pointer based on the amount actually copied. - // Don't include the null terminator. `*ppBuf` will point at the added null terminator. - (*ppBuf) += nLenToCopy - 1; - (*pnBufLen) -= nLenToCopy - 1; + buffer[bytesWritten] = '\0'; } - return nLen; + return bytesWritten; +} + +void MethodContext::recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) +{ + recPrint("PrintObjectDescription", PrintObjectDescription, CastHandle(handle), buffer, bufferSize, pRequiredBufferSize, bytesWritten); +} +void MethodContext::dmpPrintObjectDescription(DWORDLONG key, const Agnostic_PrintResult& value) +{ + dmpPrint("PrintObjectDescription", PrintObjectDescription, key, value); +} +size_t MethodContext::repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) +{ + return repPrint("PrintObjectDescription", PrintObjectDescription, CastHandle(handle), buffer, bufferSize, pRequiredBufferSize); +} + +void MethodContext::recPrintClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) +{ + recPrint("PrintClassName", PrintClassName, CastHandle(cls), buffer, bufferSize, pRequiredBufferSize, bytesWritten); +} +void MethodContext::dmpPrintClassName(DWORDLONG key, const Agnostic_PrintResult& value) +{ + dmpPrint("PrintClassName", PrintClassName, key, value); +} +size_t MethodContext::repPrintClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) +{ + return repPrint("PrintClassName", PrintClassName, CastHandle(cls), buffer, bufferSize, pRequiredBufferSize); +} + +void MethodContext::recPrintFieldName(CORINFO_FIELD_HANDLE fld, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) +{ + recPrint("PrintFieldName", PrintFieldName, CastHandle(fld), buffer, bufferSize, pRequiredBufferSize, bytesWritten); +} +void MethodContext::dmpPrintFieldName(DWORDLONG key, const Agnostic_PrintResult& value) +{ + dmpPrint("PrintFieldName", PrintFieldName, key, value); +} +size_t MethodContext::repPrintFieldName(CORINFO_FIELD_HANDLE fld, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) +{ + return repPrint("PrintFieldName", PrintFieldName, CastHandle(fld), buffer, bufferSize, pRequiredBufferSize); +} + +void MethodContext::recPrintMethodName(CORINFO_METHOD_HANDLE meth, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) +{ + recPrint("PrintMethodName", PrintMethodName, CastHandle(meth), buffer, bufferSize, pRequiredBufferSize, bytesWritten); +} +void MethodContext::dmpPrintMethodName(DWORDLONG key, const Agnostic_PrintResult& value) +{ + dmpPrint("PrintMethodName", PrintMethodName, key, value); +} +size_t MethodContext::repPrintMethodName(CORINFO_METHOD_HANDLE meth, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) +{ + return repPrint("PrintMethodName", PrintMethodName, CastHandle(meth), buffer, bufferSize, pRequiredBufferSize); } void MethodContext::recGetTailCallHelpers( diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 184102f757d8c..be1621f08dd53 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -175,10 +175,6 @@ class MethodContext CORINFO_METHOD_HANDLE method, CORINFO_CONTEXT_HANDLE context); - void recGetMethodName(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName); - void dmpGetMethodName(DLD key, DD value); - const char* repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName); - void recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName, @@ -616,10 +612,6 @@ class MethodContext CORINFO_CLASS_HANDLE* structType, CORINFO_CLASS_HANDLE memberParent); - void recGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName, const char* result); - void dmpGetFieldName(DWORDLONG key, DD value); - const char* repGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName); - void recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source, CorInfoInlineTypeCheck result); @@ -638,14 +630,6 @@ class MethodContext void dmpGetStringLiteral(DLDDD key, DD value); int repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex); - void recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); - void dmpPrintObjectDescription(DLDL key, Agnostic_PrintObjectDescriptionResult value); - size_t repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); - - void recGetHelperName(CorInfoHelpFunc funcNum, const char* result); - void dmpGetHelperName(DWORD key, DWORD value); - const char* repGetHelperName(CorInfoHelpFunc funcNum); - void recCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent, bool result); void dmpCanCast(DLDL key, DWORD value); bool repCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent); @@ -744,7 +728,7 @@ class MethodContext void dmpIsMoreSpecificType(DLDL key, DWORD value); bool repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType, TypeCompareState result); + void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result); void dmpIsEnum(DWORDLONG key, DLD value); TypeCompareState repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); @@ -817,10 +801,6 @@ class MethodContext void dmpIsValidToken(DLD key, DWORD value); bool repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK); - void recGetClassName(CORINFO_CLASS_HANDLE cls, const char* result); - void dmpGetClassName(DWORDLONG key, DWORD value); - const char* repGetClassName(CORINFO_CLASS_HANDLE cls); - void recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, char* className, const char** namespaceName); void dmpGetClassNameFromMetadata(DLD key, DD value); const char* repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName); @@ -829,20 +809,42 @@ class MethodContext void dmpGetTypeInstantiationArgument(DLD key, DWORDLONG value); CORINFO_CLASS_HANDLE repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index); - void recAppendClassName(int nBufLenIn, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly, - int nLenOut, - const char16_t* result); - void dmpAppendClassName(const Agnostic_AppendClassNameIn& key, const Agnostic_AppendClassNameOut& value); - int repAppendClassName(char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly); + void recPrint( + const char* name, + LightWeightMap*& map, + DWORDLONG handle, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize, + size_t bytesWritten); + void dmpPrint( + const char* name, + LightWeightMapBuffer* buffer, + DWORDLONG key, + const Agnostic_PrintResult& value); + size_t repPrint( + const char* name, + LightWeightMap*& map, + DWORDLONG handle, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize); + + void recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); + void dmpPrintObjectDescription(DWORDLONG key, const Agnostic_PrintResult& value); + size_t repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); + + void recPrintClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); + void dmpPrintClassName(DWORDLONG cls, const Agnostic_PrintResult& value); + size_t repPrintClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize = nullptr); + + void recPrintFieldName(CORINFO_FIELD_HANDLE fld, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); + void dmpPrintFieldName(DWORDLONG fld, const Agnostic_PrintResult& value); + size_t repPrintFieldName(CORINFO_FIELD_HANDLE fld, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize = nullptr); + + void recPrintMethodName(CORINFO_METHOD_HANDLE meth, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); + void dmpPrintMethodName(DWORDLONG meth, const Agnostic_PrintResult& value); + size_t repPrintMethodName(CORINFO_METHOD_HANDLE meth, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize = nullptr); void recGetTailCallHelpers( CORINFO_RESOLVED_TOKEN* callToken, @@ -963,10 +965,11 @@ enum mcPackets Packet_CanAccessClass = 3, Packet_CanAccessFamily = 4, Packet_CanCast = 5, + Packet_PrintMethodName = 6, Packet_CanGetCookieForPInvokeCalliSig = 7, Packet_CanGetVarArgsHandle = 8, Packet_CanInline = 9, - //Packet_CanInlineTypeCheckWithObjectVTable = 10, + Packet_PrintFieldName = 10, //Packet_CanSkipMethodVerification = 11, Packet_CanTailCall = 12, //Retired4 = 13, @@ -1012,7 +1015,6 @@ enum mcPackets Packet_GetFieldClass = 53, Packet_GetFieldInClass = 54, Packet_GetFieldInfo = 55, - Packet_GetFieldName = 56, Packet_GetFieldOffset = 57, Packet_GetFieldThreadLocalStoreID = 58, Packet_GetFieldType = 59, @@ -1020,7 +1022,6 @@ enum mcPackets Packet_GetFunctionFixedEntryPoint = 61, Packet_GetGSCookie = 62, Packet_GetHelperFtn = 63, - Packet_GetHelperName = 64, Packet_GetInlinedCallFrameVptr = 65, Packet_GetArrayIntrinsicID = 66, Packet_GetJitTimeLogFilename = 67, @@ -1031,7 +1032,6 @@ enum mcPackets Packet_GetMethodDefFromMethod = 72, Packet_GetMethodHash = 73, Packet_GetMethodInfo = 74, - Packet_GetMethodName = 75, Packet_GetMethodSig = 76, Packet_GetMethodSync = 77, Packet_GetMethodVTableOffset = 78, @@ -1104,7 +1104,7 @@ enum mcPackets //PacketCR_RecordCallSite = 146, Packet_GetLazyStringLiteralHelper = 147, Packet_IsIntrinsicType = 148, - Packet_AppendClassName = 149, + Packet_PrintClassName = 149, Packet_GetReadyToRunHelper = 150, Packet_GetIntConfigValue = 151, Packet_GetStringConfigValue = 152, diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp index 034e309634ebd..f80956305e2c3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp @@ -378,3 +378,38 @@ void PutArm64MovkConstant(UINT32* p, unsigned con) { *p = (*p & ~(0xffff << 5)) | ((con & 0xffff) << 5); } + +template +static std::string getFromPrinter(TPrint print) +{ + char buffer[256]; + + size_t requiredBufferSize; + print(buffer, sizeof(buffer), &requiredBufferSize); + + if (requiredBufferSize <= sizeof(buffer)) + { + return std::string(buffer); + } + else + { + std::vector vec(requiredBufferSize); + size_t printed = print(vec.data(), requiredBufferSize, nullptr); + assert(printed == requiredBufferSize - 1); + return std::string(vec.data()); + } +} + +std::string getMethodName(MethodContext* mc, CORINFO_METHOD_HANDLE methHnd) +{ + return getFromPrinter([&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { + return mc->repPrintMethodName(methHnd, buffer, bufferSize, requiredBufferSize); + }); +} + +std::string getClassName(MethodContext* mc, CORINFO_CLASS_HANDLE clsHnd) +{ + return getFromPrinter([&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { + return mc->repPrintClassName(clsHnd, buffer, bufferSize, requiredBufferSize); + }); +} diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h index f414e9be3623c..a8ea81c21c527 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h @@ -93,4 +93,7 @@ inline constexpr unsigned ArrLen(T (&)[size]) return size; } +std::string getMethodName(MethodContext* mc, CORINFO_METHOD_HANDLE methHnd); +std::string getClassName(MethodContext* mc, CORINFO_CLASS_HANDLE clsHnd); + #endif // !_SPMIUtil diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp index 723ee1d98ce80..0ef956bd62787 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp @@ -29,6 +29,20 @@ void interceptor_ICJC::finalizeAndCommitCollection(MethodContext* mc, CorJitResu mc->saveToFile(hFile); } +template +static void printInFull(TPrinter print) +{ + size_t requiredSize; + char buffer[256]; + print(buffer, sizeof(buffer), &requiredSize); + + if (requiredSize > sizeof(buffer)) + { + std::vector vec(requiredSize); + print(vec.data(), requiredSize, nullptr); + } +} + CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ struct CORINFO_METHOD_INFO* info, /* IN */ unsigned /* code:CorJitFlag */ flags, /* IN */ @@ -72,12 +86,11 @@ CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, // to build up a fat mc CORINFO_CLASS_HANDLE ourClass = our_ICorJitInfo.getMethodClass(info->ftn); our_ICorJitInfo.getClassAttribs(ourClass); - our_ICorJitInfo.getClassName(ourClass); our_ICorJitInfo.isValueClass(ourClass); our_ICorJitInfo.asCorInfoType(ourClass); - const char* className = nullptr; - our_ICorJitInfo.getMethodName(info->ftn, &className); + printInFull([&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { our_ICorJitInfo.printClassName(ourClass, buffer, bufferSize, requiredBufferSize); }); + printInFull([&](char* buffer, size_t bufferSize, size_t* requiredBufferSize) { our_ICorJitInfo.printMethodName(info->ftn, buffer, bufferSize, requiredBufferSize); }); #endif // Record data from the global context, if any diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 9e91b15de69fe..36933a56d3e6e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -483,15 +483,6 @@ CorInfoType interceptor_ICJI::asCorInfoType(CORINFO_CLASS_HANDLE cls) return temp; } -// for completeness -const char* interceptor_ICJI::getClassName(CORINFO_CLASS_HANDLE cls) -{ - mc->cr->AddCall("getClassName"); - const char* result = original_ICorJitInfo->getClassName(cls); - mc->recGetClassName(cls, result); - return result; -} - const char* interceptor_ICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName) { mc->cr->AddCall("getClassNameFromMetadata"); @@ -508,46 +499,12 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument(CORINFO_CLAS return result; } -// Append a (possibly truncated) textual representation of the type `cls` to a preallocated buffer. -// -// Arguments: -// ppBuf - Pointer to buffer pointer. See below for details. -// pnBufLen - Pointer to buffer length. Must not be nullptr. See below for details. -// fNamespace - If true, include the namespace/enclosing classes. -// fFullInst - If true (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters. -// fAssembly - If true, suffix with a comma and the full assembly qualification. -// -// Returns the length of the representation, as a count of characters (but not including a terminating null character). -// Note that this will always be the actual number of characters required by the representation, even if the string -// was truncated when copied to the buffer. -// -// Operation: -// -// On entry, `*pnBufLen` specifies the size of the buffer pointed to by `*ppBuf` as a count of characters. -// There are two cases: -// 1. If the size is zero, the function computes the length of the representation and returns that. -// `ppBuf` is ignored (and may be nullptr) and `*ppBuf` and `*pnBufLen` are not updated. -// 2. If the size is non-zero, the buffer pointed to by `*ppBuf` is (at least) that size. The class name -// representation is copied to the buffer pointed to by `*ppBuf`. As many characters of the name as will fit in the -// buffer are copied. Thus, if the name is larger than the size of the buffer, the name will be truncated in the buffer. -// The buffer is guaranteed to be null terminated. Thus, the size must be large enough to include a terminating null -// character, or the string will be truncated to include one. On exit, `*pnBufLen` is updated by subtracting the -// number of characters that were actually copied to the buffer. Also, `*ppBuf` is updated to point at the null -// character that was added to the end of the name. -// -int interceptor_ICJI::appendClassName(_Outptr_opt_result_buffer_(*pnBufLen) char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) +size_t interceptor_ICJI::printClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - mc->cr->AddCall("appendClassName"); - char16_t* pBufIn = (ppBuf == nullptr) ? nullptr : *ppBuf; - int nBufLenIn = (pnBufLen == nullptr) ? 0 : *pnBufLen; // pnBufLen should never be nullptr, but don't crash if it is. - int nLenOut = original_ICorJitInfo->appendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); - mc->recAppendClassName(nBufLenIn, cls, fNamespace, fFullInst, fAssembly, nLenOut, pBufIn); - return nLenOut; + mc->cr->AddCall("printClassName"); + size_t bytesWritten = original_ICorJitInfo->printClassName(cls, buffer, bufferSize, pRequiredBufferSize); + mc->recPrintClassName(cls, buffer, bufferSize, pRequiredBufferSize, bytesWritten); + return bytesWritten; } // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & @@ -838,14 +795,6 @@ void interceptor_ICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* p mc->recGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); } -const char* interceptor_ICJI::getHelperName(CorInfoHelpFunc funcNum) -{ - mc->cr->AddCall("getHelperName"); - const char* temp = original_ICorJitInfo->getHelperName(funcNum); - mc->recGetHelperName(funcNum, temp); - return temp; -} - // This function tries to initialize the class (run the class constructor). // this function returns whether the JIT must insert helper calls before // accessing static field or method. @@ -978,7 +927,7 @@ TypeCompareState interceptor_ICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLAS mc->cr->AddCall("isEnum"); CORINFO_CLASS_HANDLE tempUnderlyingType = nullptr; TypeCompareState temp = original_ICorJitInfo->isEnum(cls, &tempUnderlyingType); - mc->recIsEnum(cls, &tempUnderlyingType, temp); + mc->recIsEnum(cls, tempUnderlyingType, temp); if (underlyingType != nullptr) { *underlyingType = tempUnderlyingType; @@ -1074,16 +1023,12 @@ CorInfoIsAccessAllowedResult interceptor_ICJI::canAccessClass( // ICorFieldInfo // /**********************************************************************************/ -// this function is for debugging only. It returns the field name -// and if 'moduleName' is non-null, it sets it to something that will -// says which method (a class name, or a module name) -const char* interceptor_ICJI::getFieldName(CORINFO_FIELD_HANDLE ftn, /* IN */ - const char** moduleName /* OUT */ - ) + +size_t interceptor_ICJI::printFieldName(CORINFO_FIELD_HANDLE ftn, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - mc->cr->AddCall("getFieldName"); - const char* temp = original_ICorJitInfo->getFieldName(ftn, moduleName); - mc->recGetFieldName(ftn, moduleName, temp); + mc->cr->AddCall("printFieldName"); + size_t temp = original_ICorJitInfo->printFieldName(ftn, buffer, bufferSize, pRequiredBufferSize); + mc->recPrintFieldName(ftn, buffer, bufferSize, pRequiredBufferSize, temp); return temp; } @@ -1338,9 +1283,6 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass(CORINFO_SIG_INFO* sig, [&](DWORD exceptionCode) { this->mc->recGetArgClass(sig, args, temp, exceptionCode); - - // to build up a fat mc - getClassName(temp); }); return temp; @@ -1440,16 +1382,11 @@ mdMethodDef interceptor_ICJI::getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMeth return result; } -// this function is for debugging only. It returns the method name -// and if 'moduleName' is non-null, it sets it to something that will -// says which method (a class name, or a module name) -const char* interceptor_ICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */ - const char** moduleName /* OUT */ - ) +size_t interceptor_ICJI::printMethodName(CORINFO_METHOD_HANDLE ftn, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - mc->cr->AddCall("getMethodName"); - const char* temp = original_ICorJitInfo->getMethodName(ftn, moduleName); - mc->recGetMethodName(ftn, (char*)temp, moduleName); + mc->cr->AddCall("printMethodName"); + size_t temp = original_ICorJitInfo->printMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); + mc->recPrintMethodName(ftn, buffer, bufferSize, pRequiredBufferSize, temp); return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index 2ecdf378351f5..bdd5272db2017 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -332,13 +332,6 @@ CorInfoType interceptor_ICJI::asCorInfoType( return original_ICorJitInfo->asCorInfoType(cls); } -const char* interceptor_ICJI::getClassName( - CORINFO_CLASS_HANDLE cls) -{ - mcs->AddCall("getClassName"); - return original_ICorJitInfo->getClassName(cls); -} - const char* interceptor_ICJI::getClassNameFromMetadata( CORINFO_CLASS_HANDLE cls, const char** namespaceName) @@ -355,16 +348,14 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument( return original_ICorJitInfo->getTypeInstantiationArgument(cls, index); } -int interceptor_ICJI::appendClassName( - char16_t** ppBuf, - int* pnBufLen, +size_t interceptor_ICJI::printClassName( CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - mcs->AddCall("appendClassName"); - return original_ICorJitInfo->appendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); + mcs->AddCall("printClassName"); + return original_ICorJitInfo->printClassName(cls, buffer, bufferSize, pRequiredBufferSize); } bool interceptor_ICJI::isValueClass( @@ -587,13 +578,6 @@ void interceptor_ICJI::getReadyToRunDelegateCtorHelper( original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); } -const char* interceptor_ICJI::getHelperName( - CorInfoHelpFunc helpFunc) -{ - mcs->AddCall("getHelperName"); - return original_ICorJitInfo->getHelperName(helpFunc); -} - CorInfoInitClassResult interceptor_ICJI::initClass( CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, @@ -747,12 +731,14 @@ CorInfoIsAccessAllowedResult interceptor_ICJI::canAccessClass( return original_ICorJitInfo->canAccessClass(pResolvedToken, callerHandle, pAccessHelper); } -const char* interceptor_ICJI::getFieldName( - CORINFO_FIELD_HANDLE ftn, - const char** moduleName) +size_t interceptor_ICJI::printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - mcs->AddCall("getFieldName"); - return original_ICorJitInfo->getFieldName(ftn, moduleName); + mcs->AddCall("printFieldName"); + return original_ICorJitInfo->printFieldName(field, buffer, bufferSize, pRequiredBufferSize); } CORINFO_CLASS_HANDLE interceptor_ICJI::getFieldClass( @@ -976,12 +962,14 @@ mdMethodDef interceptor_ICJI::getMethodDefFromMethod( return original_ICorJitInfo->getMethodDefFromMethod(hMethod); } -const char* interceptor_ICJI::getMethodName( +size_t interceptor_ICJI::printMethodName( CORINFO_METHOD_HANDLE ftn, - const char** moduleName) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - mcs->AddCall("getMethodName"); - return original_ICorJitInfo->getMethodName(ftn, moduleName); + mcs->AddCall("printMethodName"); + return original_ICorJitInfo->printMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); } const char* interceptor_ICJI::getMethodNameFromMetadata( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 1e0593ec3258a..babddef2739ca 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -293,12 +293,6 @@ CorInfoType interceptor_ICJI::asCorInfoType( return original_ICorJitInfo->asCorInfoType(cls); } -const char* interceptor_ICJI::getClassName( - CORINFO_CLASS_HANDLE cls) -{ - return original_ICorJitInfo->getClassName(cls); -} - const char* interceptor_ICJI::getClassNameFromMetadata( CORINFO_CLASS_HANDLE cls, const char** namespaceName) @@ -313,15 +307,13 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::getTypeInstantiationArgument( return original_ICorJitInfo->getTypeInstantiationArgument(cls, index); } -int interceptor_ICJI::appendClassName( - char16_t** ppBuf, - int* pnBufLen, +size_t interceptor_ICJI::printClassName( CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - return original_ICorJitInfo->appendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); + return original_ICorJitInfo->printClassName(cls, buffer, bufferSize, pRequiredBufferSize); } bool interceptor_ICJI::isValueClass( @@ -515,12 +507,6 @@ void interceptor_ICJI::getReadyToRunDelegateCtorHelper( original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); } -const char* interceptor_ICJI::getHelperName( - CorInfoHelpFunc helpFunc) -{ - return original_ICorJitInfo->getHelperName(helpFunc); -} - CorInfoInitClassResult interceptor_ICJI::initClass( CORINFO_FIELD_HANDLE field, CORINFO_METHOD_HANDLE method, @@ -654,11 +640,13 @@ CorInfoIsAccessAllowedResult interceptor_ICJI::canAccessClass( return original_ICorJitInfo->canAccessClass(pResolvedToken, callerHandle, pAccessHelper); } -const char* interceptor_ICJI::getFieldName( - CORINFO_FIELD_HANDLE ftn, - const char** moduleName) +size_t interceptor_ICJI::printFieldName( + CORINFO_FIELD_HANDLE field, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - return original_ICorJitInfo->getFieldName(ftn, moduleName); + return original_ICorJitInfo->printFieldName(field, buffer, bufferSize, pRequiredBufferSize); } CORINFO_CLASS_HANDLE interceptor_ICJI::getFieldClass( @@ -854,11 +842,13 @@ mdMethodDef interceptor_ICJI::getMethodDefFromMethod( return original_ICorJitInfo->getMethodDefFromMethod(hMethod); } -const char* interceptor_ICJI::getMethodName( +size_t interceptor_ICJI::printMethodName( CORINFO_METHOD_HANDLE ftn, - const char** moduleName) + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { - return original_ICorJitInfo->getMethodName(ftn, moduleName); + return original_ICorJitInfo->printMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); } const char* interceptor_ICJI::getMethodNameFromMetadata( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index a86f7d2718424..67f57d0c73c5f 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -412,14 +412,6 @@ CorInfoType MyICJI::asCorInfoType(CORINFO_CLASS_HANDLE cls) return jitInstance->mc->repAsCorInfoType(cls); } -// for completeness -const char* MyICJI::getClassName(CORINFO_CLASS_HANDLE cls) -{ - jitInstance->mc->cr->AddCall("getClassName"); - const char* result = jitInstance->mc->repGetClassName(cls); - return result; -} - const char* MyICJI::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName) { jitInstance->mc->cr->AddCall("getClassNameFromMetadata"); @@ -434,42 +426,10 @@ CORINFO_CLASS_HANDLE MyICJI::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE c return result; } -// Append a (possibly truncated) textual representation of the type `cls` to a preallocated buffer. -// -// Arguments: -// ppBuf - Pointer to buffer pointer. See below for details. -// pnBufLen - Pointer to buffer length. Must not be nullptr. See below for details. -// fNamespace - If true, include the namespace/enclosing classes. -// fFullInst - If true (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters. -// fAssembly - If true, suffix with a comma and the full assembly qualification. -// -// Returns the length of the representation, as a count of characters (but not including a terminating null character). -// Note that this will always be the actual number of characters required by the representation, even if the string -// was truncated when copied to the buffer. -// -// Operation: -// -// On entry, `*pnBufLen` specifies the size of the buffer pointed to by `*ppBuf` as a count of characters. -// There are two cases: -// 1. If the size is zero, the function computes the length of the representation and returns that. -// `ppBuf` is ignored (and may be nullptr) and `*ppBuf` and `*pnBufLen` are not updated. -// 2. If the size is non-zero, the buffer pointed to by `*ppBuf` is (at least) that size. The class name -// representation is copied to the buffer pointed to by `*ppBuf`. As many characters of the name as will fit in the -// buffer are copied. Thus, if the name is larger than the size of the buffer, the name will be truncated in the buffer. -// The buffer is guaranteed to be null terminated. Thus, the size must be large enough to include a terminating null -// character, or the string will be truncated to include one. On exit, `*pnBufLen` is updated by subtracting the -// number of characters that were actually copied to the buffer. Also, `*ppBuf` is updated to point at the null -// character that was added to the end of the name. -// -int MyICJI::appendClassName(_Outptr_opt_result_buffer_(*pnBufLen) char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly) +size_t MyICJI::printClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - jitInstance->mc->cr->AddCall("appendClassName"); - return jitInstance->mc->repAppendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly); + jitInstance->mc->cr->AddCall("printClassName"); + return jitInstance->mc->repPrintClassName(cls, buffer, bufferSize, pRequiredBufferSize); } // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & @@ -712,12 +672,6 @@ void MyICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMeth jitInstance->mc->repGetReadyToRunDelegateCtorHelper(pTargetMethod, targetConstraint, delegateType, pLookup); } -const char* MyICJI::getHelperName(CorInfoHelpFunc funcNum) -{ - jitInstance->mc->cr->AddCall("getHelperName"); - return jitInstance->mc->repGetHelperName(funcNum); -} - // This function tries to initialize the class (run the class constructor). // this function returns whether the JIT must insert helper calls before // accessing static field or method. @@ -903,15 +857,10 @@ CorInfoIsAccessAllowedResult MyICJI::canAccessClass(CORINFO_RESOLVED_TOKEN* pRes // /**********************************************************************************/ -// this function is for debugging only. It returns the field name -// and if 'moduleName' is non-null, it sets it to something that will -// says which method (a class name, or a module name) -const char* MyICJI::getFieldName(CORINFO_FIELD_HANDLE ftn, /* IN */ - const char** moduleName /* OUT */ - ) +size_t MyICJI::printFieldName(CORINFO_FIELD_HANDLE field, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - jitInstance->mc->cr->AddCall("getFieldName"); - return jitInstance->mc->repGetFieldName(ftn, moduleName); + jitInstance->mc->cr->AddCall("printFieldName"); + return jitInstance->mc->repPrintFieldName(field, buffer, bufferSize, pRequiredBufferSize); } // return class it belongs to @@ -1265,15 +1214,10 @@ mdMethodDef MyICJI::getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) return result; } -// this function is for debugging only. It returns the method name -// and if 'moduleName' is non-null, it sets it to something that will -// says which method (a class name, or a module name) -const char* MyICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */ - const char** moduleName /* OUT */ - ) +size_t MyICJI::printMethodName(CORINFO_METHOD_HANDLE ftn, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { - jitInstance->mc->cr->AddCall("getMethodName"); - return jitInstance->mc->repGetMethodName(ftn, moduleName); + jitInstance->mc->cr->AddCall("printMethodName"); + return jitInstance->mc->repPrintMethodName(ftn, buffer, bufferSize, pRequiredBufferSize); } const char* MyICJI::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 9c8d9cbe59c0b..3c7576a8478d2 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -3417,118 +3417,107 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr } } - - /*********************************************************************/ -const char* CEEInfo::getClassName (CORINFO_CLASS_HANDLE clsHnd) +size_t CEEInfo::printClassName(CORINFO_CLASS_HANDLE cls, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { CONTRACTL { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; - MODE_PREEMPTIVE; } CONTRACTL_END; - const char* result = NULL; + size_t bytesWritten = 0; JIT_TO_EE_TRANSITION(); - TypeHandle VMClsHnd(clsHnd); - MethodTable* pMT = VMClsHnd.GetMethodTable(); - if (pMT == NULL) - { - result = ""; - } - else - { -#ifdef _DEBUG - result = pMT->GetDebugClassName(); -#else // !_DEBUG - // since this is for diagnostic purposes only, - // give up on the namespace, as we don't have a buffer to concat it - // also note this won't show array class names. - LPCUTF8 nameSpace; - result = pMT->GetFullyQualifiedNameInfo(&nameSpace); -#endif - } - - EE_TO_JIT_TRANSITION(); + size_t requiredBufferSize = 0; - return result; -} + TypeHandle th(cls); + IMDInternalImport* pImport = th.GetMethodTable()->GetMDImport(); -/***********************************************************************/ -const char* CEEInfo::getHelperName (CorInfoHelpFunc ftnNum) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - PRECONDITION(ftnNum >= 0 && ftnNum < CORINFO_HELP_COUNT); - } CONTRACTL_END; + auto append = [buffer, bufferSize, &bytesWritten, &requiredBufferSize](const char* str) + { + size_t strLen = strlen(str); - const char* result = NULL; + if ((buffer != nullptr) && (bytesWritten + 1 < bufferSize)) + { + if (bytesWritten + strLen >= bufferSize) + { + memcpy(buffer + bytesWritten, str, bufferSize - bytesWritten - 1); + bytesWritten = bufferSize - 1; + } + else + { + memcpy(buffer + bytesWritten, str, strLen); + bytesWritten += strLen; + } + } - JIT_TO_EE_TRANSITION_LEAF(); + requiredBufferSize += strLen; + }; -#ifdef _DEBUG - result = hlpFuncTable[ftnNum].name; -#else - result = "AnyJITHelper"; -#endif + // Subset of TypeString that does just what we need while staying in UTF8 + // and avoiding expensive copies. This function is called a lot in checked + // builds. + // One difference is that we do not handle escaping type names here (see + // IsTypeNameReservedChar). The situation is rare and somewhat complicated + // to handle since it requires iterating UTF8 encoded codepoints. Given + // that this function is only needed for diagnostics the complication seems + // unnecessary. + mdTypeDef td = th.GetCl(); + if (IsNilToken(td)) + { + append("(dynamicClass)"); + } + else + { + DWORD attr; + IfFailThrow(pImport->GetTypeDefProps(td, &attr, NULL)); - EE_TO_JIT_TRANSITION_LEAF(); + StackSArray nestedHierarchy; + nestedHierarchy.Append(td); - return result; -} + if (IsTdNested(attr)) + { + while (SUCCEEDED(pImport->GetNestedClassProps(td, &td))) + nestedHierarchy.Append(td); + } + for (SCOUNT_T i = nestedHierarchy.GetCount() - 1; i >= 0; i--) + { + LPCUTF8 name; + LPCUTF8 nameSpace; + IfFailThrow(pImport->GetNameOfTypeDef(nestedHierarchy[i], &name, &nameSpace)); -/*********************************************************************/ -int CEEInfo::appendClassName(_Outptr_opt_result_buffer_(*pnBufLen) char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE clsHnd, - bool fNamespace, - bool fFullInst, - bool fAssembly) -{ - CONTRACTL { - MODE_PREEMPTIVE; - THROWS; - GC_TRIGGERS; - } CONTRACTL_END; + if ((nameSpace != NULL) && (*nameSpace != '\0')) + { + append(nameSpace); + append("."); + } - int nLen = 0; + append(name); - JIT_TO_EE_TRANSITION(); + if (i != 0) + { + append("+"); + } + } + } - TypeHandle th(clsHnd); - StackSString ss; - TypeString::AppendType(ss,th, - (fNamespace ? TypeString::FormatNamespace : 0) | - (fFullInst ? TypeString::FormatFullInst : 0) | - (fAssembly ? TypeString::FormatAssembly : 0)); - const WCHAR* szString = ss.GetUnicode(); - nLen = (int)wcslen(szString); - if (*pnBufLen > 0) + if (bufferSize > 0) { - // Copy as much as will fit. - WCHAR* pBuf = (WCHAR*)*ppBuf; - int nLenToCopy = min(*pnBufLen, nLen + /* null terminator */ 1); - for (int i = 0; i < nLenToCopy - 1; i++) - { - pBuf[i] = szString[i]; - } - pBuf[nLenToCopy - 1] = 0; // null terminate the string if it wasn't already + _ASSERTE(bytesWritten < bufferSize); + buffer[bytesWritten] = '\0'; + } - // Update the buffer pointer and buffer size pointer based on the amount actually copied. - // Don't include the null terminator. `*ppBuf` will point at the added null terminator. - (*ppBuf) += nLenToCopy - 1; - (*pnBufLen) -= nLenToCopy - 1; + if (pRequiredBufferSize != nullptr) + { + *pRequiredBufferSize = requiredBufferSize + 1; } EE_TO_JIT_TRANSITION(); - // Return the actual length of the string, not including the null terminator. - return nLen; + return bytesWritten; } /*********************************************************************/ @@ -6349,83 +6338,37 @@ unsigned CEEInfo::getMethodHash (CORINFO_METHOD_HANDLE ftnHnd) } /***********************************************************************/ -const char* CEEInfo::getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) +size_t CEEInfo::printMethodName(CORINFO_METHOD_HANDLE ftnHnd, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_PREEMPTIVE; } CONTRACTL_END; - const char* result = NULL; + size_t bytesWritten = 0; JIT_TO_EE_TRANSITION(); - MethodDesc *ftn; - - ftn = GetMethod(ftnHnd); + MethodDesc* ftn = GetMethod(ftnHnd); + const char* ftnName = ftn->GetName(); - if (scopeName != 0) + size_t len = strlen(ftnName); + if (bufferSize > 0) { - if (ftn->IsLCGMethod()) - { - *scopeName = "DynamicClass"; - } - else if (ftn->IsILStub()) - { - *scopeName = ILStubResolver::GetStubClassName(ftn); - } - else - { - MethodTable * pMT = ftn->GetMethodTable(); -#if defined(_DEBUG) -#ifdef FEATURE_SYMDIFF - if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SymDiffDump)) - { - if (pMT->IsArray()) - { - ssClsNameBuff.Clear(); - ssClsNameBuff.SetUTF8(pMT->GetDebugClassName()); - } - else - pMT->_GetFullyQualifiedNameForClassNestedAware(ssClsNameBuff); - } - else - { -#endif - // Calling _GetFullyQualifiedNameForClass in chk build is very expensive - // since it construct the class name everytime we call this method. In chk - // builds we already have a cheaper way to get the class name - - // GetDebugClassName - which doesn't calculate the class name everytime. - // This results in huge saving in Ngen time for checked builds. - ssClsNameBuff.Clear(); - ssClsNameBuff.SetUTF8(pMT->GetDebugClassName()); - -#ifdef FEATURE_SYMDIFF - } -#endif - // Append generic instantiation at the end - Instantiation inst = pMT->GetInstantiation(); - if (!inst.IsEmpty()) - TypeString::AppendInst(ssClsNameBuff, inst); - - ssClsNameBuffUTF8.SetAndConvertToUTF8(ssClsNameBuff.GetUnicode()); - *scopeName = ssClsNameBuffUTF8.GetUTF8(); -#else // !_DEBUG - // since this is for diagnostic purposes only, - // give up on the namespace, as we don't have a buffer to concat it - // also note this won't show array class names. - LPCUTF8 nameSpace; - *scopeName= pMT->GetFullyQualifiedNameInfo(&nameSpace); -#endif // !_DEBUG - } + bytesWritten = min(len, bufferSize - 1); + memcpy(buffer, ftnName, bytesWritten); + buffer[bytesWritten] = '\0'; } - result = ftn->GetName(); + if (pRequiredBufferSize != NULL) + { + *pRequiredBufferSize = len + 1; + } EE_TO_JIT_TRANSITION(); - return result; + return bytesWritten; } const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd, const char** className, const char** namespaceName, const char **enclosingClassName) @@ -9298,44 +9241,36 @@ void CEEInfo::getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, } /*********************************************************************/ -const char* CEEInfo::getFieldName (CORINFO_FIELD_HANDLE fieldHnd, const char** scopeName) +size_t CEEInfo::printFieldName(CORINFO_FIELD_HANDLE fieldHnd, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_PREEMPTIVE; } CONTRACTL_END; - const char* result = NULL; - + size_t bytesWritten = 0; JIT_TO_EE_TRANSITION(); FieldDesc* field = (FieldDesc*) fieldHnd; - if (scopeName != 0) + const char* fieldName = field->GetName(); + + size_t len = strlen(fieldName); + if (bufferSize > 0) { - TypeHandle t = TypeHandle(field->GetApproxEnclosingMethodTable()); - *scopeName = ""; - if (!t.IsNull()) - { -#ifdef _DEBUG - t.GetName(ssClsNameBuff); - ssClsNameBuffUTF8.SetAndConvertToUTF8(ssClsNameBuff.GetUnicode()); - *scopeName = ssClsNameBuffUTF8.GetUTF8(); -#else // !_DEBUG - // since this is for diagnostic purposes only, - // give up on the namespace, as we don't have a buffer to concat it - // also note this won't show array class names. - LPCUTF8 nameSpace; - *scopeName= t.GetMethodTable()->GetFullyQualifiedNameInfo(&nameSpace); -#endif // !_DEBUG - } + bytesWritten = min(len, bufferSize - 1); + memcpy(buffer, fieldName, len); + buffer[bytesWritten] = '\0'; } - result = field->GetName(); + if (pRequiredBufferSize != NULL) + { + *pRequiredBufferSize = len + 1; + } EE_TO_JIT_TRANSITION(); - return result; + return bytesWritten; } /*********************************************************************/