Skip to content

Commit

Permalink
Make JIT<->EE printing methods consistent and support nested classes …
Browse files Browse the repository at this point in the history
…when printing class names (#76505)

* Switch `appendClassName`/`getClassName`, `getFieldName` and `getMethodName` into respectively `printClassName`, `printFieldName` and `printMethodName` that all are consistent with `printObjectDescription` in buffer handling, and all use UTF8

* Change `printClassName` to support nested classes, fixing the handling of these in the JIT (in particular for method sets)

* Factor handling in SPMI/ILC/crossgen2 for these methods now that they are consistent

* Add a JitTypeNameFormatter.cs for crossgen2/ILC that does exactly what `printClassName` needs to be consistent with the VM

* Remove concept of "native" `CORINFO_METHOD_HANDLE` (`eeMarkNativeTarget` and co.). This was unused before.

* Remove `CEEInfo::getHelperName`. We were keeping a list of this in the JIT anyway under `FEATURE_SIMD`, which is defined practically everywhere.

* Remove `includeNamespaces` in JIT printing that was always passed as `true`

* Change the `hackishX` names on missing SPMI data into `<unknown X>` instead, e.g. `<unknown method>`
  • Loading branch information
jakobbotsch authored Nov 20, 2022
1 parent 5c420f1 commit df00d19
Show file tree
Hide file tree
Showing 53 changed files with 1,248 additions and 1,780 deletions.
23 changes: 9 additions & 14 deletions src/coreclr/gcinfo/gcinfoencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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


///////////////////////////////////////////////////////////////////////
Expand Down
105 changes: 37 additions & 68 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 (
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/inc/gcinfoencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 13 additions & 17 deletions src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit df00d19

Please sign in to comment.