diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 7a76372184007..4958de749672e 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -1056,6 +1056,7 @@ typedef struct CORINFO_DEPENDENCY_STRUCT_* CORINFO_DEPENDENCY_HANDLE; typedef struct CORINFO_CLASS_STRUCT_* CORINFO_CLASS_HANDLE; typedef struct CORINFO_METHOD_STRUCT_* CORINFO_METHOD_HANDLE; typedef struct CORINFO_FIELD_STRUCT_* CORINFO_FIELD_HANDLE; +typedef struct CORINFO_OBJECT_STRUCT_* CORINFO_OBJECT_HANDLE; typedef struct CORINFO_ARG_LIST_STRUCT_* CORINFO_ARG_LIST_HANDLE; // represents a list of argument types typedef struct CORINFO_JUST_MY_CODE_HANDLE_*CORINFO_JUST_MY_CODE_HANDLE; typedef struct CORINFO_PROFILING_STRUCT_* CORINFO_PROFILING_HANDLE; // a handle guaranteed to be unique per process @@ -2284,7 +2285,7 @@ class ICorStaticInfo // Bytes written to the given buffer, the range is [0..bufferSize) // virtual size_t printObjectDescription ( - void* handle, /* IN */ + CORINFO_OBJECT_HANDLE handle, /* IN */ char* buffer, /* OUT */ size_t bufferSize, /* IN */ size_t* pRequiredBufferSize = nullptr /* OUT */ @@ -2500,7 +2501,7 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls ) = 0; - virtual void* getRuntimeTypePointer( + virtual CORINFO_OBJECT_HANDLE getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls ) = 0; @@ -2514,7 +2515,7 @@ class ICorStaticInfo // Returns true if object is known to be immutable // virtual bool isObjectImmutable( - void* objPtr + CORINFO_OBJECT_HANDLE objPtr ) = 0; //------------------------------------------------------------------------------ @@ -2527,7 +2528,7 @@ class ICorStaticInfo // Returns CORINFO_CLASS_HANDLE handle that represents given object's type // virtual CORINFO_CLASS_HANDLE getObjectType( - void* objPtr + CORINFO_OBJECT_HANDLE objPtr ) = 0; virtual bool getReadyToRunHelper( @@ -2729,6 +2730,8 @@ class ICorStaticInfo // Returns true iff "fldHnd" represents a static field. virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0; + virtual int getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) = 0; + /*********************************************************************************/ // // ICorDebugInfo @@ -3196,15 +3199,13 @@ class ICorDynamicInfo : public ICorStaticInfo //------------------------------------------------------------------------------ // getReadonlyStaticFieldValue: returns true and the actual field's value if the given - // field represents a statically initialized readonly field of any type, it might be: - // * integer/floating point primitive - // * null - // * frozen object reference (string, array or object) + // field represents a statically initialized readonly field of any type. // // Arguments: - // field - field handle - // buffer - buffer field's value will be stored to - // bufferSize - size of buffer + // field - field handle + // buffer - buffer field's value will be stored to + // bufferSize - size of buffer + // ignoreMovableObjects - ignore movable reference types or not // // Return Value: // Returns true if field's constant value was available and successfully copied to buffer @@ -3212,7 +3213,8 @@ class ICorDynamicInfo : public ICorStaticInfo virtual bool getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t *buffer, - int bufferSize + int bufferSize, + bool ignoreMovableObjects = true ) = 0; // If pIsSpeculative is NULL, return the class handle for the value of ref-class typed diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index ec0d19a4c7972..44c98ae5397f5 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -177,7 +177,7 @@ int getStringLiteral( int startIndex) override; size_t printObjectDescription( - void* handle, + CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) override; @@ -287,14 +287,14 @@ CorInfoHelpFunc getBoxHelper( CorInfoHelpFunc getUnBoxHelper( CORINFO_CLASS_HANDLE cls) override; -void* getRuntimeTypePointer( +CORINFO_OBJECT_HANDLE getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls) override; bool isObjectImmutable( - void* objPtr) override; + CORINFO_OBJECT_HANDLE objPtr) override; CORINFO_CLASS_HANDLE getObjectType( - void* objPtr) override; + CORINFO_OBJECT_HANDLE objPtr) override; bool getReadyToRunHelper( CORINFO_RESOLVED_TOKEN* pResolvedToken, @@ -404,6 +404,9 @@ void getFieldInfo( bool isFieldStatic( CORINFO_FIELD_HANDLE fldHnd) override; +int getArrayOrStringLength( + CORINFO_OBJECT_HANDLE objHnd) override; + void getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, @@ -616,7 +619,8 @@ void* getFieldAddress( bool getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t* buffer, - int bufferSize) override; + int bufferSize, + bool ignoreMovableObjects) override; CORINFO_CLASS_HANDLE getStaticFieldCurrentClass( CORINFO_FIELD_HANDLE field, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 90c5520ebfed6..2f1bb07461e18 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 = { /* 2ed4cd12-48ed-4a0e-892e-d24d004a5e4c */ - 0x2ed4cd12, - 0x48ed, - 0x4a0e, - {0x89, 0x2e, 0xd2, 0x4d, 0x00, 0x4a, 0x5e, 0x4c} +constexpr GUID JITEEVersionIdentifier = { /* 77b6df16-d27f-4118-9dfd-d8073ff20fb6 */ + 0x77b6df16, + 0xd27f, + 0x4118, + {0x9d, 0xfd, 0xd8, 0x7, 0x3f, 0xf2, 0xf, 0xb6} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index ed9a2be8c8d72..8c43eb4823aef 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -102,6 +102,7 @@ DEF_CLR_API(getFieldType) DEF_CLR_API(getFieldOffset) DEF_CLR_API(getFieldInfo) DEF_CLR_API(isFieldStatic) +DEF_CLR_API(getArrayOrStringLength) DEF_CLR_API(getBoundaries) DEF_CLR_API(setBoundaries) DEF_CLR_API(getVars) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 38179829a21ae..057f5ba417759 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -376,7 +376,7 @@ int WrapICorJitInfo::getStringLiteral( } size_t WrapICorJitInfo::printObjectDescription( - void* handle, + CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) @@ -665,17 +665,17 @@ CorInfoHelpFunc WrapICorJitInfo::getUnBoxHelper( return temp; } -void* WrapICorJitInfo::getRuntimeTypePointer( +CORINFO_OBJECT_HANDLE WrapICorJitInfo::getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls) { API_ENTER(getRuntimeTypePointer); - void* temp = wrapHnd->getRuntimeTypePointer(cls); + CORINFO_OBJECT_HANDLE temp = wrapHnd->getRuntimeTypePointer(cls); API_LEAVE(getRuntimeTypePointer); return temp; } bool WrapICorJitInfo::isObjectImmutable( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { API_ENTER(isObjectImmutable); bool temp = wrapHnd->isObjectImmutable(objPtr); @@ -684,7 +684,7 @@ bool WrapICorJitInfo::isObjectImmutable( } CORINFO_CLASS_HANDLE WrapICorJitInfo::getObjectType( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { API_ENTER(getObjectType); CORINFO_CLASS_HANDLE temp = wrapHnd->getObjectType(objPtr); @@ -965,6 +965,15 @@ bool WrapICorJitInfo::isFieldStatic( return temp; } +int WrapICorJitInfo::getArrayOrStringLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + API_ENTER(getArrayOrStringLength); + int temp = wrapHnd->getArrayOrStringLength(objHnd); + API_LEAVE(getArrayOrStringLength); + return temp; +} + void WrapICorJitInfo::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, @@ -1473,10 +1482,11 @@ void* WrapICorJitInfo::getFieldAddress( bool WrapICorJitInfo::getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t* buffer, - int bufferSize) + int bufferSize, + bool ignoreMovableObjects) { API_ENTER(getReadonlyStaticFieldValue); - bool temp = wrapHnd->getReadonlyStaticFieldValue(field, buffer, bufferSize); + bool temp = wrapHnd->getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects); API_LEAVE(getReadonlyStaticFieldValue); return temp; } diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index d460496996bd4..9a4be3c6e4e9e 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -6097,6 +6097,7 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Sta case GT_NEG: case GT_CAST: case GT_INTRINSIC: + case GT_ARR_LENGTH: break; case GT_IND: diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index fb41d21c86217..ba397513b6005 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7778,7 +7778,7 @@ class Compiler const char* eeGetFieldName(CORINFO_FIELD_HANDLE fieldHnd, const char** classNamePtr = nullptr); #if defined(DEBUG) - void eePrintObjectDescriptionDescription(const char* prefix, size_t handle); + void eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle); unsigned eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd); const char16_t* eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd); #endif diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index f05753ab41bf9..1b8dd208aa7c2 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -1616,7 +1616,7 @@ const char16_t* Compiler::eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd) return param.classNameWidePtr; } -void Compiler::eePrintObjectDescriptionDescription(const char* prefix, size_t handle) +void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle) { const size_t maxStrSize = 64; char str[maxStrSize]; @@ -1624,7 +1624,7 @@ void Compiler::eePrintObjectDescriptionDescription(const char* prefix, size_t ha // Ignore potential SPMI failures bool success = eeRunFunctorWithSPMIErrorTrap( - [&]() { actualLen = this->info.compCompHnd->printObjectDescription((void*)handle, str, maxStrSize); }); + [&]() { actualLen = this->info.compCompHnd->printObjectDescription(handle, str, maxStrSize); }); if (!success) { diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index f27c4302fe4e1..a7644c3bcbd0f 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -4135,7 +4135,7 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag else if (flag == GTF_ICON_OBJ_HDL) { #ifdef DEBUG - emitComp->eePrintObjectDescriptionDescription(commentPrefix, handle); + emitComp->eePrintObjectDescription(commentPrefix, (CORINFO_OBJECT_HANDLE)handle); #else str = "frozen object handle"; #endif diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 2c4c10fae8fa1..eefcf1d9364bc 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -11134,7 +11134,7 @@ void Compiler::gtDispConst(GenTree* tree) } else if (tree->IsIconHandle(GTF_ICON_OBJ_HDL)) { - eePrintObjectDescriptionDescription(" ", tree->AsIntCon()->gtIconVal); + eePrintObjectDescription(" ", (CORINFO_OBJECT_HANDLE)tree->AsIntCon()->gtIconVal); } else { @@ -17619,7 +17619,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { if (tree->IsIconHandle(GTF_ICON_OBJ_HDL)) { - objClass = info.compCompHnd->getObjectType((void*)tree->AsIntCon()->IconValue()); + objClass = info.compCompHnd->getObjectType((CORINFO_OBJECT_HANDLE)tree->AsIntCon()->IconValue()); if (objClass != NO_CLASS_HANDLE) { // if we managed to get a class handle it's definitely not null diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 644cdd9c993d9..8b508e405a279 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4344,7 +4344,7 @@ GenTree* Compiler::impImportCnsTreeFromBuffer(uint8_t* buffer, var_types valueTy } case TYP_REF: { - void* ptr; + size_t ptr; memcpy(&ptr, buffer, sizeof(ssize_t)); if (ptr == 0) @@ -4354,9 +4354,9 @@ GenTree* Compiler::impImportCnsTreeFromBuffer(uint8_t* buffer, var_types valueTy else { setMethodHasFrozenObjects(); - tree = gtNewIconEmbHndNode(ptr, nullptr, GTF_ICON_OBJ_HDL, nullptr); + tree = gtNewIconEmbHndNode((void*)ptr, nullptr, GTF_ICON_OBJ_HDL, nullptr); tree->gtType = TYP_REF; - INDEBUG(tree->AsIntCon()->gtTargetHandle = (size_t)ptr); + INDEBUG(tree->AsIntCon()->gtTargetHandle = ptr); } break; } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 6e75c957486c9..4a20bac071333 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7180,7 +7180,7 @@ void Lowering::LowerStoreIndirCommon(GenTreeStoreInd* ind) if (ind->Data()->IsIconHandle(GTF_ICON_OBJ_HDL)) { const ssize_t handle = ind->Data()->AsIntCon()->IconValue(); - if (!comp->info.compCompHnd->isObjectImmutable(reinterpret_cast(handle))) + if (!comp->info.compCompHnd->isObjectImmutable(reinterpret_cast(handle))) { // On platforms with weaker memory model we need to make sure we use a store with the release semantic // when we publish a potentially mutable object diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 8f7211b88edc0..dcefa8725be36 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -8218,11 +8218,11 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) CORINFO_CLASS_HANDLE hClass = gtGetHelperArgClassHandle(argNode); if ((hClass != NO_CLASS_HANDLE) && !gtIsActiveCSE_Candidate(argNode)) { - void* ptr = info.compCompHnd->getRuntimeTypePointer(hClass); - if (ptr != nullptr) + CORINFO_OBJECT_HANDLE ptr = info.compCompHnd->getRuntimeTypePointer(hClass); + if (ptr != NULL) { setMethodHasFrozenObjects(); - GenTree* retNode = gtNewIconEmbHndNode(ptr, nullptr, GTF_ICON_OBJ_HDL, nullptr); + GenTree* retNode = gtNewIconEmbHndNode((void*)ptr, nullptr, GTF_ICON_OBJ_HDL, nullptr); retNode->gtType = TYP_REF; INDEBUG(retNode->AsIntCon()->gtTargetHandle = (size_t)ptr); return fgMorphTree(retNode); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index f638cd51afde0..11ffa8951c7ea 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2083,9 +2083,58 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) } else { + // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable) + if (func == VNFunc(GT_ARR_LENGTH)) + { + // Case 1: ARR_LENGTH(FROZEN_OBJ) + ValueNum addressVN = VNNormalValue(arg0VN); + if (IsVNHandle(addressVN) && (GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) + { + size_t handle = CoercedConstantValue(addressVN); + int len = m_pComp->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); + if (len >= 0) + { + resultVN = VNForIntCon(len); + } + } + + // Case 2: ARR_LENGTH(static-readonly-field) + VNFuncApp funcApp; + if ((resultVN == NoVN) && GetVNFunc(addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad)) + { + ValueNum fieldSeqVN = VNNormalValue(funcApp.m_args[0]); + if (IsVNHandle(fieldSeqVN) && (GetHandleFlags(fieldSeqVN) == GTF_ICON_FIELD_SEQ)) + { + FieldSeq* fieldSeq = FieldSeqVNToFieldSeq(fieldSeqVN); + if (fieldSeq != nullptr) + { + CORINFO_FIELD_HANDLE field = fieldSeq->GetFieldHandle(); + if (field != NULL) + { + uint8_t buffer[TARGET_POINTER_SIZE] = {0}; + if (m_pComp->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, + TARGET_POINTER_SIZE, false)) + { + // In case of 64bit jit emitting 32bit codegen this handle will be 64bit + // value holding 32bit handle with upper half zeroed (hence, "= NULL"). + // It's done to match the current crossgen/ILC behavior. + CORINFO_OBJECT_HANDLE objHandle = NULL; + memcpy(&objHandle, buffer, TARGET_POINTER_SIZE); + int len = m_pComp->info.compCompHnd->getArrayOrStringLength(objHandle); + if (len >= 0) + { + resultVN = VNForIntCon(len); + } + } + } + } + } + } + } + // Try to perform constant-folding. // - if (VNEvalCanFoldUnaryFunc(typ, func, arg0VN)) + if ((resultVN == NoVN) && VNEvalCanFoldUnaryFunc(typ, func, arg0VN)) { resultVN = EvalFuncForConstantArgs(typ, func, arg0VN); } @@ -8700,6 +8749,15 @@ void Compiler::fgValueNumberTree(GenTree* tree) VNFunc loadFunc = ((tree->gtFlags & GTF_IND_NONNULL) != 0) ? VNF_InvariantNonNullLoad : VNF_InvariantLoad; + // Special case: for initialized non-null 'static readonly' fields we want to keep field + // sequence to be able to fold their value + if ((loadFunc == VNF_InvariantNonNullLoad) && addr->IsIconHandle(GTF_ICON_CONST_PTR) && + (addr->AsIntCon()->gtFieldSeq != nullptr) && + (addr->AsIntCon()->gtFieldSeq->GetOffset() == addr->AsIntCon()->IconValue())) + { + addrNvnp.SetBoth(vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq)); + } + tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), loadFunc, addrNvnp); tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp); } @@ -8797,7 +8855,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) { if (tree->AsOp()->gtOp1 != nullptr) { - if (tree->OperGet() == GT_NOP) + if (tree->OperIs(GT_NOP)) { // Pass through arg vn. tree->gtVNPair = tree->AsOp()->gtOp1->gtVNPair; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index a5c324a33fada..376de7408b6bb 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1859,7 +1859,7 @@ private int getStringLiteral(CORINFO_MODULE_STRUCT_* module, uint metaTOK, char* return result; } - private nuint printObjectDescription(void* handle, byte* buffer, nuint bufferSize, nuint* pRequiredBufferSize) + private nuint printObjectDescription(CORINFO_OBJECT_STRUCT_* handle, byte* buffer, nuint bufferSize, nuint* pRequiredBufferSize) { Debug.Assert(bufferSize > 0 && handle != null && buffer != null); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 048c6bf00fbe3..4b830673d4a8c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -554,7 +554,7 @@ private static int _getStringLiteral(IntPtr thisHandle, IntPtr* ppException, COR } [UnmanagedCallersOnly] - private static UIntPtr _printObjectDescription(IntPtr thisHandle, IntPtr* ppException, void* handle, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) + private static UIntPtr _printObjectDescription(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* handle, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) { var _this = GetThis(thisHandle); try @@ -1003,7 +1003,7 @@ private static CorInfoHelpFunc _getUnBoxHelper(IntPtr thisHandle, IntPtr* ppExce } [UnmanagedCallersOnly] - private static void* _getRuntimeTypePointer(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) + private static CORINFO_OBJECT_STRUCT_* _getRuntimeTypePointer(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { var _this = GetThis(thisHandle); try @@ -1018,7 +1018,7 @@ private static CorInfoHelpFunc _getUnBoxHelper(IntPtr thisHandle, IntPtr* ppExce } [UnmanagedCallersOnly] - private static byte _isObjectImmutable(IntPtr thisHandle, IntPtr* ppException, void* objPtr) + private static byte _isObjectImmutable(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objPtr) { var _this = GetThis(thisHandle); try @@ -1033,7 +1033,7 @@ private static byte _isObjectImmutable(IntPtr thisHandle, IntPtr* ppException, v } [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getObjectType(IntPtr thisHandle, IntPtr* ppException, void* objPtr) + private static CORINFO_CLASS_STRUCT_* _getObjectType(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objPtr) { var _this = GetThis(thisHandle); try @@ -1464,6 +1464,21 @@ private static byte _isFieldStatic(IntPtr thisHandle, IntPtr* ppException, CORIN } } + [UnmanagedCallersOnly] + private static int _getArrayOrStringLength(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objHnd) + { + var _this = GetThis(thisHandle); + try + { + return _this.getArrayOrStringLength(objHnd); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] private static void _getBoundaries(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint* cILOffsets, uint** pILOffsets, BoundaryTypes* implicitBoundaries) { @@ -2229,12 +2244,12 @@ private static uint _getClassDomainID(IntPtr thisHandle, IntPtr* ppException, CO } [UnmanagedCallersOnly] - private static byte _getReadonlyStaticFieldValue(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, int bufferSize) + private static byte _getReadonlyStaticFieldValue(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, int bufferSize, byte ignoreMovableObjects) { var _this = GetThis(thisHandle); try { - return _this.getReadonlyStaticFieldValue(field, buffer, bufferSize) ? (byte)1 : (byte)0; + return _this.getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects != 0) ? (byte)1 : (byte)0; } catch (Exception ex) { @@ -2670,7 +2685,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 180); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 181); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2709,7 +2724,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[34] = (delegate* unmanaged)&_isValidToken; callbacks[35] = (delegate* unmanaged)&_isValidStringRef; callbacks[36] = (delegate* unmanaged)&_getStringLiteral; - callbacks[37] = (delegate* unmanaged)&_printObjectDescription; + callbacks[37] = (delegate* unmanaged)&_printObjectDescription; callbacks[38] = (delegate* unmanaged)&_asCorInfoType; callbacks[39] = (delegate* unmanaged)&_getClassName; callbacks[40] = (delegate* unmanaged)&_getClassNameFromMetadata; @@ -2739,9 +2754,9 @@ private static IntPtr GetUnmanagedCallbacks() 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[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; @@ -2770,88 +2785,89 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[95] = (delegate* unmanaged)&_getFieldOffset; callbacks[96] = (delegate* unmanaged)&_getFieldInfo; callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - 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)&_getMethodName; - 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; + callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[99] = (delegate* unmanaged)&_getBoundaries; + callbacks[100] = (delegate* unmanaged)&_setBoundaries; + callbacks[101] = (delegate* unmanaged)&_getVars; + callbacks[102] = (delegate* unmanaged)&_setVars; + callbacks[103] = (delegate* unmanaged)&_reportRichMappings; + callbacks[104] = (delegate* unmanaged)&_allocateArray; + callbacks[105] = (delegate* unmanaged)&_freeArray; + callbacks[106] = (delegate* unmanaged)&_getArgNext; + callbacks[107] = (delegate* unmanaged)&_getArgType; + callbacks[108] = (delegate* unmanaged)&_getExactClasses; + callbacks[109] = (delegate* unmanaged)&_getArgClass; + callbacks[110] = (delegate* unmanaged)&_getHFAType; + callbacks[111] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[112] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[113] = (delegate* unmanaged)&_FilterException; + callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[116] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[117] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[118] = (delegate* unmanaged)&_getEEInfo; + callbacks[119] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[120] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[121] = (delegate* unmanaged)&_getMethodName; + callbacks[122] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[123] = (delegate* unmanaged)&_getMethodHash; + callbacks[124] = (delegate* unmanaged)&_findNameOfToken; + callbacks[125] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[126] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[127] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[128] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[129] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[130] = (delegate* unmanaged)&_getHelperFtn; + callbacks[131] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[132] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[133] = (delegate* unmanaged)&_getMethodSync; + callbacks[134] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[135] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[136] = (delegate* unmanaged)&_embedClassHandle; + callbacks[137] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[138] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[139] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[140] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[141] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[142] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[146] = (delegate* unmanaged)&_getCallInfo; + callbacks[147] = (delegate* unmanaged)&_canAccessFamily; + callbacks[148] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[149] = (delegate* unmanaged)&_getClassDomainID; + callbacks[150] = (delegate* unmanaged)&_getFieldAddress; + callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[152] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[153] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[154] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[155] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[156] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[157] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[158] = (delegate* unmanaged)&_addActiveDependency; + callbacks[159] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[160] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[161] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[162] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[163] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[164] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[165] = (delegate* unmanaged)&_allocMem; + callbacks[166] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[167] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[168] = (delegate* unmanaged)&_allocGCInfo; + callbacks[169] = (delegate* unmanaged)&_setEHcount; + callbacks[170] = (delegate* unmanaged)&_setEHinfo; + callbacks[171] = (delegate* unmanaged)&_logMsg; + callbacks[172] = (delegate* unmanaged)&_doAssert; + callbacks[173] = (delegate* unmanaged)&_reportFatalError; + callbacks[174] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[175] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[176] = (delegate* unmanaged)&_recordCallSite; + callbacks[177] = (delegate* unmanaged)&_recordRelocation; + callbacks[178] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[179] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[180] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 66fac586cb31a..7e102d47f02a7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -32,6 +32,10 @@ public struct CORINFO_FIELD_STRUCT_ { } + public struct CORINFO_OBJECT_STRUCT_ + { + } + public struct CORINFO_CLASS_STRUCT_ { } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 61f5fa42e2ec0..e120cacc136f6 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -134,6 +134,7 @@ ICorJitInfo::PgoSource*, ref PgoSource CORINFO_MODULE_HANDLE,CORINFO_MODULE_STRUCT_* CORINFO_METHOD_HANDLE,CORINFO_METHOD_STRUCT_* CORINFO_FIELD_HANDLE,CORINFO_FIELD_STRUCT_* +CORINFO_OBJECT_HANDLE,CORINFO_OBJECT_STRUCT_* CORINFO_CLASS_HANDLE,CORINFO_CLASS_STRUCT_* CORINFO_ASSEMBLY_HANDLE,CORINFO_ASSEMBLY_STRUCT_* CORINFO_JUST_MY_CODE_HANDLE,CORINFO_JUST_MY_CODE_HANDLE_* @@ -192,7 +193,7 @@ FUNCTIONS bool isValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK) bool isValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK) int getStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex) - size_t printObjectDescription(void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) + 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) @@ -222,9 +223,9 @@ FUNCTIONS CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls) - void* getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) - bool isObjectImmutable(void* objPtr) - CORINFO_CLASS_HANDLE getObjectType(void* objPtr) + CORINFO_OBJECT_HANDLE getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) + bool isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) + 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) @@ -253,6 +254,7 @@ FUNCTIONS unsigned getFieldOffset(CORINFO_FIELD_HANDLE field) void getFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_ACCESS_FLAGS flags, CORINFO_FIELD_INFO* pResult) bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) + int getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) void getBoundaries(CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, uint32_t** pILOffsets, ICorDebugInfo::BoundaryTypes* implicitBoundaries) void setBoundaries(CORINFO_METHOD_HANDLE ftn, uint32_t cMap, ICorDebugInfo::OffsetMapping* pMap) void getVars(CORINFO_METHOD_HANDLE ftn, uint32_t* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers) @@ -305,7 +307,7 @@ FUNCTIONS bool isRIDClassDomainID(CORINFO_CLASS_HANDLE cls); unsigned getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection); void* getFieldAddress(CORINFO_FIELD_HANDLE field, VOIDSTARSTAR ppIndirection); - bool getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize); + bool getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t *buffer, int bufferSize, bool ignoreMovableObjects); CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, BoolStar pIsSpeculative); CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *pSig, void **ppIndirection); bool canGetVarArgsHandle(CORINFO_SIG_INFO *pSig); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs index bc863631e8818..21bc5dda0b908 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; - +using System.Diagnostics; using Internal.Text; using Internal.TypeSystem; @@ -39,6 +39,12 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) public bool IsKnownImmutable => _data.IsKnownImmutable; + public int GetArrayLength() + { + Debug.Assert(ObjectType.IsArray); + return _data.ArrayLength; + } + int ISymbolNode.Offset => 0; int ISymbolDefinitionNode.Offset diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs index d1978383f236b..0f155245303e5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs @@ -105,6 +105,8 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer return string.CompareOrdinal(_data, ((FrozenStringNode)other)._data); } + public string Data => _data; + public override string ToString() => $"\"{_data}\""; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index 24cfdac46c01a..87b93cd8e8f2e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -1716,6 +1716,7 @@ public interface ISerializableReference : ISerializableValue TypeDesc Type { get; } void WriteContent(ref ObjectDataBuilder builder, ISymbolNode thisNode, NodeFactory factory); bool IsKnownImmutable { get; } + int ArrayLength { get; } } /// @@ -2137,6 +2138,8 @@ public override void WriteFieldData(ref ObjectDataBuilder builder, NodeFactory f } public bool IsKnownImmutable => _methodPointed.Signature.IsStatic; + + public int ArrayLength => throw new NotSupportedException(); } #pragma warning disable CA1852 @@ -2227,6 +2230,8 @@ public virtual void WriteContent(ref ObjectDataBuilder builder, ISymbolNode this } public bool IsKnownImmutable => _elementCount == 0; + + public int ArrayLength => Length; } private sealed class ForeignTypeInstance : AllocatedReferenceTypeValue @@ -2348,6 +2353,8 @@ public virtual void WriteContent(ref ObjectDataBuilder builder, ISymbolNode this } public bool IsKnownImmutable => !Type.GetFields().GetEnumerator().MoveNext(); + + public int ArrayLength => throw new NotSupportedException(); } private struct FieldAccessor diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index c70e19a81eda2..974590abe9eba 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2997,24 +2997,29 @@ private int getExactClasses(CORINFO_CLASS_STRUCT_* baseType, int maxExactClasses return 0; } - private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize) + private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, bool ignoreMovableObjects) { return false; } - private CORINFO_CLASS_STRUCT_* getObjectType(void* objPtr) + private CORINFO_CLASS_STRUCT_* getObjectType(CORINFO_OBJECT_STRUCT_* objPtr) { throw new NotSupportedException(); } - private bool isObjectImmutable(void* objPtr) + private bool isObjectImmutable(CORINFO_OBJECT_STRUCT_* objPtr) { throw new NotSupportedException(); } - private void* getRuntimeTypePointer(CORINFO_CLASS_STRUCT_* cls) + private CORINFO_OBJECT_STRUCT_* getRuntimeTypePointer(CORINFO_CLASS_STRUCT_* cls) { return null; } + + private int getArrayOrStringLength(CORINFO_OBJECT_STRUCT_* objHnd) + { + return -1; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index bd923c96617e4..5fa43d0d527bc 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2212,7 +2212,7 @@ private int getExactClasses(CORINFO_CLASS_STRUCT_* baseType, int maxExactClasses return index; } - private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize) + private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buffer, int bufferSize, bool ignoreMovableObjects) { Debug.Assert(fieldHandle != null); Debug.Assert(buffer != null); @@ -2265,7 +2265,7 @@ private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byt return false; } - private CORINFO_CLASS_STRUCT_* getObjectType(void* objPtr) + private CORINFO_CLASS_STRUCT_* getObjectType(CORINFO_OBJECT_STRUCT_* objPtr) { object obj = HandleToObject(objPtr); return obj switch @@ -2277,14 +2277,14 @@ private bool getReadonlyStaticFieldValue(CORINFO_FIELD_STRUCT_* fieldHandle, byt } #pragma warning disable CA1822 // Mark members as static - private void* getRuntimeTypePointer(CORINFO_CLASS_STRUCT_* cls) + private CORINFO_OBJECT_STRUCT_* getRuntimeTypePointer(CORINFO_CLASS_STRUCT_* cls) #pragma warning restore CA1822 // Mark members as static { // TODO: https://github.com/dotnet/runtime/pull/75573#issuecomment-1250824543 return null; } - private bool isObjectImmutable(void* objPtr) + private bool isObjectImmutable(CORINFO_OBJECT_STRUCT_* objPtr) { object obj = HandleToObject(objPtr); return obj switch @@ -2294,5 +2294,16 @@ private bool isObjectImmutable(void* objPtr) _ => throw new NotImplementedException($"Unexpected object in isObjectImmutable: {obj}") }; } + + private int getArrayOrStringLength(CORINFO_OBJECT_STRUCT_* objHnd) + { + object obj = HandleToObject(objHnd); + return obj switch + { + FrozenStringNode frozenStr => frozenStr.Data.Length, + FrozenObjectNode frozenObj => frozenObj.GetArrayLength(), + _ => throw new NotImplementedException($"Unexpected object in getArrayOrStringLength: {obj}") + }; + } } } diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 563a59c4339ef..fb7889cbb9d9f 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -48,7 +48,7 @@ struct JitInterfaceCallbacks bool (* isValidToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK); bool (* isValidStringRef)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK); 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, void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); + 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); @@ -78,9 +78,9 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* getTypeForBox)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoHelpFunc (* getBoxHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoHelpFunc (* getUnBoxHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); - void* (* getRuntimeTypePointer)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); - bool (* isObjectImmutable)(void * thisHandle, CorInfoExceptionClass** ppException, void* objPtr); - CORINFO_CLASS_HANDLE (* getObjectType)(void * thisHandle, CorInfoExceptionClass** ppException, void* objPtr); + CORINFO_OBJECT_HANDLE (* getRuntimeTypePointer)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); + bool (* isObjectImmutable)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objPtr); + 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); @@ -109,6 +109,7 @@ struct JitInterfaceCallbacks unsigned (* getFieldOffset)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field); void (* getFieldInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, CORINFO_ACCESS_FLAGS flags, CORINFO_FIELD_INFO* pResult); bool (* isFieldStatic)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd); + int (* getArrayOrStringLength)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objHnd); void (* getBoundaries)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, uint32_t** pILOffsets, ICorDebugInfo::BoundaryTypes* implicitBoundaries); void (* setBoundaries)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, uint32_t cMap, ICorDebugInfo::OffsetMapping* pMap); void (* getVars)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, uint32_t* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers); @@ -161,7 +162,7 @@ struct JitInterfaceCallbacks bool (* isRIDClassDomainID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); unsigned (* getClassDomainID)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, void** ppIndirection); void* (* getFieldAddress)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, void** ppIndirection); - bool (* getReadonlyStaticFieldValue)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize); + bool (* getReadonlyStaticFieldValue)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects); CORINFO_CLASS_HANDLE (* getStaticFieldCurrentClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE field, bool* pIsSpeculative); CORINFO_VARARGS_HANDLE (* getVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig, void** ppIndirection); bool (* canGetVarArgsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* pSig); @@ -570,7 +571,7 @@ class JitInterfaceWrapper : public ICorJitInfo } virtual size_t printObjectDescription( - void* handle, + CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) @@ -859,17 +860,17 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual void* getRuntimeTypePointer( + virtual CORINFO_OBJECT_HANDLE getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls) { CorInfoExceptionClass* pException = nullptr; - void* temp = _callbacks->getRuntimeTypePointer(_thisHandle, &pException, cls); + CORINFO_OBJECT_HANDLE temp = _callbacks->getRuntimeTypePointer(_thisHandle, &pException, cls); if (pException != nullptr) throw pException; return temp; } virtual bool isObjectImmutable( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { CorInfoExceptionClass* pException = nullptr; bool temp = _callbacks->isObjectImmutable(_thisHandle, &pException, objPtr); @@ -878,7 +879,7 @@ class JitInterfaceWrapper : public ICorJitInfo } virtual CORINFO_CLASS_HANDLE getObjectType( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { CorInfoExceptionClass* pException = nullptr; CORINFO_CLASS_HANDLE temp = _callbacks->getObjectType(_thisHandle, &pException, objPtr); @@ -1159,6 +1160,15 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual int getArrayOrStringLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + CorInfoExceptionClass* pException = nullptr; + int temp = _callbacks->getArrayOrStringLength(_thisHandle, &pException, objHnd); + if (pException != nullptr) throw pException; + return temp; +} + virtual void getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, @@ -1649,10 +1659,11 @@ class JitInterfaceWrapper : public ICorJitInfo virtual bool getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t* buffer, - int bufferSize) + int bufferSize, + bool ignoreMovableObjects) { CorInfoExceptionClass* pException = nullptr; - bool temp = _callbacks->getReadonlyStaticFieldValue(_thisHandle, &pException, field, buffer, bufferSize); + bool temp = _callbacks->getReadonlyStaticFieldValue(_thisHandle, &pException, field, buffer, bufferSize, ignoreMovableObjects); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 2b1eb255951cc..dab1ac0c1a064 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -80,7 +80,7 @@ LWM(GetDelegateCtor, Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut) LWM(GetEEInfo, DWORD, Agnostic_CORINFO_EE_INFO) LWM(GetEHinfo, DLD, Agnostic_CORINFO_EH_CLAUSE) LWM(GetFieldAddress, DWORDLONG, Agnostic_GetFieldAddress) -LWM(GetReadonlyStaticFieldValue, DLD, DD) +LWM(GetReadonlyStaticFieldValue, DLDD, DD) LWM(GetStaticFieldCurrentClass, DWORDLONG, Agnostic_GetStaticFieldCurrentClass) LWM(GetFieldClass, DWORDLONG, DWORDLONG) LWM(GetFieldInClass, DLD, DWORDLONG) @@ -148,6 +148,7 @@ LWM(InitClass, Agnostic_InitClass, DWORD) LWM(IsCompatibleDelegate, Agnostic_IsCompatibleDelegate, DD) LWM(IsDelegateCreationAllowed, DLDL, DWORD) LWM(IsFieldStatic, DWORDLONG, DWORD) +LWM(GetArrayOrStringLength, DWORDLONG, DWORD) LWM(ExpandRawHandleIntrinsic, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_GENERICHANDLE_RESULT) LWM(IsIntrinsicType, DWORDLONG, DWORD) LWM(IsSDArray, DWORDLONG, DWORD) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 3afd927f7b416..0d4a17f65b837 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -2223,7 +2223,7 @@ CorInfoHelpFunc MethodContext::repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls) return result; } -void MethodContext::recGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls, void* result) +void MethodContext::recGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls, CORINFO_OBJECT_HANDLE result) { if (GetRuntimeTypePointer == nullptr) GetRuntimeTypePointer = new LightWeightMap(); @@ -2237,16 +2237,16 @@ void MethodContext::dmpGetRuntimeTypePointer(DWORDLONG key, DWORDLONG value) { printf("GetRuntimeTypePointer key cls-%016llX, value res-%016llX", key, value); } -void* MethodContext::repGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) +CORINFO_OBJECT_HANDLE MethodContext::repGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) { DWORDLONG key = CastHandle(cls); AssertMapAndKeyExist(GetRuntimeTypePointer, key, ": key %016llX", key); DWORDLONG value = GetRuntimeTypePointer->Get(key); DEBUG_REP(dmpGetRuntimeTypePointer(key, value)); - return (void*)value; + return (CORINFO_OBJECT_HANDLE)value; } -void MethodContext::recIsObjectImmutable(void* objPtr, bool result) +void MethodContext::recIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr, bool result) { if (IsObjectImmutable == nullptr) IsObjectImmutable = new LightWeightMap(); @@ -2260,7 +2260,7 @@ void MethodContext::dmpIsObjectImmutable(DWORDLONG key, DWORD value) { printf("IsObjectImmutable key obj-%016llX, value res-%u", key, value); } -bool MethodContext::repIsObjectImmutable(void* objPtr) +bool MethodContext::repIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) { DWORDLONG key = (DWORDLONG)objPtr; AssertMapAndKeyExist(IsObjectImmutable, key, ": key %016llX", key); @@ -2269,7 +2269,7 @@ bool MethodContext::repIsObjectImmutable(void* objPtr) return (bool)value; } -void MethodContext::recGetObjectType(void* objPtr, CORINFO_CLASS_HANDLE result) +void MethodContext::recGetObjectType(CORINFO_OBJECT_HANDLE objPtr, CORINFO_CLASS_HANDLE result) { if (GetObjectType == nullptr) GetObjectType = new LightWeightMap(); @@ -2283,7 +2283,7 @@ void MethodContext::dmpGetObjectType(DWORDLONG key, DWORDLONG value) { printf("GetObjectType key obj-%016llX, value res-%016llX", key, value); } -CORINFO_CLASS_HANDLE MethodContext::repGetObjectType(void* objPtr) +CORINFO_CLASS_HANDLE MethodContext::repGetObjectType(CORINFO_OBJECT_HANDLE objPtr) { DWORDLONG key = (DWORDLONG)objPtr; AssertMapAndKeyExist(GetObjectType, key, ": key %016llX", key); @@ -3663,15 +3663,16 @@ void* MethodContext::repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd return (void*)value.fieldAddress; } -void MethodContext::recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool result) +void MethodContext::recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects, bool result) { if (GetReadonlyStaticFieldValue == nullptr) - GetReadonlyStaticFieldValue = new LightWeightMap(); + GetReadonlyStaticFieldValue = new LightWeightMap(); - DLD key; + DLDD key; ZeroMemory(&key, sizeof(key)); key.A = CastHandle(field); key.B = (DWORD)bufferSize; + key.C = (DWORD)ignoreMovableObjects; DWORD tmpBuf = (DWORD)-1; if (buffer != nullptr && result) @@ -3684,17 +3685,18 @@ void MethodContext::recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, u GetReadonlyStaticFieldValue->Add(key, value); DEBUG_REC(dmpGetReadonlyStaticFieldValue(key, value)); } -void MethodContext::dmpGetReadonlyStaticFieldValue(DLD key, DD value) +void MethodContext::dmpGetReadonlyStaticFieldValue(DLDD key, DD value) { - printf("GetReadonlyStaticFieldValue key fld-%016llX bufSize-%u, result-%u", key.A, key.B, value.A); + printf("GetReadonlyStaticFieldValue key fld-%016llX bufSize-%u, ignoremovable-%u, result-%u", key.A, key.B, key.C, value.A); GetReadonlyStaticFieldValue->Unlock(); } -bool MethodContext::repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize) +bool MethodContext::repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects) { - DLD key; + DLDD key; ZeroMemory(&key, sizeof(key)); key.A = CastHandle(field); key.B = (DWORD)bufferSize; + key.C = (DWORD)ignoreMovableObjects; AssertMapAndKeyExist(GetReadonlyStaticFieldValue, key, ": key %016llX", key.A); @@ -4944,7 +4946,7 @@ int MethodContext::repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned me return srcBufferLength; } -void MethodContext::recPrintObjectDescription(void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) +void MethodContext::recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten) { if (PrintObjectDescription == nullptr) PrintObjectDescription = new LightWeightMap(); @@ -4973,7 +4975,7 @@ void MethodContext::dmpPrintObjectDescription(DLDL key, Agnostic_PrintObjectDesc 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(void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) +size_t MethodContext::repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) { DLDL key; key.A = CastHandle(handle); @@ -7017,6 +7019,29 @@ bool MethodContext::repIsFieldStatic(CORINFO_FIELD_HANDLE fhld) return value != 0; } +void MethodContext::recGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHandle, int result) +{ + if (GetArrayOrStringLength == nullptr) + GetArrayOrStringLength = new LightWeightMap(); + + DWORDLONG key = CastHandle(objHandle); + DWORD value = (DWORD)result; + GetArrayOrStringLength->Add(key, value); + DEBUG_REC(dmpGetArrayOrStringLength(key, value)); +} +void MethodContext::dmpGetArrayOrStringLength(DWORDLONG key, DWORD value) +{ + printf("GetArrayOrStringLength key %016llX, value %u", key, value); +} +int MethodContext::repGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHandle) +{ + DWORDLONG key = CastHandle(objHandle); + AssertMapAndKeyExist(GetArrayOrStringLength, key, ": key %016llX", key); + DWORD value = GetArrayOrStringLength->Get(key); + DEBUG_REP(dmpGetArrayOrStringLength(key, value)); + return value != 0; +} + void MethodContext::recGetIntConfigValue(const WCHAR* name, int defaultValue, int result) { if (GetIntConfigValue == nullptr) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index e28f4ed09f044..c3e2fdabfde69 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -314,17 +314,17 @@ class MethodContext void dmpGetUnBoxHelper(DWORDLONG key, DWORD value); CorInfoHelpFunc repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls); - void recGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls, void* result); + void recGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls, CORINFO_OBJECT_HANDLE result); void dmpGetRuntimeTypePointer(DWORDLONG key, DWORDLONG value); - void* repGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls); + CORINFO_OBJECT_HANDLE repGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls); - void recIsObjectImmutable(void* objPtr, bool result); + void recIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr, bool result); void dmpIsObjectImmutable(DWORDLONG key, DWORD value); - bool repIsObjectImmutable(void* objPtr); + bool repIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr); - void recGetObjectType(void* objPtr, CORINFO_CLASS_HANDLE result); + void recGetObjectType(CORINFO_OBJECT_HANDLE objPtr, CORINFO_CLASS_HANDLE result); void dmpGetObjectType(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetObjectType(void* objPtr); + CORINFO_CLASS_HANDLE repGetObjectType(CORINFO_OBJECT_HANDLE objPtr); void recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, @@ -492,9 +492,9 @@ class MethodContext void dmpGetFieldAddress(DWORDLONG key, const Agnostic_GetFieldAddress& value); void* repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection); - void recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool result); - void dmpGetReadonlyStaticFieldValue(DLD key, DD value); - bool repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize); + void recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects, bool result); + void dmpGetReadonlyStaticFieldValue(DLDD key, DD value); + bool repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects); void recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool isSpeculative, CORINFO_CLASS_HANDLE result); void dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value); @@ -638,9 +638,9 @@ 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(void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); + 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(void* handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); + 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); @@ -876,6 +876,10 @@ class MethodContext void dmpIsFieldStatic(DWORDLONG key, DWORD value); bool repIsFieldStatic(CORINFO_FIELD_HANDLE fhld); + void recGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd, int result); + void dmpGetArrayOrStringLength(DWORDLONG key, DWORD value); + int repGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd); + void recGetIntConfigValue(const WCHAR* name, int defaultValue, int result); void dmpGetIntConfigValue(const Agnostic_ConfigIntInfo& key, int value); int repGetIntConfigValue(const WCHAR* name, int defaultValue); @@ -1149,6 +1153,7 @@ enum mcPackets Packet_GetObjectType = 199, Packet_IsObjectImmutable = 200, Packet_ExpandRawHandleIntrinsic = 201, + Packet_GetArrayOrStringLength = 202, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index cee845252fcfe..75d5a6f43749c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -455,10 +455,10 @@ int interceptor_ICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN * return temp; } -size_t interceptor_ICJI::printObjectDescription(void* handle, /* IN */ - char* buffer, /* OUT */ - size_t bufferSize, /* IN */ - size_t* pRequiredBufferSize /* OUT */ +size_t interceptor_ICJI::printObjectDescription(CORINFO_OBJECT_HANDLE handle, /* IN */ + char* buffer, /* OUT */ + size_t bufferSize, /* IN */ + size_t* pRequiredBufferSize /* OUT */ ) { mc->cr->AddCall("printObjectDescription"); @@ -793,15 +793,15 @@ CorInfoHelpFunc interceptor_ICJI::getUnBoxHelper(CORINFO_CLASS_HANDLE cls) return temp; } -void* interceptor_ICJI::getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) +CORINFO_OBJECT_HANDLE interceptor_ICJI::getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) { mc->cr->AddCall("getRuntimeTypePointer"); - void* temp = original_ICorJitInfo->getRuntimeTypePointer(cls); + CORINFO_OBJECT_HANDLE temp = original_ICorJitInfo->getRuntimeTypePointer(cls); mc->recGetRuntimeTypePointer(cls, temp); return temp; } -bool interceptor_ICJI::isObjectImmutable(void* typeObj) +bool interceptor_ICJI::isObjectImmutable(CORINFO_OBJECT_HANDLE typeObj) { mc->cr->AddCall("isObjectImmutable"); bool temp = original_ICorJitInfo->isObjectImmutable(typeObj); @@ -809,7 +809,7 @@ bool interceptor_ICJI::isObjectImmutable(void* typeObj) return temp; } -CORINFO_CLASS_HANDLE interceptor_ICJI::getObjectType(void* typeObj) +CORINFO_CLASS_HANDLE interceptor_ICJI::getObjectType(CORINFO_OBJECT_HANDLE typeObj) { mc->cr->AddCall("getObjectType"); CORINFO_CLASS_HANDLE temp = original_ICorJitInfo->getObjectType(typeObj); @@ -1123,6 +1123,14 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return result; } +int interceptor_ICJI::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) +{ + mc->cr->AddCall("getArrayOrStringLength"); + int result = original_ICorJitInfo->getArrayOrStringLength(objHnd); + mc->recGetArrayOrStringLength(objHnd, result); + return result; +} + /*********************************************************************************/ // // ICorDebugInfo @@ -1742,11 +1750,11 @@ void* interceptor_ICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd return temp; } -bool interceptor_ICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize) +bool interceptor_ICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects) { mc->cr->AddCall("getReadonlyStaticFieldValue"); - bool result = original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize); - mc->recGetReadonlyStaticFieldValue(field, buffer, bufferSize, result); + bool result = original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects); + mc->recGetReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects, result); return result; } 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 6769ddb62371e..c9bb221333a32 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -316,7 +316,7 @@ int interceptor_ICJI::getStringLiteral( } size_t interceptor_ICJI::printObjectDescription( - void* handle, + CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) @@ -546,7 +546,7 @@ CorInfoHelpFunc interceptor_ICJI::getUnBoxHelper( return original_ICorJitInfo->getUnBoxHelper(cls); } -void* interceptor_ICJI::getRuntimeTypePointer( +CORINFO_OBJECT_HANDLE interceptor_ICJI::getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls) { mcs->AddCall("getRuntimeTypePointer"); @@ -554,14 +554,14 @@ void* interceptor_ICJI::getRuntimeTypePointer( } bool interceptor_ICJI::isObjectImmutable( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { mcs->AddCall("isObjectImmutable"); return original_ICorJitInfo->isObjectImmutable(objPtr); } CORINFO_CLASS_HANDLE interceptor_ICJI::getObjectType( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { mcs->AddCall("getObjectType"); return original_ICorJitInfo->getObjectType(objPtr); @@ -787,6 +787,13 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } +int interceptor_ICJI::getArrayOrStringLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + mcs->AddCall("getArrayOrStringLength"); + return original_ICorJitInfo->getArrayOrStringLength(objHnd); +} + void interceptor_ICJI::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, @@ -1207,10 +1214,11 @@ void* interceptor_ICJI::getFieldAddress( bool interceptor_ICJI::getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t* buffer, - int bufferSize) + int bufferSize, + bool ignoreMovableObjects) { mcs->AddCall("getReadonlyStaticFieldValue"); - return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize); + return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects); } CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( 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 b3f34f8a5cb54..6f5367b1fbff6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -279,7 +279,7 @@ int interceptor_ICJI::getStringLiteral( } size_t interceptor_ICJI::printObjectDescription( - void* handle, + CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize) @@ -479,20 +479,20 @@ CorInfoHelpFunc interceptor_ICJI::getUnBoxHelper( return original_ICorJitInfo->getUnBoxHelper(cls); } -void* interceptor_ICJI::getRuntimeTypePointer( +CORINFO_OBJECT_HANDLE interceptor_ICJI::getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls) { return original_ICorJitInfo->getRuntimeTypePointer(cls); } bool interceptor_ICJI::isObjectImmutable( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { return original_ICorJitInfo->isObjectImmutable(objPtr); } CORINFO_CLASS_HANDLE interceptor_ICJI::getObjectType( - void* objPtr) + CORINFO_OBJECT_HANDLE objPtr) { return original_ICorJitInfo->getObjectType(objPtr); } @@ -689,6 +689,12 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } +int interceptor_ICJI::getArrayOrStringLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + return original_ICorJitInfo->getArrayOrStringLength(objHnd); +} + void interceptor_ICJI::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, @@ -1057,9 +1063,10 @@ void* interceptor_ICJI::getFieldAddress( bool interceptor_ICJI::getReadonlyStaticFieldValue( CORINFO_FIELD_HANDLE field, uint8_t* buffer, - int bufferSize) + int bufferSize, + bool ignoreMovableObjects) { - return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize); + return original_ICorJitInfo->getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects); } CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 92b42376ce04c..cebb456c7afeb 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -388,10 +388,10 @@ int MyICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN */ return jitInstance->mc->repGetStringLiteral(module, metaTOK, buffer, bufferSize, startIndex); } -size_t MyICJI::printObjectDescription(void* handle, /* IN */ - char* buffer, /* OUT */ - size_t bufferSize, /* IN */ - size_t* pRequiredBufferSize /* OUT */ +size_t MyICJI::printObjectDescription(CORINFO_OBJECT_HANDLE handle, /* IN */ + char* buffer, /* OUT */ + size_t bufferSize, /* IN */ + size_t* pRequiredBufferSize /* OUT */ ) { jitInstance->mc->cr->AddCall("printObjectDescription"); @@ -673,21 +673,21 @@ CorInfoHelpFunc MyICJI::getUnBoxHelper(CORINFO_CLASS_HANDLE cls) return result; } -void* MyICJI::getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) +CORINFO_OBJECT_HANDLE MyICJI::getRuntimeTypePointer(CORINFO_CLASS_HANDLE cls) { jitInstance->mc->cr->AddCall("getRuntimeTypePointer"); - void* result = jitInstance->mc->repGetRuntimeTypePointer(cls); + CORINFO_OBJECT_HANDLE result = jitInstance->mc->repGetRuntimeTypePointer(cls); return result; } -bool MyICJI::isObjectImmutable(void* objPtr) +bool MyICJI::isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) { jitInstance->mc->cr->AddCall("isObjectImmutable"); bool result = jitInstance->mc->repIsObjectImmutable(objPtr); return result; } -CORINFO_CLASS_HANDLE MyICJI::getObjectType(void* objPtr) +CORINFO_CLASS_HANDLE MyICJI::getObjectType(CORINFO_OBJECT_HANDLE objPtr) { jitInstance->mc->cr->AddCall("getObjectType"); CORINFO_CLASS_HANDLE result = jitInstance->mc->repGetObjectType(objPtr); @@ -948,6 +948,12 @@ bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return jitInstance->mc->repIsFieldStatic(fldHnd); } +int MyICJI::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) +{ + jitInstance->mc->cr->AddCall("getArrayOrStringLength"); + return jitInstance->mc->repGetArrayOrStringLength(objHnd); +} + /*********************************************************************************/ // // ICorDebugInfo @@ -1520,10 +1526,10 @@ void* MyICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection) return jitInstance->mc->repGetFieldAddress(field, ppIndirection); } -bool MyICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize) +bool MyICJI::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects) { jitInstance->mc->cr->AddCall("getReadonlyStaticFieldValue"); - return jitInstance->mc->repGetReadonlyStaticFieldValue(field, buffer, bufferSize); + return jitInstance->mc->repGetReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects); } // return the class handle for the current value of a static field diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c1606c893b98b..3d0012cbd4119 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -718,10 +718,10 @@ int CEEInfo::getStringLiteral ( } size_t CEEInfo::printObjectDescription ( - void* handle, - char* buffer, - size_t bufferSize, - size_t* pRequiredBufferSize) + CORINFO_OBJECT_HANDLE handle, + char* buffer, + size_t bufferSize, + size_t* pRequiredBufferSize) { CONTRACTL{ THROWS; @@ -735,20 +735,18 @@ size_t CEEInfo::printObjectDescription ( JIT_TO_EE_TRANSITION(); - Object* obj = (Object*)handle; - GCX_COOP(); - + OBJECTREF obj = getObjectFromJitHandle(handle); StackSString stackStr; // Currently only supported for String and RuntimeType if (obj->GetMethodTable()->IsString()) { - ((StringObject*)obj)->GetSString(stackStr); + ((STRINGREF)obj)->GetSString(stackStr); } else if (obj->GetMethodTable() == g_pRuntimeTypeClass) { - ((ReflectClassBaseObject*)obj)->GetType().GetName(stackStr); + ((REFLECTCLASSBASEREF)obj)->GetType().GetName(stackStr); } else { @@ -1719,6 +1717,40 @@ bool CEEInfo::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return res; } +int CEEInfo::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + int arrLen = -1; + JIT_TO_EE_TRANSITION(); + + _ASSERT(objHnd != NULL); + + GCX_COOP(); + + OBJECTREF obj = getObjectFromJitHandle(objHnd); + + if (obj->GetMethodTable()->IsArray()) + { + arrLen = ((ARRAYBASEREF)obj)->GetNumComponents(); + } + else if (obj->GetMethodTable()->IsString()) + { + arrLen = ((STRINGREF)obj)->GetStringLength(); + } + else + { + UNREACHABLE(); + } + + EE_TO_JIT_TRANSITION(); + return arrLen; +} + //--------------------------------------------------------------------------------------- // void @@ -2853,6 +2885,56 @@ void CEEInfo::ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, ScanToken(pModule, pResolvedToken, th, pMD); } +CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF objref, bool knownFrozen) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + Object* obj = OBJECTREFToObject(objref); + if (knownFrozen || GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + { + return (CORINFO_OBJECT_HANDLE)obj; + } + + if (m_pJitHandles == nullptr) + { + m_pJitHandles = new SArray(); + } + + OBJECTHANDLEHolder handle = AppDomain::GetCurrentDomain()->CreateHandle(objref); + m_pJitHandles->Append(handle); + handle.SuppressRelease(); + + // We know that handle is aligned so we use the lowest bit as a marker + // "this is a handle, not a frozen object". + return (CORINFO_OBJECT_HANDLE)((size_t)handle.GetValue() | 1); +} + +OBJECTREF CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + size_t intHandle = (size_t)handle; + if (intHandle & 1) + { + return ObjectToOBJECTREF(*(Object**)(intHandle - 1)); + } + + // Frozen object + return ObjectToOBJECTREF((Object*)intHandle); +} + MethodDesc * CEEInfo::GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle) { STANDARD_VM_CONTRACT; @@ -6006,7 +6088,7 @@ CorInfoHelpFunc CEEInfo::getUnBoxHelper(CORINFO_CLASS_HANDLE clsHnd) } /***********************************************************************/ -void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) +CORINFO_OBJECT_HANDLE CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) { CONTRACTL{ THROWS; @@ -6014,7 +6096,7 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) MODE_PREEMPTIVE; } CONTRACTL_END; - void* pointer = nullptr; + CORINFO_OBJECT_HANDLE pointer = NULL; JIT_TO_EE_TRANSITION(); @@ -6022,7 +6104,9 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) if (!typeHnd.IsCanonicalSubtype() && typeHnd.IsManagedClassObjectPinned()) { GCX_COOP(); - pointer = OBJECTREFToObject(typeHnd.GetManagedClassObject()); + // ManagedClassObject is frozen here + pointer = (CORINFO_OBJECT_HANDLE)OBJECTREFToObject(typeHnd.GetManagedClassObject()); + _ASSERT(GCHeapUtilities::GetGCHeap()->IsInFrozenSegment((Object*)pointer)); } EE_TO_JIT_TRANSITION(); @@ -6032,7 +6116,7 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) /***********************************************************************/ -bool CEEInfo::isObjectImmutable(void* objPtr) +bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) { CONTRACTL{ THROWS; @@ -6040,11 +6124,13 @@ bool CEEInfo::isObjectImmutable(void* objPtr) MODE_PREEMPTIVE; } CONTRACTL_END; + _ASSERT(objHandle != NULL); + #ifdef DEBUG JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = (Object*)objPtr; + OBJECTREF obj = getObjectFromJitHandle(objHandle); MethodTable* type = obj->GetMethodTable(); _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); @@ -6057,7 +6143,7 @@ bool CEEInfo::isObjectImmutable(void* objPtr) } /***********************************************************************/ -CORINFO_CLASS_HANDLE CEEInfo::getObjectType(void* objPtr) +CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objHandle) { CONTRACTL{ THROWS; @@ -6065,15 +6151,14 @@ CORINFO_CLASS_HANDLE CEEInfo::getObjectType(void* objPtr) MODE_PREEMPTIVE; } CONTRACTL_END; - _ASSERT(objPtr != nullptr); + _ASSERT(objHandle != NULL); CORINFO_CLASS_HANDLE handle = NULL; JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = (Object*)objPtr; - VALIDATEOBJECT(obj); + OBJECTREF obj = getObjectFromJitHandle(objHandle); handle = (CORINFO_CLASS_HANDLE)obj->GetMethodTable(); EE_TO_JIT_TRANSITION(); @@ -11875,7 +11960,7 @@ void* CEEJitInfo::getFieldAddress(CORINFO_FIELD_HANDLE fieldHnd, return result; } -bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t* buffer, int bufferSize) +bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects) { CONTRACTL { THROWS; @@ -11913,10 +11998,21 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t if (fieldObj != NULL) { Object* obj = OBJECTREFToObject(fieldObj); - if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + CORINFO_OBJECT_HANDLE handle; + + if (ignoreMovableObjects) + { + if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + { + handle = getJitHandleForObject(fieldObj, true); + memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); + result = true; + } + } + else { - intptr_t ptr = (intptr_t)obj; - memcpy(buffer, &ptr, sizeof(intptr_t)); + handle = getJitHandleForObject(fieldObj); + memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); result = true; } } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 9b517406ce4f1..c0fcb0a92fb72 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -494,6 +494,7 @@ class CEEInfo : public ICorJitInfo CORINFO_CLASS_HANDLE *clsRet = NULL /* optional out */ ); CEEInfo(MethodDesc * fd = NULL, bool fAllowInlining = true) : + m_pJitHandles(nullptr), m_pMethodBeingCompiled(fd), m_pThread(GetThreadNULLOk()), m_hMethodForSecurity_Key(NULL), @@ -509,6 +510,21 @@ class CEEInfo : public ICorJitInfo virtual ~CEEInfo() { LIMITED_METHOD_CONTRACT; + +#if !defined(DACCESS_COMPILE) + // Free all handles used by JIT + if (m_pJitHandles != nullptr) + { + OBJECTHANDLE* elements = m_pJitHandles->GetElements(); + unsigned count = m_pJitHandles->GetCount(); + for (unsigned i = 0; i < count; i++) + { + DestroyHandle(elements[i]); + } + delete m_pJitHandles; + m_pJitHandles = nullptr; + } +#endif } // Performs any work JIT-related work that should be performed at process shutdown. @@ -569,6 +585,7 @@ class CEEInfo : public ICorJitInfo #endif protected: + SArray* m_pJitHandles; // GC handles used by JIT MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled Thread * m_pThread; // Cached current thread for faster JIT-EE transitions CORJIT_FLAGS m_jitFlags; @@ -579,6 +596,9 @@ class CEEInfo : public ICorJitInfo return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled; } + CORINFO_OBJECT_HANDLE getJitHandleForObject(OBJECTREF objref, bool knownFrozen = false); + OBJECTREF getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle); + // Cache of last GetMethodForSecurity() lookup CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key; MethodDesc * m_pMethodForSecurity_Value;