From 0fe704200ff37afb76d86e767c117f999577d73b Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 03:28:23 +0200 Subject: [PATCH 01/41] Initial impl of Jan's suggestions --- src/coreclr/inc/corinfo.h | 3 + src/coreclr/inc/icorjitinfoimpl_generated.h | 3 + src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/jit/ICorJitInfo_names_generated.h | 1 + .../jit/ICorJitInfo_wrapper_generated.hpp | 9 + src/coreclr/jit/assertionprop.cpp | 1 + src/coreclr/jit/importer.cpp | 12 +- src/coreclr/jit/valuenum.cpp | 50 ++++- src/coreclr/jit/valuenumfuncs.h | 4 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 10 + .../JitInterface/CorInfoImpl_generated.cs | 182 ++++++++++-------- .../ThunkGenerator/ThunkInput.txt | 2 + .../aot/jitinterface/jitinterface_generated.h | 10 + .../tools/superpmi/superpmi-shared/lwmlist.h | 1 + .../superpmi-shared/methodcontext.cpp | 23 +++ .../superpmi/superpmi-shared/methodcontext.h | 5 + .../superpmi-shim-collector/icorjitinfo.cpp | 8 + .../icorjitinfo_generated.cpp | 7 + .../icorjitinfo_generated.cpp | 6 + .../tools/superpmi/superpmi/icorjitinfo.cpp | 6 + src/coreclr/vm/jitinterface.cpp | 60 +++++- 21 files changed, 315 insertions(+), 98 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 7a763721840072..b8c84b978d8d15 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 @@ -2729,6 +2730,8 @@ class ICorStaticInfo // Returns true iff "fldHnd" represents a static field. virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0; + virtual int getArrayLength(CORINFO_OBJECT_HANDLE objHnd) = 0; + /*********************************************************************************/ // // ICorDebugInfo diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index ec0d19a4c7972e..c626d0851c6f12 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -404,6 +404,9 @@ void getFieldInfo( bool isFieldStatic( CORINFO_FIELD_HANDLE fldHnd) override; +int getArrayLength( + CORINFO_OBJECT_HANDLE objHnd) override; + void getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 90c5520ebfed64..2f1bb07461e18b 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 ed9a2be8c8d72b..a8fe608a778d9d 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(getArrayLength) 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 38179829a21ae0..7e3f0a9e53bbd9 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -965,6 +965,15 @@ bool WrapICorJitInfo::isFieldStatic( return temp; } +int WrapICorJitInfo::getArrayLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + API_ENTER(getArrayLength); + int temp = wrapHnd->getArrayLength(objHnd); + API_LEAVE(getArrayLength); + return temp; +} + void WrapICorJitInfo::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index a295b41f7f3740..ef9b15eadbf5ae 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -6127,6 +6127,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/importer.cpp b/src/coreclr/jit/importer.cpp index 644cdd9c993d94..598ec501a84c28 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4344,19 +4344,23 @@ 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) { tree = gtNewNull(); } - else + else if ((ptr & 1) == 0) // Check the lowest bit for "Is frozen" mark { 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); + } + else + { + return nullptr; } break; } diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 791305c22d3387..4b8b8cf8c168bc 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8685,7 +8685,21 @@ void Compiler::fgValueNumberTree(GenTree* tree) VNFunc loadFunc = ((tree->gtFlags & GTF_IND_NONNULL) != 0) ? VNF_InvariantNonNullLoad : VNF_InvariantLoad; - tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), loadFunc, addrNvnp); + // Special case: for initialized non-null 'static readonly' fields we want to keep field + // sequence + // to be able to fold their value + ValueNum fieldSeqVN; + if ((loadFunc == VNF_InvariantNonNullLoad) && addr->IsIconHandle(GTF_ICON_CONST_PTR)) + { + fieldSeqVN = vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq); + } + else + { + fieldSeqVN = vnStore->VNForNull(); + } + + tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), loadFunc, addrNvnp, + ValueNumPair(fieldSeqVN, fieldSeqVN)); tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp); } } @@ -8774,6 +8788,40 @@ void Compiler::fgValueNumberTree(GenTree* tree) } else // Look up the VNFunc for the node { + if (tree->OperIs(GT_ARR_LENGTH)) + { + ValueNum addressVN = tree->gtGetOp1()->gtVNPair.GetLiberal(); + VNFuncApp funcApp; + if (vnStore->GetVNFunc(addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad)) + { + ValueNum fieldSeqVN = funcApp.m_args[1]; + if ((fieldSeqVN != vnStore->VNForNull()) && (fieldSeqVN != ValueNumStore::NoVN)) + { + FieldSeq* fieldSeq = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); + if (fieldSeq != nullptr) + { + CORINFO_FIELD_HANDLE field = fieldSeq->GetFieldHandle(); + if (field != NULL) + { + uint8_t buffer[TARGET_POINTER_SIZE] = {0}; + if (this->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, + TARGET_POINTER_SIZE)) + { + CORINFO_OBJECT_HANDLE objHandle; + memcpy(&objHandle, buffer, TARGET_POINTER_SIZE); + int len = this->info.compCompHnd->getArrayLength(objHandle); + if (len >= 0) + { + tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + return; + } + } + } + } + } + } + } + VNFunc vnf = GetVNFuncForNode(tree); if (ValueNumStore::VNFuncIsLegal(vnf)) diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index b8fcc8b7af66a1..19f253df9c407b 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -144,8 +144,8 @@ ValueNumFuncDef(Box, 3, false, false, false) ValueNumFuncDef(BoxNullable, 3, false, false, false) ValueNumFuncDef(LazyStrCns, 2, false, true, false) // Lazy-initialized string literal (helper) -ValueNumFuncDef(InvariantLoad, 1, false, false, false) // Args: 0: (VN of) the address. -ValueNumFuncDef(InvariantNonNullLoad, 1, false, true, false) // Args: 0: (VN of) the address. +ValueNumFuncDef(InvariantLoad, 2, false, false, false) // Args: 0: (VN of) the address, 1: field sequence (if any). +ValueNumFuncDef(InvariantNonNullLoad, 2, false, true, false) // Args: 0: (VN of) the address, 1: field sequence (if any). ValueNumFuncDef(Unbox, 2, false, true, false) ValueNumFuncDef(LT_UN, 2, false, false, false) // unsigned or unordered comparisons diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 7fe0b02967b58c..53ac26319db062 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2881,6 +2881,16 @@ private bool isFieldStatic(CORINFO_FIELD_STRUCT_* fldHnd) return HandleToObject(fldHnd).IsStatic; } +#pragma warning disable CA1822 // Mark members as static + private int getArrayLength(CORINFO_FIELD_STRUCT_* objHnd) +#pragma warning restore CA1822 // Mark members as static + { + // This is not used on crossgen and NativeAOT. + // For NativeAOT we'll need a different API, e.g. "getArrayLength(void* frozenObjPtr)" + // We'll add it as part of "allocate static arrays on FOH" effort for CoreCLR + return -1; + } + private void getBoundaries(CORINFO_METHOD_STRUCT_* ftn, ref uint cILOffsets, ref uint* pILOffsets, BoundaryTypes* implicitBoundaries) { // TODO: Debugging diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 048c6bf00fbe3c..9ead90331b50e5 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1464,6 +1464,21 @@ private static byte _isFieldStatic(IntPtr thisHandle, IntPtr* ppException, CORIN } } + [UnmanagedCallersOnly] + private static int _getArrayLength(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objHnd) + { + var _this = GetThis(thisHandle); + try + { + return _this.getArrayLength(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) { @@ -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; @@ -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)&_getArrayLength; + 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/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 61f5fa42e2ec0b..228a42e472f029 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_* @@ -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 getArrayLength(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) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 563a59c4339ef9..6e4eb7ac344b3d 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -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 (* getArrayLength)(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); @@ -1159,6 +1160,15 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual int getArrayLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + CorInfoExceptionClass* pException = nullptr; + int temp = _callbacks->getArrayLength(_thisHandle, &pException, objHnd); + if (pException != nullptr) throw pException; + return temp; +} + virtual void getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 2b1eb255951cc1..394ffc476ab1a1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -148,6 +148,7 @@ LWM(InitClass, Agnostic_InitClass, DWORD) LWM(IsCompatibleDelegate, Agnostic_IsCompatibleDelegate, DD) LWM(IsDelegateCreationAllowed, DLDL, DWORD) LWM(IsFieldStatic, DWORDLONG, DWORD) +LWM(GetArrayLength, 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 3afd927f7b416b..19ddf1e039895c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -7017,6 +7017,29 @@ bool MethodContext::repIsFieldStatic(CORINFO_FIELD_HANDLE fhld) return value != 0; } +void MethodContext::recGetArrayLength(CORINFO_OBJECT_HANDLE fhld, int result) +{ + if (GetArrayLength == nullptr) + GetArrayLength = new LightWeightMap(); + + DWORDLONG key = CastHandle(fhld); + DWORD value = result ? 1 : 0; + GetArrayLength->Add(key, value); + DEBUG_REC(dmpGetArrayLength(key, value)); +} +void MethodContext::dmpGetArrayLength(DWORDLONG key, DWORD value) +{ + printf("GetArrayLength key %016llX, value %u", key, value); +} +int MethodContext::repGetArrayLength(CORINFO_OBJECT_HANDLE fhld) +{ + DWORDLONG key = CastHandle(fhld); + AssertMapAndKeyExist(GetArrayLength, key, ": key %016llX", key); + DWORD value = GetArrayLength->Get(key); + DEBUG_REP(dmpGetArrayLength(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 e28f4ed09f0443..0949ac06b53c04 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -876,6 +876,10 @@ class MethodContext void dmpIsFieldStatic(DWORDLONG key, DWORD value); bool repIsFieldStatic(CORINFO_FIELD_HANDLE fhld); + void recGetArrayLength(CORINFO_OBJECT_HANDLE objHnd, int result); + void dmpGetArrayLength(DWORDLONG key, DWORD value); + int repGetArrayLength(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_GetArrayLength = 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 cee845252fcfe5..71578459b2b363 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1123,6 +1123,14 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return result; } +int interceptor_ICJI::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +{ + mc->cr->AddCall("getArrayLength"); + int result = original_ICorJitInfo->getArrayLength(objHnd); + mc->recGetArrayLength(objHnd, result); + return result; +} + /*********************************************************************************/ // // ICorDebugInfo 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 6769ddb62371ed..efdbd7d15fbc94 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -787,6 +787,13 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } +int interceptor_ICJI::getArrayLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + mcs->AddCall("getArrayLength"); + return original_ICorJitInfo->getArrayLength(objHnd); +} + void interceptor_ICJI::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, 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 b3f34f8a5cb546..fe90b312ee4d0a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -689,6 +689,12 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } +int interceptor_ICJI::getArrayLength( + CORINFO_OBJECT_HANDLE objHnd) +{ + return original_ICorJitInfo->getArrayLength(objHnd); +} + void interceptor_ICJI::getBoundaries( CORINFO_METHOD_HANDLE ftn, unsigned int* cILOffsets, diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 92b42376ce04c7..b56c26241c731d 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -948,6 +948,12 @@ bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return jitInstance->mc->repIsFieldStatic(fldHnd); } +int MyICJI::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +{ + jitInstance->mc->cr->AddCall("getArrayLength"); + return jitInstance->mc->repGetArrayLength(objHnd); +} + /*********************************************************************************/ // // ICorDebugInfo diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a7789b5657c8aa..baa502f1363ccc 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1721,6 +1721,47 @@ bool CEEInfo::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return res; } +int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + int arrLen = -1; + JIT_TO_EE_TRANSITION(); + + _ASSERT(objHnd != NULL); + + GCX_COOP(); + + Object* obj = nullptr; + size_t handle = (size_t)objHnd; + if (handle & 1) + { + obj = *(Object**)(handle - 1); + } + else + { + obj = (Object*)handle; + _ASSERT(GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)); + } + _ASSERT(obj != nullptr); + + if (obj->GetMethodTable()->IsArray() && obj->GetMethodTable()->GetInternalCorElementType() == ELEMENT_TYPE_SZARRAY) + { + arrLen = ((ArrayBase*)obj)->GetNumComponents(); + } + else if (obj->GetMethodTable()->IsString()) + { + arrLen = ((StringObject*)obj)->GetStringLength(); + } + + EE_TO_JIT_TRANSITION(); + return arrLen; +} + //--------------------------------------------------------------------------------------- // void @@ -11915,12 +11956,25 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t if (fieldObj != NULL) { Object* obj = OBJECTREFToObject(fieldObj); + size_t handle; if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { - intptr_t ptr = (intptr_t)obj; - memcpy(buffer, &ptr, sizeof(intptr_t)); - result = true; + handle = (size_t)obj; + } + else + { + PTR_MethodTable objMT = obj->GetMethodTable(); + // We don't need to limit it to these types but JIT doesn't need other types of + // objects at the moment so it's for better throughput. + if (objMT->IsString() || objMT->IsArray()) + { + // TODO: save handle to a list to then release once JIT finishes + handle = (size_t)AppDomain::GetCurrentDomain()->CreateHandle(fieldObj); + handle |= 1; + } } + memcpy(buffer, &handle, sizeof(size_t)); + result = true; } else { From e4283631f81226c2dcc09b77070a9ecdead63ea2 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 11:16:13 +0200 Subject: [PATCH 02/41] Address part of the feedback --- src/coreclr/inc/corinfo.h | 15 +++++------ src/coreclr/inc/icorjitinfoimpl_generated.h | 3 ++- .../jit/ICorJitInfo_wrapper_generated.hpp | 5 ++-- src/coreclr/jit/valuenum.cpp | 2 +- .../JitInterface/CorInfoImpl_generated.cs | 6 ++--- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 2 +- .../aot/jitinterface/jitinterface_generated.h | 7 ++--- .../tools/superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 26 ++++++++++--------- .../superpmi/superpmi-shared/methodcontext.h | 6 ++--- .../superpmi-shim-collector/icorjitinfo.cpp | 6 ++--- .../icorjitinfo_generated.cpp | 5 ++-- .../icorjitinfo_generated.cpp | 5 ++-- .../tools/superpmi/superpmi/icorjitinfo.cpp | 4 +-- src/coreclr/vm/jitinterface.cpp | 10 ++++--- 17 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index b8c84b978d8d15..8689d95f34e8ee 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -3199,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 @@ -3215,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 c626d0851c6f12..e430b3c2cdce97 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -619,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/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 7e3f0a9e53bbd9..4f74fcaacdb249 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1482,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/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 4b8b8cf8c168bc..ac6a238762f649 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8805,7 +8805,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) { uint8_t buffer[TARGET_POINTER_SIZE] = {0}; if (this->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, - TARGET_POINTER_SIZE)) + TARGET_POINTER_SIZE, false)) { CORINFO_OBJECT_HANDLE objHandle; memcpy(&objHandle, buffer, TARGET_POINTER_SIZE); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 9ead90331b50e5..2ec789e0feb82f 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -2244,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) { @@ -2838,7 +2838,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[148] = (delegate* unmanaged)&_isRIDClassDomainID; callbacks[149] = (delegate* unmanaged)&_getClassDomainID; callbacks[150] = (delegate* unmanaged)&_getFieldAddress; - callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; callbacks[152] = (delegate* unmanaged)&_getStaticFieldCurrentClass; callbacks[153] = (delegate* unmanaged)&_getVarArgsHandle; callbacks[154] = (delegate* unmanaged)&_canGetVarArgsHandle; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 228a42e472f029..908c3d54b68665 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -307,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.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 73f2cf5f6fe71e..62b8218834b6e7 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2991,7 +2991,7 @@ 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; } 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 bd923c96617e4f..d8ebd99805e54e 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); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 6e4eb7ac344b3d..aebde049f79d36 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -162,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); @@ -1659,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 394ffc476ab1a1..7ae199546cd264 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) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 19ddf1e039895c..252b4e9302e4d0 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -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); @@ -7017,13 +7019,13 @@ bool MethodContext::repIsFieldStatic(CORINFO_FIELD_HANDLE fhld) return value != 0; } -void MethodContext::recGetArrayLength(CORINFO_OBJECT_HANDLE fhld, int result) +void MethodContext::recGetArrayLength(CORINFO_OBJECT_HANDLE objHandle, int result) { if (GetArrayLength == nullptr) GetArrayLength = new LightWeightMap(); - DWORDLONG key = CastHandle(fhld); - DWORD value = result ? 1 : 0; + DWORDLONG key = CastHandle(objHandle); + DWORD value = (DWORD)result; GetArrayLength->Add(key, value); DEBUG_REC(dmpGetArrayLength(key, value)); } @@ -7031,9 +7033,9 @@ void MethodContext::dmpGetArrayLength(DWORDLONG key, DWORD value) { printf("GetArrayLength key %016llX, value %u", key, value); } -int MethodContext::repGetArrayLength(CORINFO_OBJECT_HANDLE fhld) +int MethodContext::repGetArrayLength(CORINFO_OBJECT_HANDLE objHandle) { - DWORDLONG key = CastHandle(fhld); + DWORDLONG key = CastHandle(objHandle); AssertMapAndKeyExist(GetArrayLength, key, ": key %016llX", key); DWORD value = GetArrayLength->Get(key); DEBUG_REP(dmpGetArrayLength(key, value)); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 0949ac06b53c04..2501c258e592e6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -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); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 71578459b2b363..e3dc64ba05f737 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1750,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 efdbd7d15fbc94..ba2a199fe30d42 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1214,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 fe90b312ee4d0a..be1b59d242399e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -1063,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 b56c26241c731d..cc8f99289facdd 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1526,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 baa502f1363ccc..f6e14247afdf7c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11918,7 +11918,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; @@ -11960,8 +11960,10 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { handle = (size_t)obj; + memcpy(buffer, &handle, sizeof(size_t)); + result = true; } - else + else if (!ignoreMovableObjects) { PTR_MethodTable objMT = obj->GetMethodTable(); // We don't need to limit it to these types but JIT doesn't need other types of @@ -11971,10 +11973,10 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t // TODO: save handle to a list to then release once JIT finishes handle = (size_t)AppDomain::GetCurrentDomain()->CreateHandle(fieldObj); handle |= 1; + memcpy(buffer, &handle, sizeof(size_t)); + result = true; } } - memcpy(buffer, &handle, sizeof(size_t)); - result = true; } else { From 774af699b70b8ecb9be329c37a331164a13a9eac Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 14:54:31 +0200 Subject: [PATCH 03/41] Address feedback --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 2 +- src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | 2 +- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/ee_il_dll.cpp | 4 ++-- src/coreclr/jit/emit.cpp | 2 +- src/coreclr/jit/gentree.cpp | 2 +- src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 4 ++-- .../tools/Common/JitInterface/CorInfoImpl_generated.cs | 4 ++-- src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | 4 ++++ .../Common/JitInterface/ThunkGenerator/ThunkInput.txt | 2 +- .../tools/aot/jitinterface/jitinterface_generated.h | 4 ++-- .../tools/superpmi/superpmi-shared/methodcontext.cpp | 4 ++-- .../tools/superpmi/superpmi-shared/methodcontext.h | 4 ++-- .../superpmi/superpmi-shim-collector/icorjitinfo.cpp | 8 ++++---- .../superpmi-shim-counter/icorjitinfo_generated.cpp | 2 +- .../superpmi-shim-simple/icorjitinfo_generated.cpp | 2 +- src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp | 8 ++++---- src/coreclr/vm/jitinterface.cpp | 8 ++++---- 19 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 8689d95f34e8ee..5b878e9a358710 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2285,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 */ diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index e430b3c2cdce97..f0112046b9ac21 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; diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 4f74fcaacdb249..406575c95db07a 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) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2ccbccd5d51e0a..a949179c7f1e33 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7779,7 +7779,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 eePrintObjectDescriptionDescription(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 7fb9387204cae4..ba66d30e59cf7f 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -1615,7 +1615,7 @@ const char16_t* Compiler::eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd) return param.classNameWidePtr; } -void Compiler::eePrintObjectDescriptionDescription(const char* prefix, size_t handle) +void Compiler::eePrintObjectDescriptionDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle) { const size_t maxStrSize = 64; char str[maxStrSize]; @@ -1623,7 +1623,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 f27c4302fe4e1e..82d542a88340be 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->eePrintObjectDescriptionDescription(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 2c4c10fae8fa1f..b2917149c6ce94 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); + eePrintObjectDescriptionDescription(" ", (CORINFO_OBJECT_HANDLE)tree->AsIntCon()->gtIconVal); } else { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 53ac26319db062..3c667a56ad213e 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1833,7 +1833,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); @@ -2882,7 +2882,7 @@ private bool isFieldStatic(CORINFO_FIELD_STRUCT_* fldHnd) } #pragma warning disable CA1822 // Mark members as static - private int getArrayLength(CORINFO_FIELD_STRUCT_* objHnd) + private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) #pragma warning restore CA1822 // Mark members as static { // This is not used on crossgen and NativeAOT. diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 2ec789e0feb82f..d70d1742076a02 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 @@ -2724,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; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 66fac586cb31ae..7e102d47f02a7f 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 908c3d54b68665..4a5dd7675dee05 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -193,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) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index aebde049f79d36..024f2f39f7bdd2 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); @@ -571,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) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 252b4e9302e4d0..978b17792ef0c4 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -4946,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(); @@ -4975,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); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 2501c258e592e6..f14c7905fedb1f 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -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); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index e3dc64ba05f737..c283b4b76bd78a 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"); 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 ba2a199fe30d42..b7a240dfcb3194 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) 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 be1b59d242399e..7a86949b4c8819 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) diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index cc8f99289facdd..bcbc28666f6728 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"); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f6e14247afdf7c..b345a4da1ebfd1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -720,10 +720,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; From 28b9be3ebdcb7c585a5767d14af0f8ff21271d6d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 14:56:07 +0200 Subject: [PATCH 04/41] Remove "is frozen" check from jit --- src/coreclr/jit/importer.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 598ec501a84c28..8b508e405a279b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4351,17 +4351,13 @@ GenTree* Compiler::impImportCnsTreeFromBuffer(uint8_t* buffer, var_types valueTy { tree = gtNewNull(); } - else if ((ptr & 1) == 0) // Check the lowest bit for "Is frozen" mark + else { setMethodHasFrozenObjects(); tree = gtNewIconEmbHndNode((void*)ptr, nullptr, GTF_ICON_OBJ_HDL, nullptr); tree->gtType = TYP_REF; INDEBUG(tree->AsIntCon()->gtTargetHandle = ptr); } - else - { - return nullptr; - } break; } default: From 9f92bfbb8a46d556f27af69e6d5363282efff3c5 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 15:54:10 +0200 Subject: [PATCH 05/41] NativeAOT support --- src/coreclr/jit/valuenum.cpp | 16 +++++++++++++++- .../tools/Common/JitInterface/CorInfoImpl.cs | 10 ---------- .../DependencyAnalysis/FrozenObjectNode.cs | 8 +++++++- .../DependencyAnalysis/FrozenStringNode.cs | 2 ++ .../ILCompiler.Compiler/Compiler/TypePreinit.cs | 7 +++++++ .../JitInterface/CorInfoImpl.ReadyToRun.cs | 5 +++++ .../JitInterface/CorInfoImpl.RyuJit.cs | 11 +++++++++++ src/coreclr/vm/jitinterface.cpp | 6 +++++- 8 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index ac6a238762f649..1d75201679253d 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8788,9 +8788,23 @@ void Compiler::fgValueNumberTree(GenTree* tree) } else // Look up the VNFunc for the node { + // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable) if (tree->OperIs(GT_ARR_LENGTH)) { - ValueNum addressVN = tree->gtGetOp1()->gtVNPair.GetLiberal(); + // Case 1: ARR_LENGTH(FROZEN_OBJ) + ValueNum addressVN = tree->gtGetOp1()->gtVNPair.GetLiberal(); + if (vnStore->IsVNHandle(addressVN) && (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) + { + size_t handle = vnStore->CoercedConstantValue(addressVN); + int len = this->info.compCompHnd->getArrayLength((CORINFO_OBJECT_HANDLE)handle); + if (len >= 0) + { + tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + return; + } + } + + // Case 2: ARR_LENGTH(static-readonly-field) VNFuncApp funcApp; if (vnStore->GetVNFunc(addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad)) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 3c667a56ad213e..a8b7c36a2471ba 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2881,16 +2881,6 @@ private bool isFieldStatic(CORINFO_FIELD_STRUCT_* fldHnd) return HandleToObject(fldHnd).IsStatic; } -#pragma warning disable CA1822 // Mark members as static - private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) -#pragma warning restore CA1822 // Mark members as static - { - // This is not used on crossgen and NativeAOT. - // For NativeAOT we'll need a different API, e.g. "getArrayLength(void* frozenObjPtr)" - // We'll add it as part of "allocate static arrays on FOH" effort for CoreCLR - return -1; - } - private void getBoundaries(CORINFO_METHOD_STRUCT_* ftn, ref uint cILOffsets, ref uint* pILOffsets, BoundaryTypes* implicitBoundaries) { // TODO: Debugging 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 bc863631e88183..21bc5dda0b908f 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 d1978383f236b2..0f155245303e5e 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 24cfdac46c01a7..87b93cd8e8f2e3 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 62b8218834b6e7..882c8cabe99e9c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -3010,5 +3010,10 @@ private bool isObjectImmutable(void* objPtr) { return null; } + + private int getArrayLength(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 d8ebd99805e54e..2ab44b8e12d470 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2294,5 +2294,16 @@ private bool isObjectImmutable(void* objPtr) _ => throw new NotImplementedException($"Unexpected object in isObjectImmutable: {obj}") }; } + + private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) + { + object obj = HandleToObject(objPtr); + return obj switch + { + FrozenStringNode frozenStr => frozenStr.Data.Length, + FrozenObjectNode frozenObj => frozenObj.GetArrayLength(), + _ => throw new NotImplementedException($"Unexpected object in getArrayLength: {obj}") + }; + } } } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b345a4da1ebfd1..e15bf8f8d91932 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1749,7 +1749,7 @@ int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) } _ASSERT(obj != nullptr); - if (obj->GetMethodTable()->IsArray() && obj->GetMethodTable()->GetInternalCorElementType() == ELEMENT_TYPE_SZARRAY) + if (obj->GetMethodTable()->IsArray()) { arrLen = ((ArrayBase*)obj)->GetNumComponents(); } @@ -1757,6 +1757,10 @@ int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) { arrLen = ((StringObject*)obj)->GetStringLength(); } + else + { + UNREACHABLE(); + } EE_TO_JIT_TRANSITION(); return arrLen; From 687d5cb1357511d363eedd2b3e8d6f77e9b64a88 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 16:13:51 +0200 Subject: [PATCH 06/41] Use CORINFO_OBJECT_HANDLE in more places --- src/coreclr/inc/corinfo.h | 6 +++--- src/coreclr/inc/icorjitinfoimpl_generated.h | 6 +++--- src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | 8 ++++---- src/coreclr/jit/gentree.cpp | 2 +- src/coreclr/jit/lower.cpp | 2 +- src/coreclr/jit/morph.cpp | 6 +++--- .../Common/JitInterface/CorInfoImpl_generated.cs | 12 ++++++------ .../JitInterface/ThunkGenerator/ThunkInput.txt | 6 +++--- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 6 +++--- .../JitInterface/CorInfoImpl.RyuJit.cs | 8 ++++---- .../aot/jitinterface/jitinterface_generated.h | 14 +++++++------- .../superpmi/superpmi-shared/methodcontext.cpp | 14 +++++++------- .../tools/superpmi/superpmi-shared/methodcontext.h | 12 ++++++------ .../superpmi-shim-collector/icorjitinfo.cpp | 8 ++++---- .../icorjitinfo_generated.cpp | 6 +++--- .../superpmi-shim-simple/icorjitinfo_generated.cpp | 6 +++--- .../tools/superpmi/superpmi/icorjitinfo.cpp | 8 ++++---- src/coreclr/vm/jitinterface.cpp | 12 ++++++------ 18 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 5b878e9a358710..f8f502d8ab1643 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2501,7 +2501,7 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls ) = 0; - virtual void* getRuntimeTypePointer( + virtual CORINFO_OBJECT_HANDLE getRuntimeTypePointer( CORINFO_CLASS_HANDLE cls ) = 0; @@ -2515,7 +2515,7 @@ class ICorStaticInfo // Returns true if object is known to be immutable // virtual bool isObjectImmutable( - void* objPtr + CORINFO_OBJECT_HANDLE objPtr ) = 0; //------------------------------------------------------------------------------ @@ -2528,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( diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index f0112046b9ac21..d70bf242b035dc 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -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, diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 406575c95db07a..82d7dd9439a922 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -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); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b2917149c6ce94..b2833bbd610e32 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -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/lower.cpp b/src/coreclr/jit/lower.cpp index 6e75c957486c97..4a20bac071333c 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 eb4a019a73dfab..87a5dc930aeb8e 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -8298,11 +8298,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/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index d70d1742076a02..87e9007110120b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -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 @@ -2754,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; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 4a5dd7675dee05..b19a20a1012832 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -223,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) 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 882c8cabe99e9c..c9ff0cb9313d89 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2996,17 +2996,17 @@ 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) { 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; } 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 2ab44b8e12d470..d4bfe1f2d78a71 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -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 @@ -2297,7 +2297,7 @@ private bool isObjectImmutable(void* objPtr) private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) { - object obj = HandleToObject(objPtr); + object obj = HandleToObject(objHnd); return obj switch { FrozenStringNode frozenStr => frozenStr.Data.Length, diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 024f2f39f7bdd2..48dbe67153446e 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -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); @@ -860,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); @@ -879,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); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 978b17792ef0c4..3da2e3d2258929 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); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index f14c7905fedb1f..d8359c23503322 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, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index c283b4b76bd78a..25bfb3d7dfb7a6 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -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); 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 b7a240dfcb3194..d1b07b4ef41b17 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -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); 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 7a86949b4c8819..5525675e270d8e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -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); } diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index bcbc28666f6728..be82250730f2f9 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -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); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e15bf8f8d91932..d56cbb6a9622a9 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6053,7 +6053,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; @@ -6061,7 +6061,7 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) MODE_PREEMPTIVE; } CONTRACTL_END; - void* pointer = nullptr; + CORINFO_OBJECT_HANDLE pointer = NULL; JIT_TO_EE_TRANSITION(); @@ -6069,7 +6069,7 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) if (!typeHnd.IsCanonicalSubtype() && typeHnd.IsManagedClassObjectPinned()) { GCX_COOP(); - pointer = OBJECTREFToObject(typeHnd.GetManagedClassObject()); + pointer = (CORINFO_OBJECT_HANDLE)OBJECTREFToObject(typeHnd.GetManagedClassObject()); } EE_TO_JIT_TRANSITION(); @@ -6079,7 +6079,7 @@ void* CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd) /***********************************************************************/ -bool CEEInfo::isObjectImmutable(void* objPtr) +bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) { CONTRACTL{ THROWS; @@ -6104,7 +6104,7 @@ bool CEEInfo::isObjectImmutable(void* objPtr) } /***********************************************************************/ -CORINFO_CLASS_HANDLE CEEInfo::getObjectType(void* objPtr) +CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objPtr) { CONTRACTL{ THROWS; @@ -6112,7 +6112,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getObjectType(void* objPtr) MODE_PREEMPTIVE; } CONTRACTL_END; - _ASSERT(objPtr != nullptr); + _ASSERT(objPtr != NULL); CORINFO_CLASS_HANDLE handle = NULL; From 872058d8739668a4d27b1d1e9c0ff96c2befed0f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 17:23:46 +0200 Subject: [PATCH 07/41] Free jit handles upon exit --- src/coreclr/vm/appdomain.hpp | 7 +++ src/coreclr/vm/jitinterface.cpp | 90 ++++++++++++++++++++++++++++----- src/coreclr/vm/jitinterface.h | 7 ++- 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index ecf13313bef381..7467e4853365b5 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/src/coreclr/vm/appdomain.hpp @@ -1010,6 +1010,13 @@ class BaseDomain return ::CreateHandle(m_handleStore, object); } + void DestroyHandle(OBJECTHANDLE handle) + { + WRAPPER_NO_CONTRACT; + CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, handle == NULL) + ::DestroyHandle(handle); + } + OBJECTHANDLE CreateWeakHandle(OBJECTREF object) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index d56cbb6a9622a9..e9b2407aaf9ef7 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2523,6 +2523,23 @@ void CEEInfo::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd) pMD->AsDynamicMethodDesc()->GetResolver()->FreeCompileTimeState(); } + // 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++) + { + size_t elementHandle = (size_t)elements[i]; + // All jit handles have the lowest bit set ("it's not a frozen object" marker) + // Clear it here. + _ASSERT(elementHandle & 1); + AppDomain::GetCurrentDomain()->DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); + } + delete m_pJitHandles; + m_pJitHandles = nullptr; + } + EE_TO_JIT_TRANSITION(); } @@ -2900,6 +2917,53 @@ void CEEInfo::ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, ScanToken(pModule, pResolvedToken, th, pMD); } +OBJECTHANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + if (m_pJitHandles == nullptr) + { + m_pJitHandles = new SArray(); + } + + OBJECTHANDLE handle; + GCPROTECT_BEGIN(obj); + handle = AppDomain::GetCurrentDomain()->CreateHandle(obj); + + // We know that handle is aligned so we use the lowest bit as a marker + // "this is a handle, not a frozen object". + handle = (OBJECTHANDLE)((size_t)handle | 1); + m_pJitHandles->Append(handle); + GCPROTECT_END(); + return handle; +} + +Object* CEEInfo::getObjectFromJitHandle(OBJECTHANDLE handle) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + size_t intHandle = (size_t)handle; + if (intHandle & 1) + { + return *(Object**)(intHandle - 1); + } + + // Frozen object + return (Object*)intHandle; +} + MethodDesc * CEEInfo::GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle) { STANDARD_VM_CONTRACT; @@ -6069,7 +6133,9 @@ CORINFO_OBJECT_HANDLE CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd if (!typeHnd.IsCanonicalSubtype() && typeHnd.IsManagedClassObjectPinned()) { GCX_COOP(); + // ManagedClassObject is frozen here pointer = (CORINFO_OBJECT_HANDLE)OBJECTREFToObject(typeHnd.GetManagedClassObject()); + _ASSERT(GCHeapUtilities::GetGCHeap()->IsInFrozenSegment((Object*)pointer)); } EE_TO_JIT_TRANSITION(); @@ -6079,7 +6145,7 @@ CORINFO_OBJECT_HANDLE CEEInfo::getRuntimeTypePointer(CORINFO_CLASS_HANDLE clsHnd /***********************************************************************/ -bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) +bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) { CONTRACTL{ THROWS; @@ -6087,11 +6153,13 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) MODE_PREEMPTIVE; } CONTRACTL_END; + _ASSERT(objHandle != NULL); + #ifdef DEBUG JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = (Object*)objPtr; + Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHandle); MethodTable* type = obj->GetMethodTable(); _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); @@ -6104,7 +6172,7 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objPtr) } /***********************************************************************/ -CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objPtr) +CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objHandle) { CONTRACTL{ THROWS; @@ -6112,14 +6180,14 @@ CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objPtr) MODE_PREEMPTIVE; } CONTRACTL_END; - _ASSERT(objPtr != NULL); + _ASSERT(objHandle != NULL); CORINFO_CLASS_HANDLE handle = NULL; JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = (Object*)objPtr; + Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHandle); VALIDATEOBJECT(obj); handle = (CORINFO_CLASS_HANDLE)obj->GetMethodTable(); @@ -11960,11 +12028,11 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t if (fieldObj != NULL) { Object* obj = OBJECTREFToObject(fieldObj); - size_t handle; + OBJECTHANDLE handle; if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { - handle = (size_t)obj; - memcpy(buffer, &handle, sizeof(size_t)); + handle = (OBJECTHANDLE)obj; + memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); result = true; } else if (!ignoreMovableObjects) @@ -11974,10 +12042,8 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t // objects at the moment so it's for better throughput. if (objMT->IsString() || objMT->IsArray()) { - // TODO: save handle to a list to then release once JIT finishes - handle = (size_t)AppDomain::GetCurrentDomain()->CreateHandle(fieldObj); - handle |= 1; - memcpy(buffer, &handle, sizeof(size_t)); + handle = getJitHandleForObject(fieldObj); + memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); result = true; } } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 9b517406ce4f14..b0edbffc94ac6e 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), @@ -569,16 +570,20 @@ 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; - + CORINFO_METHOD_HANDLE getMethodBeingCompiled() { LIMITED_METHOD_CONTRACT; return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled; } + OBJECTHANDLE getJitHandleForObject(OBJECTREF obj); + Object* getObjectFromJitHandle(OBJECTHANDLE handle); + // Cache of last GetMethodForSecurity() lookup CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key; MethodDesc * m_pMethodForSecurity_Value; From 860d706f9f9f4cd455a5dfe8fe847f9df941e14c Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sat, 29 Oct 2022 17:24:44 +0200 Subject: [PATCH 08/41] Update src/coreclr/vm/jitinterface.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/jitinterface.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e9b2407aaf9ef7..48ef0646d61932 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12038,10 +12038,6 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t else if (!ignoreMovableObjects) { PTR_MethodTable objMT = obj->GetMethodTable(); - // We don't need to limit it to these types but JIT doesn't need other types of - // objects at the moment so it's for better throughput. - if (objMT->IsString() || objMT->IsArray()) - { handle = getJitHandleForObject(fieldObj); memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); result = true; From bffb8e65c87c0c4ea88ec4c28c8e65f2f789ce6f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 17:26:15 +0200 Subject: [PATCH 09/41] Clean up --- src/coreclr/vm/jitinterface.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 48ef0646d61932..c7128a52d7a16a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12037,11 +12037,9 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t } else if (!ignoreMovableObjects) { - PTR_MethodTable objMT = obj->GetMethodTable(); - handle = getJitHandleForObject(fieldObj); - memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); - result = true; - } + handle = getJitHandleForObject(fieldObj); + memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); + result = true; } } else From f0a35cc70d2c372ebbec200aa91e219ae60f1d9f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 17:27:50 +0200 Subject: [PATCH 10/41] clean up in getArrayLength --- src/coreclr/vm/jitinterface.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c7128a52d7a16a..4f9e50ad1e7046 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1736,18 +1736,7 @@ int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) GCX_COOP(); - Object* obj = nullptr; - size_t handle = (size_t)objHnd; - if (handle & 1) - { - obj = *(Object**)(handle - 1); - } - else - { - obj = (Object*)handle; - _ASSERT(GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)); - } - _ASSERT(obj != nullptr); + Object* obj = getObjectFromJitHandle(objHnd); if (obj->GetMethodTable()->IsArray()) { From bfaf6ee831b12b1d394a4cdb47b67eaa1ccad050 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sat, 29 Oct 2022 17:29:45 +0200 Subject: [PATCH 11/41] Update jitinterface.h --- src/coreclr/vm/jitinterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index b0edbffc94ac6e..255b6419b4524a 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -574,7 +574,7 @@ class CEEInfo : public ICorJitInfo MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled Thread * m_pThread; // Cached current thread for faster JIT-EE transitions CORJIT_FLAGS m_jitFlags; - + CORINFO_METHOD_HANDLE getMethodBeingCompiled() { LIMITED_METHOD_CONTRACT; From a3ccc919a3ef04daff61d51fbe5933de44ba6da7 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 17:33:55 +0200 Subject: [PATCH 12/41] Remove unnecessary DestroyHandle --- src/coreclr/vm/appdomain.hpp | 7 ------- src/coreclr/vm/jitinterface.cpp | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index 7467e4853365b5..ecf13313bef381 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/src/coreclr/vm/appdomain.hpp @@ -1010,13 +1010,6 @@ class BaseDomain return ::CreateHandle(m_handleStore, object); } - void DestroyHandle(OBJECTHANDLE handle) - { - WRAPPER_NO_CONTRACT; - CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, handle == NULL) - ::DestroyHandle(handle); - } - OBJECTHANDLE CreateWeakHandle(OBJECTREF object) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 4f9e50ad1e7046..1d4ca6e26e8efc 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2523,7 +2523,7 @@ void CEEInfo::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd) // All jit handles have the lowest bit set ("it's not a frozen object" marker) // Clear it here. _ASSERT(elementHandle & 1); - AppDomain::GetCurrentDomain()->DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); + ::DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); } delete m_pJitHandles; m_pJitHandles = nullptr; From 7e041c1efb4ffbbd5de4b358c295055b5d74c5a9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 17:52:20 +0200 Subject: [PATCH 13/41] Rename to getArrayOrStringLength, free jit handles in destructor --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 2 +- src/coreclr/jit/ICorJitInfo_names_generated.h | 2 +- .../jit/ICorJitInfo_wrapper_generated.hpp | 8 +++---- src/coreclr/jit/valuenum.cpp | 4 ++-- .../JitInterface/CorInfoImpl_generated.cs | 6 ++--- .../ThunkGenerator/ThunkInput.txt | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- .../JitInterface/CorInfoImpl.RyuJit.cs | 4 ++-- .../aot/jitinterface/jitinterface_generated.h | 6 ++--- .../tools/superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 22 +++++++++---------- .../superpmi/superpmi-shared/methodcontext.h | 8 +++---- .../superpmi-shim-collector/icorjitinfo.cpp | 2 +- .../icorjitinfo_generated.cpp | 6 ++--- .../icorjitinfo_generated.cpp | 4 ++-- .../tools/superpmi/superpmi/icorjitinfo.cpp | 6 ++--- src/coreclr/vm/jitinterface.cpp | 21 ++---------------- src/coreclr/vm/jitinterface.h | 19 ++++++++++++++++ 19 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index f8f502d8ab1643..4958de749672e5 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2730,7 +2730,7 @@ class ICorStaticInfo // Returns true iff "fldHnd" represents a static field. virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0; - virtual int getArrayLength(CORINFO_OBJECT_HANDLE objHnd) = 0; + virtual int getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) = 0; /*********************************************************************************/ // diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index d70bf242b035dc..44c98ae5397f53 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -404,7 +404,7 @@ void getFieldInfo( bool isFieldStatic( CORINFO_FIELD_HANDLE fldHnd) override; -int getArrayLength( +int getArrayOrStringLength( CORINFO_OBJECT_HANDLE objHnd) override; void getBoundaries( diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index a8fe608a778d9d..8c43eb4823aefc 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -102,7 +102,7 @@ DEF_CLR_API(getFieldType) DEF_CLR_API(getFieldOffset) DEF_CLR_API(getFieldInfo) DEF_CLR_API(isFieldStatic) -DEF_CLR_API(getArrayLength) +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 82d7dd9439a922..057f5ba4177591 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -965,12 +965,12 @@ bool WrapICorJitInfo::isFieldStatic( return temp; } -int WrapICorJitInfo::getArrayLength( +int WrapICorJitInfo::getArrayOrStringLength( CORINFO_OBJECT_HANDLE objHnd) { - API_ENTER(getArrayLength); - int temp = wrapHnd->getArrayLength(objHnd); - API_LEAVE(getArrayLength); + API_ENTER(getArrayOrStringLength); + int temp = wrapHnd->getArrayOrStringLength(objHnd); + API_LEAVE(getArrayOrStringLength); return temp; } diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 1d75201679253d..b5f63faa6e1282 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8796,7 +8796,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) if (vnStore->IsVNHandle(addressVN) && (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) { size_t handle = vnStore->CoercedConstantValue(addressVN); - int len = this->info.compCompHnd->getArrayLength((CORINFO_OBJECT_HANDLE)handle); + int len = this->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); if (len >= 0) { tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); @@ -8823,7 +8823,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) { CORINFO_OBJECT_HANDLE objHandle; memcpy(&objHandle, buffer, TARGET_POINTER_SIZE); - int len = this->info.compCompHnd->getArrayLength(objHandle); + int len = this->info.compCompHnd->getArrayOrStringLength(objHandle); if (len >= 0) { tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 87e9007110120b..4b830673d4a8c2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1465,12 +1465,12 @@ private static byte _isFieldStatic(IntPtr thisHandle, IntPtr* ppException, CORIN } [UnmanagedCallersOnly] - private static int _getArrayLength(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objHnd) + private static int _getArrayOrStringLength(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objHnd) { var _this = GetThis(thisHandle); try { - return _this.getArrayLength(objHnd); + return _this.getArrayOrStringLength(objHnd); } catch (Exception ex) { @@ -2785,7 +2785,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[95] = (delegate* unmanaged)&_getFieldOffset; callbacks[96] = (delegate* unmanaged)&_getFieldInfo; callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - callbacks[98] = (delegate* unmanaged)&_getArrayLength; + callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; callbacks[99] = (delegate* unmanaged)&_getBoundaries; callbacks[100] = (delegate* unmanaged)&_setBoundaries; callbacks[101] = (delegate* unmanaged)&_getVars; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index b19a20a1012832..e120cacc136f62 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -254,7 +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 getArrayLength(CORINFO_OBJECT_HANDLE objHnd) + 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) 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 c9ff0cb9313d89..cfb2125c162e58 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -3011,7 +3011,7 @@ private bool isObjectImmutable(CORINFO_OBJECT_STRUCT_* objPtr) return null; } - private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) + 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 d4bfe1f2d78a71..5fa43d0d527bc0 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2295,14 +2295,14 @@ private bool isObjectImmutable(CORINFO_OBJECT_STRUCT_* objPtr) }; } - private int getArrayLength(CORINFO_OBJECT_STRUCT_* objHnd) + 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 getArrayLength: {obj}") + _ => 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 48dbe67153446e..fb7889cbb9d9f4 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -109,7 +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 (* getArrayLength)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_OBJECT_HANDLE objHnd); + 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); @@ -1160,11 +1160,11 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual int getArrayLength( + virtual int getArrayOrStringLength( CORINFO_OBJECT_HANDLE objHnd) { CorInfoExceptionClass* pException = nullptr; - int temp = _callbacks->getArrayLength(_thisHandle, &pException, objHnd); + int temp = _callbacks->getArrayOrStringLength(_thisHandle, &pException, objHnd); 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 7ae199546cd264..dab1ac0c1a0641 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -148,7 +148,7 @@ LWM(InitClass, Agnostic_InitClass, DWORD) LWM(IsCompatibleDelegate, Agnostic_IsCompatibleDelegate, DD) LWM(IsDelegateCreationAllowed, DLDL, DWORD) LWM(IsFieldStatic, DWORDLONG, DWORD) -LWM(GetArrayLength, 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 3da2e3d2258929..0d4a17f65b8370 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -7019,26 +7019,26 @@ bool MethodContext::repIsFieldStatic(CORINFO_FIELD_HANDLE fhld) return value != 0; } -void MethodContext::recGetArrayLength(CORINFO_OBJECT_HANDLE objHandle, int result) +void MethodContext::recGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHandle, int result) { - if (GetArrayLength == nullptr) - GetArrayLength = new LightWeightMap(); + if (GetArrayOrStringLength == nullptr) + GetArrayOrStringLength = new LightWeightMap(); DWORDLONG key = CastHandle(objHandle); DWORD value = (DWORD)result; - GetArrayLength->Add(key, value); - DEBUG_REC(dmpGetArrayLength(key, value)); + GetArrayOrStringLength->Add(key, value); + DEBUG_REC(dmpGetArrayOrStringLength(key, value)); } -void MethodContext::dmpGetArrayLength(DWORDLONG key, DWORD value) +void MethodContext::dmpGetArrayOrStringLength(DWORDLONG key, DWORD value) { - printf("GetArrayLength key %016llX, value %u", key, value); + printf("GetArrayOrStringLength key %016llX, value %u", key, value); } -int MethodContext::repGetArrayLength(CORINFO_OBJECT_HANDLE objHandle) +int MethodContext::repGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHandle) { DWORDLONG key = CastHandle(objHandle); - AssertMapAndKeyExist(GetArrayLength, key, ": key %016llX", key); - DWORD value = GetArrayLength->Get(key); - DEBUG_REP(dmpGetArrayLength(key, value)); + AssertMapAndKeyExist(GetArrayOrStringLength, key, ": key %016llX", key); + DWORD value = GetArrayOrStringLength->Get(key); + DEBUG_REP(dmpGetArrayOrStringLength(key, value)); return value != 0; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index d8359c23503322..c3e2fdabfde699 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -876,9 +876,9 @@ class MethodContext void dmpIsFieldStatic(DWORDLONG key, DWORD value); bool repIsFieldStatic(CORINFO_FIELD_HANDLE fhld); - void recGetArrayLength(CORINFO_OBJECT_HANDLE objHnd, int result); - void dmpGetArrayLength(DWORDLONG key, DWORD value); - int repGetArrayLength(CORINFO_OBJECT_HANDLE objHnd); + 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); @@ -1153,7 +1153,7 @@ enum mcPackets Packet_GetObjectType = 199, Packet_IsObjectImmutable = 200, Packet_ExpandRawHandleIntrinsic = 201, - Packet_GetArrayLength = 202, + 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 25bfb3d7dfb7a6..aeb42b4a3f8a19 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1127,7 +1127,7 @@ int interceptor_ICJI::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) { mc->cr->AddCall("getArrayLength"); int result = original_ICorJitInfo->getArrayLength(objHnd); - mc->recGetArrayLength(objHnd, result); + mc->recGetArrayOrStringLength(objHnd, 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 d1b07b4ef41b17..c9bb221333a325 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -787,11 +787,11 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } -int interceptor_ICJI::getArrayLength( +int interceptor_ICJI::getArrayOrStringLength( CORINFO_OBJECT_HANDLE objHnd) { - mcs->AddCall("getArrayLength"); - return original_ICorJitInfo->getArrayLength(objHnd); + mcs->AddCall("getArrayOrStringLength"); + return original_ICorJitInfo->getArrayOrStringLength(objHnd); } void interceptor_ICJI::getBoundaries( 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 5525675e270d8e..6f5367b1fbff6e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -689,10 +689,10 @@ bool interceptor_ICJI::isFieldStatic( return original_ICorJitInfo->isFieldStatic(fldHnd); } -int interceptor_ICJI::getArrayLength( +int interceptor_ICJI::getArrayOrStringLength( CORINFO_OBJECT_HANDLE objHnd) { - return original_ICorJitInfo->getArrayLength(objHnd); + return original_ICorJitInfo->getArrayOrStringLength(objHnd); } void interceptor_ICJI::getBoundaries( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index be82250730f2f9..cebb456c7afebd 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -948,10 +948,10 @@ bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return jitInstance->mc->repIsFieldStatic(fldHnd); } -int MyICJI::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +int MyICJI::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) { - jitInstance->mc->cr->AddCall("getArrayLength"); - return jitInstance->mc->repGetArrayLength(objHnd); + jitInstance->mc->cr->AddCall("getArrayOrStringLength"); + return jitInstance->mc->repGetArrayOrStringLength(objHnd); } /*********************************************************************************/ diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 1d4ca6e26e8efc..e80248e14893eb 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1721,7 +1721,7 @@ bool CEEInfo::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return res; } -int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +int CEEInfo::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) { CONTRACTL { THROWS; @@ -1736,7 +1736,7 @@ int CEEInfo::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) GCX_COOP(); - Object* obj = getObjectFromJitHandle(objHnd); + Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHnd); if (obj->GetMethodTable()->IsArray()) { @@ -2512,23 +2512,6 @@ void CEEInfo::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd) pMD->AsDynamicMethodDesc()->GetResolver()->FreeCompileTimeState(); } - // 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++) - { - size_t elementHandle = (size_t)elements[i]; - // All jit handles have the lowest bit set ("it's not a frozen object" marker) - // Clear it here. - _ASSERT(elementHandle & 1); - ::DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); - } - delete m_pJitHandles; - m_pJitHandles = nullptr; - } - EE_TO_JIT_TRANSITION(); } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 255b6419b4524a..d064a11dd6cf65 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -510,6 +510,25 @@ 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++) + { + size_t elementHandle = (size_t)elements[i]; + // All jit handles have the lowest bit set ("it's not a frozen object" marker) + // Clear it here. + _ASSERT(elementHandle & 1); + DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); + } + delete m_pJitHandles; + m_pJitHandles = nullptr; + } +#endif } // Performs any work JIT-related work that should be performed at process shutdown. From 1bba1ec9ee1c77ec94638d126432f89aee49fb89 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 29 Oct 2022 18:12:52 +0200 Subject: [PATCH 14/41] fix compilation --- .../tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index aeb42b4a3f8a19..75d5a6f43749c7 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1123,10 +1123,10 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) return result; } -int interceptor_ICJI::getArrayLength(CORINFO_OBJECT_HANDLE objHnd) +int interceptor_ICJI::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) { - mc->cr->AddCall("getArrayLength"); - int result = original_ICorJitInfo->getArrayLength(objHnd); + mc->cr->AddCall("getArrayOrStringLength"); + int result = original_ICorJitInfo->getArrayOrStringLength(objHnd); mc->recGetArrayOrStringLength(objHnd, result); return result; } From ee0117ec3e51cef2aa1fbef7814df3b67b552003 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Oct 2022 16:19:15 +0200 Subject: [PATCH 15/41] Use IND instead of LoadVector --- src/coreclr/jit/hwintrinsicxarch.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 7c2d84264fb5f0..2c351b52281dbc 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1815,22 +1815,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, op1 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2); } - NamedIntrinsic loadIntrinsic = NI_Illegal; - - if (simdSize == 32) - { - loadIntrinsic = NI_AVX_LoadVector256; - } - else if (simdBaseType != TYP_FLOAT) - { - loadIntrinsic = NI_SSE2_LoadVector128; - } - else - { - loadIntrinsic = NI_SSE_LoadVector128; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); + retNode = gtNewIndir(retType, op1); break; } From b20f1fbcfa0b462ed8ec3d01ade4ed3e0af8d590 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 30 Oct 2022 19:03:06 +0200 Subject: [PATCH 16/41] Update hwintrinsicxarch.cpp --- src/coreclr/jit/hwintrinsicxarch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 2c351b52281dbc..61e554d7c53e30 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1816,6 +1816,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, } retNode = gtNewIndir(retType, op1); + retNode->gtFlags |= GTF_IND_UNALIGNED; break; } From 2a12b109a36ec2237d528d08fc5bfad05194cbf6 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 30 Oct 2022 19:36:11 +0200 Subject: [PATCH 17/41] Update hwintrinsicxarch.cpp --- src/coreclr/jit/hwintrinsicxarch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 61e554d7c53e30..47637c792de6fc 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1816,7 +1816,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, } retNode = gtNewIndir(retType, op1); - retNode->gtFlags |= GTF_IND_UNALIGNED; + retNode->gtFlags |= GTF_IND_UNALIGNED | GTF_GLOB_REF; break; } From 504acf36251fab9f6f55041cbc28e35bccacf9e4 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 30 Oct 2022 21:58:09 +0200 Subject: [PATCH 18/41] Apply suggestions from code review Co-authored-by: Jan Kotas --- src/coreclr/vm/jitinterface.cpp | 7 +++---- src/coreclr/vm/jitinterface.h | 6 +----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e80248e14893eb..39c6257aa85bcb 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2889,7 +2889,7 @@ void CEEInfo::ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, ScanToken(pModule, pResolvedToken, th, pMD); } -OBJECTHANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) +CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) { CONTRACTL { @@ -2910,13 +2910,12 @@ OBJECTHANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) // We know that handle is aligned so we use the lowest bit as a marker // "this is a handle, not a frozen object". - handle = (OBJECTHANDLE)((size_t)handle | 1); m_pJitHandles->Append(handle); GCPROTECT_END(); - return handle; + return (CORINFO_OBJECT_HANDLE)((size_t)handle | 1); } -Object* CEEInfo::getObjectFromJitHandle(OBJECTHANDLE handle) +Object* CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) { CONTRACTL { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index d064a11dd6cf65..eb3f31a0e3afeb 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -519,11 +519,7 @@ class CEEInfo : public ICorJitInfo unsigned count = m_pJitHandles->GetCount(); for (unsigned i = 0; i < count; i++) { - size_t elementHandle = (size_t)elements[i]; - // All jit handles have the lowest bit set ("it's not a frozen object" marker) - // Clear it here. - _ASSERT(elementHandle & 1); - DestroyHandle((OBJECTHANDLE)(elementHandle - 1)); + DestroyHandle(elements[i]); } delete m_pJitHandles; m_pJitHandles = nullptr; From b56a67f0d6fb5b4c4815c527f304e1f93cb157f8 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Oct 2022 22:34:49 +0200 Subject: [PATCH 19/41] Address feedback --- src/coreclr/vm/jitinterface.cpp | 20 ++++++++++---------- src/coreclr/vm/jitinterface.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 39c6257aa85bcb..423d4ca720ac7c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1736,7 +1736,7 @@ int CEEInfo::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) GCX_COOP(); - Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHnd); + Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHnd)); if (obj->GetMethodTable()->IsArray()) { @@ -2915,7 +2915,7 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) return (CORINFO_OBJECT_HANDLE)((size_t)handle | 1); } -Object* CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) +OBJECTREF CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) { CONTRACTL { @@ -2928,11 +2928,11 @@ Object* CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) size_t intHandle = (size_t)handle; if (intHandle & 1) { - return *(Object**)(intHandle - 1); + return ObjectToOBJECTREF(*(Object**)(intHandle - 1)); } // Frozen object - return (Object*)intHandle; + return ObjectToOBJECTREF((Object*)intHandle); } MethodDesc * CEEInfo::GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle) @@ -6130,7 +6130,7 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHandle); + Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHandle)); MethodTable* type = obj->GetMethodTable(); _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); @@ -6158,7 +6158,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objHandle) JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = getObjectFromJitHandle((OBJECTHANDLE)objHandle); + Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHandle)); VALIDATEOBJECT(obj); handle = (CORINFO_CLASS_HANDLE)obj->GetMethodTable(); @@ -11999,17 +11999,17 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t if (fieldObj != NULL) { Object* obj = OBJECTREFToObject(fieldObj); - OBJECTHANDLE handle; + CORINFO_OBJECT_HANDLE handle; if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { - handle = (OBJECTHANDLE)obj; - memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); + handle = (CORINFO_OBJECT_HANDLE)obj; + memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); result = true; } else if (!ignoreMovableObjects) { handle = getJitHandleForObject(fieldObj); - memcpy(buffer, &handle, sizeof(OBJECTHANDLE)); + memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); result = true; } } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index eb3f31a0e3afeb..00787777d45512 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -596,8 +596,8 @@ class CEEInfo : public ICorJitInfo return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled; } - OBJECTHANDLE getJitHandleForObject(OBJECTREF obj); - Object* getObjectFromJitHandle(OBJECTHANDLE handle); + CORINFO_OBJECT_HANDLE getJitHandleForObject(OBJECTREF obj); + OBJECTREF getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle); // Cache of last GetMethodForSecurity() lookup CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key; From 15a39a663b9cf9beef6aecbce83de50a35127f5b Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Oct 2022 23:20:37 +0200 Subject: [PATCH 20/41] Address feedback --- src/coreclr/vm/jitinterface.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 423d4ca720ac7c..54a078c58aed0f 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -737,10 +737,8 @@ size_t CEEInfo::printObjectDescription ( JIT_TO_EE_TRANSITION(); - Object* obj = (Object*)handle; - GCX_COOP(); - + Object* obj = OBJECTREFToObject(getObjectFromJitHandle(handle)); StackSString stackStr; // Currently only supported for String and RuntimeType From 1683f2926288962a18a203b429e651a9595665ce Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Oct 2022 23:29:05 +0200 Subject: [PATCH 21/41] Address feedback --- src/coreclr/vm/jitinterface.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 54a078c58aed0f..236683b57e369b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2902,15 +2902,13 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) m_pJitHandles = new SArray(); } - OBJECTHANDLE handle; - GCPROTECT_BEGIN(obj); - handle = AppDomain::GetCurrentDomain()->CreateHandle(obj); + OBJECTHANDLEHolder handle = AppDomain::GetCurrentDomain()->CreateHandle(obj); + 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". - m_pJitHandles->Append(handle); - GCPROTECT_END(); - return (CORINFO_OBJECT_HANDLE)((size_t)handle | 1); + return (CORINFO_OBJECT_HANDLE)((size_t)handle.GetValue() | 1); } OBJECTREF CEEInfo::getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle) From 43a32c9207f04749283134936257ff28e4b1261a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 30 Oct 2022 23:49:35 +0200 Subject: [PATCH 22/41] Move "Is frozen" check to getJitHandleForObject --- src/coreclr/vm/jitinterface.cpp | 12 +++++++++--- src/coreclr/vm/jitinterface.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 236683b57e369b..10d563952d6ed6 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2887,7 +2887,7 @@ void CEEInfo::ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, ScanToken(pModule, pResolvedToken, th, pMD); } -CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) +CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF objref, bool knownFrozen) { CONTRACTL { @@ -2902,7 +2902,13 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF obj) m_pJitHandles = new SArray(); } - OBJECTHANDLEHolder handle = AppDomain::GetCurrentDomain()->CreateHandle(obj); + Object* obj = OBJECTREFToObject(objref); + if (knownFrozen || GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + { + return (CORINFO_OBJECT_HANDLE)obj; + } + + OBJECTHANDLEHolder handle = AppDomain::GetCurrentDomain()->CreateHandle(objref); m_pJitHandles->Append(handle); handle.SuppressRelease(); @@ -11998,7 +12004,7 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t CORINFO_OBJECT_HANDLE handle; if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { - handle = (CORINFO_OBJECT_HANDLE)obj; + handle = getJitHandleForObject(fieldObj, true); memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); result = true; } diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 00787777d45512..c0fcb0a92fb72f 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -596,7 +596,7 @@ class CEEInfo : public ICorJitInfo return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled; } - CORINFO_OBJECT_HANDLE getJitHandleForObject(OBJECTREF obj); + CORINFO_OBJECT_HANDLE getJitHandleForObject(OBJECTREF objref, bool knownFrozen = false); OBJECTREF getObjectFromJitHandle(CORINFO_OBJECT_HANDLE handle); // Cache of last GetMethodForSecurity() lookup From d10f4eb0dbc480b46b907f68d2d2dc0c23831c6e Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 31 Oct 2022 00:05:17 +0200 Subject: [PATCH 23/41] Update src/coreclr/vm/jitinterface.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/jitinterface.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 10d563952d6ed6..cb1f8c0c634de3 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2897,17 +2897,17 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF objref, bool know } CONTRACTL_END; - if (m_pJitHandles == nullptr) - { - m_pJitHandles = new SArray(); - } - 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(); From 4443383320fa1fbbfcb1f72d2c704b3c537d6d7b Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 31 Oct 2022 00:06:33 +0200 Subject: [PATCH 24/41] Update src/coreclr/vm/jitinterface.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/jitinterface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index cb1f8c0c634de3..674d5ae61ab579 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1734,15 +1734,15 @@ int CEEInfo::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) GCX_COOP(); - Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHnd)); + OBJECTREF obj = getObjectFromJitHandle(objHnd); if (obj->GetMethodTable()->IsArray()) { - arrLen = ((ArrayBase*)obj)->GetNumComponents(); + arrLen = ((BASEARRAYREF)obj)->GetNumComponents(); } else if (obj->GetMethodTable()->IsString()) { - arrLen = ((StringObject*)obj)->GetStringLength(); + arrLen = ((STRINGREF)obj)->GetStringLength(); } else { From 429b4d1e32c2abb2ffed4f7939e0e9d6ed095c0f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 00:13:42 +0200 Subject: [PATCH 25/41] use OBJECTREF everywhere --- src/coreclr/vm/jitinterface.cpp | 23 +++++++++++------------ src/coreclr/vm/object.h | 2 ++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 674d5ae61ab579..a5f83d612969f1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -738,17 +738,17 @@ size_t CEEInfo::printObjectDescription ( JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = OBJECTREFToObject(getObjectFromJitHandle(handle)); + 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 { @@ -1738,7 +1738,7 @@ int CEEInfo::getArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd) if (obj->GetMethodTable()->IsArray()) { - arrLen = ((BASEARRAYREF)obj)->GetNumComponents(); + arrLen = ((ARRAYBASEREF)obj)->GetNumComponents(); } else if (obj->GetMethodTable()->IsString()) { @@ -2897,15 +2897,15 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF objref, bool know } CONTRACTL_END; - Object* obj = OBJECTREFToObject(objref); - if (knownFrozen || GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + if (m_pJitHandles == nullptr) { - return (CORINFO_OBJECT_HANDLE)obj; + m_pJitHandles = new SArray(); } - if (m_pJitHandles == nullptr) + Object* obj = OBJECTREFToObject(objref); + if (knownFrozen || GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) { - m_pJitHandles = new SArray(); + return (CORINFO_OBJECT_HANDLE)obj; } OBJECTHANDLEHolder handle = AppDomain::GetCurrentDomain()->CreateHandle(objref); @@ -6132,7 +6132,7 @@ bool CEEInfo::isObjectImmutable(CORINFO_OBJECT_HANDLE objHandle) JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHandle)); + OBJECTREF obj = getObjectFromJitHandle(objHandle); MethodTable* type = obj->GetMethodTable(); _ASSERTE(type->IsString() || type == g_pRuntimeTypeClass); @@ -6160,8 +6160,7 @@ CORINFO_CLASS_HANDLE CEEInfo::getObjectType(CORINFO_OBJECT_HANDLE objHandle) JIT_TO_EE_TRANSITION(); GCX_COOP(); - Object* obj = OBJECTREFToObject(getObjectFromJitHandle(objHandle)); - VALIDATEOBJECT(obj); + OBJECTREF obj = getObjectFromJitHandle(objHandle); handle = (CORINFO_CLASS_HANDLE)obj->GetMethodTable(); EE_TO_JIT_TRANSITION(); diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 1b7f140aae89f1..0f4fa67b3c1e8d 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -834,6 +834,7 @@ typedef REF UPTRARRAYREF; typedef REF CHARARRAYREF; typedef REF PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays. typedef REF STRINGREF; +typedef REF REFLECTCLASSBASEREF; #else // USE_CHECKED_OBJECTREFS @@ -853,6 +854,7 @@ typedef PTR_UPTRArray UPTRARRAYREF; typedef PTR_CHARArray CHARARRAYREF; typedef PTR_PTRArray PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays. typedef PTR_StringObject STRINGREF; +typedef PTR_ReflectClassBaseObject REFLECTCLASSBASEREF #endif // USE_CHECKED_OBJECTREFS From 49c32c468c79968ab019699da647d9b2cc21c9e0 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 00:15:50 +0200 Subject: [PATCH 26/41] fix bad merge --- src/coreclr/vm/jitinterface.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a5f83d612969f1..8020bb6598a9ca 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2897,17 +2897,17 @@ CORINFO_OBJECT_HANDLE CEEInfo::getJitHandleForObject(OBJECTREF objref, bool know } CONTRACTL_END; - if (m_pJitHandles == nullptr) - { - m_pJitHandles = new SArray(); - } - 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(); From 5dbbef4ba9b3bb1a50b03326a9e83d00e0e6c9fc Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 00:42:49 +0200 Subject: [PATCH 27/41] Cannonize more loads --- src/coreclr/jit/hwintrinsicarm64.cpp | 51 ++++------------------------ src/coreclr/jit/hwintrinsicxarch.cpp | 42 ++++------------------- 2 files changed, 13 insertions(+), 80 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 4a77e3ac77a56a..ab5cdbf49c5834 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1242,38 +1242,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector64_Load: - case NI_Vector128_Load: - { - assert(sig->numArgs == 1); - - op1 = impPopStack().val; - - if (op1->OperIs(GT_CAST)) - { - // Although the API specifies a pointer, if what we have is a BYREF, that's what - // we really want, so throw away the cast. - if (op1->gtGetOp1()->TypeGet() == TYP_BYREF) - { - op1 = op1->gtGetOp1(); - } - } - - NamedIntrinsic loadIntrinsic = NI_Illegal; - - if (simdSize == 16) - { - loadIntrinsic = NI_AdvSimd_LoadVector128; - } - else - { - loadIntrinsic = NI_AdvSimd_LoadVector64; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); - break; - } - case NI_Vector64_LoadAligned: case NI_Vector128_LoadAligned: { @@ -1354,11 +1322,16 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_AdvSimd_LoadVector64: + case NI_AdvSimd_LoadVector128: + case NI_Vector64_Load: + case NI_Vector128_Load: case NI_Vector64_LoadUnsafe: case NI_Vector128_LoadUnsafe: { if (sig->numArgs == 2) { + assert((intrinsic == NI_Vector128_LoadUnsafe) || (intrinsic == NI_Vector64_LoadUnsafe)); op2 = impPopStack().val; } else @@ -1385,18 +1358,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op1 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2); } - NamedIntrinsic loadIntrinsic = NI_Illegal; - - if (simdSize == 16) - { - loadIntrinsic = NI_AdvSimd_LoadVector128; - } - else - { - loadIntrinsic = NI_AdvSimd_LoadVector64; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); + retNode = gtNewIndir(retType, op1); + retNode->gtFlags |= GTF_IND_UNALIGNED | GTF_GLOB_REF; break; } diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 47637c792de6fc..96829bafe7e491 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1657,42 +1657,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector128_Load: - case NI_Vector256_Load: - { - assert(sig->numArgs == 1); - - op1 = impPopStack().val; - - if (op1->OperIs(GT_CAST)) - { - // Although the API specifies a pointer, if what we have is a BYREF, that's what - // we really want, so throw away the cast. - if (op1->gtGetOp1()->TypeGet() == TYP_BYREF) - { - op1 = op1->gtGetOp1(); - } - } - - NamedIntrinsic loadIntrinsic = NI_Illegal; - - if (simdSize == 32) - { - loadIntrinsic = NI_AVX_LoadVector256; - } - else if (simdBaseType != TYP_FLOAT) - { - loadIntrinsic = NI_SSE2_LoadVector128; - } - else - { - loadIntrinsic = NI_SSE_LoadVector128; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); - break; - } - case NI_Vector128_LoadAligned: case NI_Vector256_LoadAligned: { @@ -1784,11 +1748,17 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_SSE_LoadVector128: + case NI_SSE2_LoadVector128: + case NI_AVX_LoadVector256: + case NI_Vector128_Load: + case NI_Vector256_Load: case NI_Vector128_LoadUnsafe: case NI_Vector256_LoadUnsafe: { if (sig->numArgs == 2) { + assert((intrinsic == NI_Vector128_LoadUnsafe) || (intrinsic == NI_Vector256_LoadUnsafe)); op2 = impPopStack().val; } else From 62f5cbb78a6465a084957e1773a43f733d2d536c Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 00:49:57 +0200 Subject: [PATCH 28/41] check ISAs --- src/coreclr/jit/hwintrinsicarm64.cpp | 7 +++++++ src/coreclr/jit/hwintrinsicxarch.cpp | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index ab5cdbf49c5834..78c65f1020c165 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1339,6 +1339,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); } + if (((intrinsic == NI_AdvSimd_LoadVector64) || (intrinsic == NI_AdvSimd_LoadVector128)) && + !compOpportunisticallyDependsOn(InstructionSet_AdvSimd)) + { + // Only canonize explicit loads when we have corresponding ISAs available + break; + } + op1 = impPopStack().val; if (op1->OperIs(GT_CAST)) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 96829bafe7e491..8b1270e0d57877 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1766,6 +1766,14 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); } + if (((intrinsic == NI_SSE_LoadVector128) && !compOpportunisticallyDependsOn(InstructionSet_SSE)) || + ((intrinsic == NI_SSE2_LoadVector128) && !compOpportunisticallyDependsOn(InstructionSet_SSE2)) || + ((intrinsic == NI_AVX_LoadVector256) && !compOpportunisticallyDependsOn(InstructionSet_AVX))) + { + // Only canonize explicit loads when we have corresponding ISAs available + break; + } + op1 = impPopStack().val; if (op1->OperIs(GT_CAST)) From a096211beea0d56e4139945f12fa9f339c1bf32c Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 00:52:58 +0200 Subject: [PATCH 29/41] Fix comments --- src/coreclr/jit/hwintrinsicarm64.cpp | 4 ++-- src/coreclr/jit/hwintrinsicxarch.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 78c65f1020c165..517ec81350587a 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1340,9 +1340,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } if (((intrinsic == NI_AdvSimd_LoadVector64) || (intrinsic == NI_AdvSimd_LoadVector128)) && - !compOpportunisticallyDependsOn(InstructionSet_AdvSimd)) + !compExactlyDependsOn(InstructionSet_AdvSimd)) { - // Only canonize explicit loads when we have corresponding ISAs available + // Use IND for explicit loads only when we have corresponding ISAs available break; } diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 8b1270e0d57877..dfdc9d1d049b9b 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1766,11 +1766,11 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); } - if (((intrinsic == NI_SSE_LoadVector128) && !compOpportunisticallyDependsOn(InstructionSet_SSE)) || - ((intrinsic == NI_SSE2_LoadVector128) && !compOpportunisticallyDependsOn(InstructionSet_SSE2)) || - ((intrinsic == NI_AVX_LoadVector256) && !compOpportunisticallyDependsOn(InstructionSet_AVX))) + if (((intrinsic == NI_SSE_LoadVector128) && !compExactlyDependsOn(InstructionSet_SSE)) || + ((intrinsic == NI_SSE2_LoadVector128) && !compExactlyDependsOn(InstructionSet_SSE2)) || + ((intrinsic == NI_AVX_LoadVector256) && !compExactlyDependsOn(InstructionSet_AVX))) { - // Only canonize explicit loads when we have corresponding ISAs available + // Use IND for explicit loads only when we have corresponding ISAs available break; } From efd71e95d6217dc067eaaa306a03a89cc93a7d67 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 03:41:34 +0200 Subject: [PATCH 30/41] Handle stores --- src/coreclr/jit/hwintrinsicarm64.cpp | 31 +++----------- src/coreclr/jit/hwintrinsicxarch.cpp | 64 ++++------------------------ 2 files changed, 16 insertions(+), 79 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 517ec81350587a..4e041e614dbce6 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1339,13 +1339,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); } - if (((intrinsic == NI_AdvSimd_LoadVector64) || (intrinsic == NI_AdvSimd_LoadVector128)) && - !compExactlyDependsOn(InstructionSet_AdvSimd)) - { - // Use IND for explicit loads only when we have corresponding ISAs available - break; - } - op1 = impPopStack().val; if (op1->OperIs(GT_CAST)) @@ -1574,22 +1567,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector64_Store: - case NI_Vector128_Store: - { - assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); - - impSpillSideEffect(true, - verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); - - op2 = impPopStack().val; - op1 = impSIMDPopStack(simdType); - - retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize); - break; - } - case NI_Vector64_StoreAligned: case NI_Vector128_StoreAligned: { @@ -1638,6 +1615,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_AdvSimd_Store: + case NI_Vector64_Store: + case NI_Vector128_Store: case NI_Vector64_StoreUnsafe: case NI_Vector128_StoreUnsafe: { @@ -1645,6 +1625,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (sig->numArgs == 3) { + assert((intrinsic == NI_Vector128_StoreUnsafe) || (intrinsic == NI_Vector64_StoreUnsafe)); impSpillSideEffect(true, verCurrentState.esStackDepth - 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); @@ -1671,7 +1652,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3); } - retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize); + retNode = gtNewOperNode(GT_IND, simdType, op2); + retNode->gtFlags |= (GTF_GLOB_REF | GTF_IND_UNALIGNED); + retNode = gtNewAssignNode(retNode, op1); break; } diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index dfdc9d1d049b9b..1e27dde676075d 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1766,14 +1766,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 1); } - if (((intrinsic == NI_SSE_LoadVector128) && !compExactlyDependsOn(InstructionSet_SSE)) || - ((intrinsic == NI_SSE2_LoadVector128) && !compExactlyDependsOn(InstructionSet_SSE2)) || - ((intrinsic == NI_AVX_LoadVector256) && !compExactlyDependsOn(InstructionSet_AVX))) - { - // Use IND for explicit loads only when we have corresponding ISAs available - break; - } - op1 = impPopStack().val; if (op1->OperIs(GT_CAST)) @@ -2120,37 +2112,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector128_Store: - case NI_Vector256_Store: - { - assert(sig->numArgs == 2); - var_types simdType = getSIMDTypeForSize(simdSize); - - impSpillSideEffect(true, - verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); - - op2 = impPopStack().val; - op1 = impSIMDPopStack(simdType); - - NamedIntrinsic storeIntrinsic = NI_Illegal; - - if (simdSize == 32) - { - storeIntrinsic = NI_AVX_Store; - } - else if (simdBaseType != TYP_FLOAT) - { - storeIntrinsic = NI_SSE2_Store; - } - else - { - storeIntrinsic = NI_SSE_Store; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, storeIntrinsic, simdBaseJitType, simdSize); - break; - } - case NI_Vector128_StoreAligned: case NI_Vector256_StoreAligned: { @@ -2213,6 +2174,11 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_SSE_Store: + case NI_SSE2_Store: + case NI_AVX_Store: + case NI_Vector128_Store: + case NI_Vector256_Store: case NI_Vector128_StoreUnsafe: case NI_Vector256_StoreUnsafe: { @@ -2220,6 +2186,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (sig->numArgs == 3) { + assert((intrinsic == NI_Vector128_StoreUnsafe) || (intrinsic == NI_Vector256_StoreUnsafe)); impSpillSideEffect(true, verCurrentState.esStackDepth - 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); @@ -2246,22 +2213,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3); } - NamedIntrinsic storeIntrinsic = NI_Illegal; - - if (simdSize == 32) - { - storeIntrinsic = NI_AVX_Store; - } - else if (simdBaseType != TYP_FLOAT) - { - storeIntrinsic = NI_SSE2_Store; - } - else - { - storeIntrinsic = NI_SSE_Store; - } - - retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, storeIntrinsic, simdBaseJitType, simdSize); + retNode = gtNewOperNode(GT_IND, simdType, op2); + retNode->gtFlags |= (GTF_GLOB_REF | GTF_IND_UNALIGNED); + retNode = gtNewAssignNode(retNode, op1); break; } From 27a26193e30d7f5070b852d08219f5aa2b59b12e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 03:51:55 +0200 Subject: [PATCH 31/41] Fix compilation & address feedback around redundant IsFrozenSegment call --- src/coreclr/vm/jitinterface.cpp | 15 +++++++++------ src/coreclr/vm/object.h | 2 -- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 8020bb6598a9ca..f6ecda4dfd6f22 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12001,17 +12001,20 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t { Object* obj = OBJECTREFToObject(fieldObj); CORINFO_OBJECT_HANDLE handle; - if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + + if (ignoreMovableObjects) { - handle = getJitHandleForObject(fieldObj, true); - memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); - result = true; + if (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj)) + { + handle = getJitHandleForObject(fieldObj, true); + memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); + result = true; + } } - else if (!ignoreMovableObjects) + else { handle = getJitHandleForObject(fieldObj); memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); - result = true; } } else diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 0f4fa67b3c1e8d..1b7f140aae89f1 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -834,7 +834,6 @@ typedef REF UPTRARRAYREF; typedef REF CHARARRAYREF; typedef REF PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays. typedef REF STRINGREF; -typedef REF REFLECTCLASSBASEREF; #else // USE_CHECKED_OBJECTREFS @@ -854,7 +853,6 @@ typedef PTR_UPTRArray UPTRARRAYREF; typedef PTR_CHARArray CHARARRAYREF; typedef PTR_PTRArray PTRARRAYREF; // Warning: Use PtrArray only for single dimensional arrays, not multidim arrays. typedef PTR_StringObject STRINGREF; -typedef PTR_ReflectClassBaseObject REFLECTCLASSBASEREF #endif // USE_CHECKED_OBJECTREFS From d5c3cab76bbcd239152aef898804a85d248ad7b9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 12:15:45 +0200 Subject: [PATCH 32/41] DescriptionDescription -> Description --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/ee_il_dll.cpp | 2 +- src/coreclr/jit/emit.cpp | 2 +- src/coreclr/jit/gentree.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index a949179c7f1e33..41feee494fb83a 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7779,7 +7779,7 @@ class Compiler const char* eeGetFieldName(CORINFO_FIELD_HANDLE fieldHnd, const char** classNamePtr = nullptr); #if defined(DEBUG) - void eePrintObjectDescriptionDescription(const char* prefix, CORINFO_OBJECT_HANDLE 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 5e55e8dd1fc025..1b8dd208aa7c28 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, CORINFO_OBJECT_HANDLE handle) +void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle) { const size_t maxStrSize = 64; char str[maxStrSize]; diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 82d542a88340be..a7644c3bcbd0f1 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, (CORINFO_OBJECT_HANDLE)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 b2833bbd610e32..eefcf1d9364bca 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(" ", (CORINFO_OBJECT_HANDLE)tree->AsIntCon()->gtIconVal); + eePrintObjectDescription(" ", (CORINFO_OBJECT_HANDLE)tree->AsIntCon()->gtIconVal); } else { From 96397b126c53fb4e1b99826ba8ca45dd97dae75d Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 31 Oct 2022 13:00:43 +0200 Subject: [PATCH 33/41] Update valuenum.cpp --- src/coreclr/jit/valuenum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index b5f63faa6e1282..cbfdd4863732ea 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8821,7 +8821,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) if (this->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, TARGET_POINTER_SIZE, false)) { - CORINFO_OBJECT_HANDLE objHandle; + CORINFO_OBJECT_HANDLE objHandle = NULL; memcpy(&objHandle, buffer, TARGET_POINTER_SIZE); int len = this->info.compCompHnd->getArrayOrStringLength(objHandle); if (len >= 0) From 076d4cdd3ea014d8980594b73418ee71a44ada4d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 13:23:47 +0200 Subject: [PATCH 34/41] Add comments --- src/coreclr/jit/valuenum.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index cbfdd4863732ea..3e5257c83426d9 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8821,6 +8821,9 @@ void Compiler::fgValueNumberTree(GenTree* tree) if (this->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 = this->info.compCompHnd->getArrayOrStringLength(objHandle); From 752c8403572187d1a597cd2e64954be5e40b73c5 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 18:16:37 +0200 Subject: [PATCH 35/41] Revert unrelated SIMD changes (accidentally pushed) --- src/coreclr/jit/hwintrinsicarm64.cpp | 75 +++++++++++++---- src/coreclr/jit/hwintrinsicxarch.cpp | 116 +++++++++++++++++++++++---- 2 files changed, 160 insertions(+), 31 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 4e041e614dbce6..4a77e3ac77a56a 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1242,6 +1242,38 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector64_Load: + case NI_Vector128_Load: + { + assert(sig->numArgs == 1); + + op1 = impPopStack().val; + + if (op1->OperIs(GT_CAST)) + { + // Although the API specifies a pointer, if what we have is a BYREF, that's what + // we really want, so throw away the cast. + if (op1->gtGetOp1()->TypeGet() == TYP_BYREF) + { + op1 = op1->gtGetOp1(); + } + } + + NamedIntrinsic loadIntrinsic = NI_Illegal; + + if (simdSize == 16) + { + loadIntrinsic = NI_AdvSimd_LoadVector128; + } + else + { + loadIntrinsic = NI_AdvSimd_LoadVector64; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_LoadAligned: case NI_Vector128_LoadAligned: { @@ -1322,16 +1354,11 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_AdvSimd_LoadVector64: - case NI_AdvSimd_LoadVector128: - case NI_Vector64_Load: - case NI_Vector128_Load: case NI_Vector64_LoadUnsafe: case NI_Vector128_LoadUnsafe: { if (sig->numArgs == 2) { - assert((intrinsic == NI_Vector128_LoadUnsafe) || (intrinsic == NI_Vector64_LoadUnsafe)); op2 = impPopStack().val; } else @@ -1358,8 +1385,18 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op1 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2); } - retNode = gtNewIndir(retType, op1); - retNode->gtFlags |= GTF_IND_UNALIGNED | GTF_GLOB_REF; + NamedIntrinsic loadIntrinsic = NI_Illegal; + + if (simdSize == 16) + { + loadIntrinsic = NI_AdvSimd_LoadVector128; + } + else + { + loadIntrinsic = NI_AdvSimd_LoadVector64; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); break; } @@ -1567,6 +1604,22 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector64_Store: + case NI_Vector128_Store: + { + assert(sig->numArgs == 2); + var_types simdType = getSIMDTypeForSize(simdSize); + + impSpillSideEffect(true, + verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); + + op2 = impPopStack().val; + op1 = impSIMDPopStack(simdType); + + retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize); + break; + } + case NI_Vector64_StoreAligned: case NI_Vector128_StoreAligned: { @@ -1615,9 +1668,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_AdvSimd_Store: - case NI_Vector64_Store: - case NI_Vector128_Store: case NI_Vector64_StoreUnsafe: case NI_Vector128_StoreUnsafe: { @@ -1625,7 +1675,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (sig->numArgs == 3) { - assert((intrinsic == NI_Vector128_StoreUnsafe) || (intrinsic == NI_Vector64_StoreUnsafe)); impSpillSideEffect(true, verCurrentState.esStackDepth - 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); @@ -1652,9 +1701,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3); } - retNode = gtNewOperNode(GT_IND, simdType, op2); - retNode->gtFlags |= (GTF_GLOB_REF | GTF_IND_UNALIGNED); - retNode = gtNewAssignNode(retNode, op1); + retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize); break; } diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 1e27dde676075d..7c2d84264fb5f0 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1657,6 +1657,42 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_Load: + case NI_Vector256_Load: + { + assert(sig->numArgs == 1); + + op1 = impPopStack().val; + + if (op1->OperIs(GT_CAST)) + { + // Although the API specifies a pointer, if what we have is a BYREF, that's what + // we really want, so throw away the cast. + if (op1->gtGetOp1()->TypeGet() == TYP_BYREF) + { + op1 = op1->gtGetOp1(); + } + } + + NamedIntrinsic loadIntrinsic = NI_Illegal; + + if (simdSize == 32) + { + loadIntrinsic = NI_AVX_LoadVector256; + } + else if (simdBaseType != TYP_FLOAT) + { + loadIntrinsic = NI_SSE2_LoadVector128; + } + else + { + loadIntrinsic = NI_SSE_LoadVector128; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); + break; + } + case NI_Vector128_LoadAligned: case NI_Vector256_LoadAligned: { @@ -1748,17 +1784,11 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_SSE_LoadVector128: - case NI_SSE2_LoadVector128: - case NI_AVX_LoadVector256: - case NI_Vector128_Load: - case NI_Vector256_Load: case NI_Vector128_LoadUnsafe: case NI_Vector256_LoadUnsafe: { if (sig->numArgs == 2) { - assert((intrinsic == NI_Vector128_LoadUnsafe) || (intrinsic == NI_Vector256_LoadUnsafe)); op2 = impPopStack().val; } else @@ -1785,8 +1815,22 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, op1 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2); } - retNode = gtNewIndir(retType, op1); - retNode->gtFlags |= GTF_IND_UNALIGNED | GTF_GLOB_REF; + NamedIntrinsic loadIntrinsic = NI_Illegal; + + if (simdSize == 32) + { + loadIntrinsic = NI_AVX_LoadVector256; + } + else if (simdBaseType != TYP_FLOAT) + { + loadIntrinsic = NI_SSE2_LoadVector128; + } + else + { + loadIntrinsic = NI_SSE_LoadVector128; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, loadIntrinsic, simdBaseJitType, simdSize); break; } @@ -2112,6 +2156,37 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_Store: + case NI_Vector256_Store: + { + assert(sig->numArgs == 2); + var_types simdType = getSIMDTypeForSize(simdSize); + + impSpillSideEffect(true, + verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); + + op2 = impPopStack().val; + op1 = impSIMDPopStack(simdType); + + NamedIntrinsic storeIntrinsic = NI_Illegal; + + if (simdSize == 32) + { + storeIntrinsic = NI_AVX_Store; + } + else if (simdBaseType != TYP_FLOAT) + { + storeIntrinsic = NI_SSE2_Store; + } + else + { + storeIntrinsic = NI_SSE_Store; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, storeIntrinsic, simdBaseJitType, simdSize); + break; + } + case NI_Vector128_StoreAligned: case NI_Vector256_StoreAligned: { @@ -2174,11 +2249,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_SSE_Store: - case NI_SSE2_Store: - case NI_AVX_Store: - case NI_Vector128_Store: - case NI_Vector256_Store: case NI_Vector128_StoreUnsafe: case NI_Vector256_StoreUnsafe: { @@ -2186,7 +2256,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (sig->numArgs == 3) { - assert((intrinsic == NI_Vector128_StoreUnsafe) || (intrinsic == NI_Vector256_StoreUnsafe)); impSpillSideEffect(true, verCurrentState.esStackDepth - 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); @@ -2213,9 +2282,22 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3); } - retNode = gtNewOperNode(GT_IND, simdType, op2); - retNode->gtFlags |= (GTF_GLOB_REF | GTF_IND_UNALIGNED); - retNode = gtNewAssignNode(retNode, op1); + NamedIntrinsic storeIntrinsic = NI_Illegal; + + if (simdSize == 32) + { + storeIntrinsic = NI_AVX_Store; + } + else if (simdBaseType != TYP_FLOAT) + { + storeIntrinsic = NI_SSE2_Store; + } + else + { + storeIntrinsic = NI_SSE_Store; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, storeIntrinsic, simdBaseJitType, simdSize); break; } From ea8e369e4affa19705303a6daa46dac5057a44b3 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 20:54:43 +0200 Subject: [PATCH 36/41] Use Exception sets --- src/coreclr/jit/valuenum.cpp | 30 ++++++++++++++++-------------- src/coreclr/jit/valuenumfuncs.h | 4 ++-- src/coreclr/vm/jitinterface.cpp | 1 + 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index e7f968d4155a17..396c74bf1555b8 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8701,20 +8701,14 @@ void Compiler::fgValueNumberTree(GenTree* tree) ((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 - ValueNum fieldSeqVN; - if ((loadFunc == VNF_InvariantNonNullLoad) && addr->IsIconHandle(GTF_ICON_CONST_PTR)) + // sequence to be able to fold their value + if ((loadFunc == VNF_InvariantNonNullLoad) && addr->IsIconHandle(GTF_ICON_CONST_PTR) && + addr->AsIntCon()->gtFieldSeq != nullptr) { - fieldSeqVN = vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq); - } - else - { - fieldSeqVN = vnStore->VNForNull(); + addrNvnp.SetBoth(vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq)); } - tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), loadFunc, addrNvnp, - ValueNumPair(fieldSeqVN, fieldSeqVN)); + tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), loadFunc, addrNvnp); tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp); } } @@ -8807,14 +8801,18 @@ void Compiler::fgValueNumberTree(GenTree* tree) if (tree->OperIs(GT_ARR_LENGTH)) { // Case 1: ARR_LENGTH(FROZEN_OBJ) - ValueNum addressVN = tree->gtGetOp1()->gtVNPair.GetLiberal(); + ValueNum addressVN = vnStore->VNNormalValue(tree->gtGetOp1()->gtVNPair.GetLiberal()); if (vnStore->IsVNHandle(addressVN) && (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) { size_t handle = vnStore->CoercedConstantValue(addressVN); int len = this->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); if (len >= 0) { + ValueNumPair op1vnp; + ValueNumPair op1Xvnp; + vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); return; } } @@ -8823,8 +8821,8 @@ void Compiler::fgValueNumberTree(GenTree* tree) VNFuncApp funcApp; if (vnStore->GetVNFunc(addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad)) { - ValueNum fieldSeqVN = funcApp.m_args[1]; - if ((fieldSeqVN != vnStore->VNForNull()) && (fieldSeqVN != ValueNumStore::NoVN)) + ValueNum fieldSeqVN = vnStore->VNNormalValue(funcApp.m_args[0]); + if (vnStore->IsVNHandle(fieldSeqVN) && (vnStore->GetHandleFlags(fieldSeqVN) == GTF_ICON_FIELD_SEQ)) { FieldSeq* fieldSeq = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); if (fieldSeq != nullptr) @@ -8844,7 +8842,11 @@ void Compiler::fgValueNumberTree(GenTree* tree) int len = this->info.compCompHnd->getArrayOrStringLength(objHandle); if (len >= 0) { + ValueNumPair op1vnp; + ValueNumPair op1Xvnp; + vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); return; } } diff --git a/src/coreclr/jit/valuenumfuncs.h b/src/coreclr/jit/valuenumfuncs.h index 19f253df9c407b..b8fcc8b7af66a1 100644 --- a/src/coreclr/jit/valuenumfuncs.h +++ b/src/coreclr/jit/valuenumfuncs.h @@ -144,8 +144,8 @@ ValueNumFuncDef(Box, 3, false, false, false) ValueNumFuncDef(BoxNullable, 3, false, false, false) ValueNumFuncDef(LazyStrCns, 2, false, true, false) // Lazy-initialized string literal (helper) -ValueNumFuncDef(InvariantLoad, 2, false, false, false) // Args: 0: (VN of) the address, 1: field sequence (if any). -ValueNumFuncDef(InvariantNonNullLoad, 2, false, true, false) // Args: 0: (VN of) the address, 1: field sequence (if any). +ValueNumFuncDef(InvariantLoad, 1, false, false, false) // Args: 0: (VN of) the address. +ValueNumFuncDef(InvariantNonNullLoad, 1, false, true, false) // Args: 0: (VN of) the address. ValueNumFuncDef(Unbox, 2, false, true, false) ValueNumFuncDef(LT_UN, 2, false, false, false) // unsigned or unordered comparisons diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 80fbef8f7f0aaa..3d0012cbd4119c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12013,6 +12013,7 @@ bool CEEInfo::getReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE fieldHnd, uint8_t { handle = getJitHandleForObject(fieldObj); memcpy(buffer, &handle, sizeof(CORINFO_OBJECT_HANDLE)); + result = true; } } else From 2fab46b441c5af521c4b585760e4af8a97ceecaa Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 21:15:26 +0200 Subject: [PATCH 37/41] Address feedback --- src/coreclr/jit/valuenum.cpp | 120 +++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 396c74bf1555b8..f555187539037b 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8797,79 +8797,87 @@ void Compiler::fgValueNumberTree(GenTree* tree) } else // Look up the VNFunc for the node { - // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable) - if (tree->OperIs(GT_ARR_LENGTH)) + VNFunc vnf = GetVNFuncForNode(tree); + + if (ValueNumStore::VNFuncIsLegal(vnf)) { - // Case 1: ARR_LENGTH(FROZEN_OBJ) - ValueNum addressVN = vnStore->VNNormalValue(tree->gtGetOp1()->gtVNPair.GetLiberal()); - if (vnStore->IsVNHandle(addressVN) && (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) + if (GenTree::OperIsUnary(oper)) { - size_t handle = vnStore->CoercedConstantValue(addressVN); - int len = this->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); - if (len >= 0) + if (tree->AsOp()->gtOp1 != nullptr) { - ValueNumPair op1vnp; - ValueNumPair op1Xvnp; - vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); - tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); - return; - } - } + bool foldedToConst = false; - // Case 2: ARR_LENGTH(static-readonly-field) - VNFuncApp funcApp; - if (vnStore->GetVNFunc(addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad)) - { - ValueNum fieldSeqVN = vnStore->VNNormalValue(funcApp.m_args[0]); - if (vnStore->IsVNHandle(fieldSeqVN) && (vnStore->GetHandleFlags(fieldSeqVN) == GTF_ICON_FIELD_SEQ)) - { - FieldSeq* fieldSeq = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); - if (fieldSeq != nullptr) + // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable) + if (tree->OperIs(GT_ARR_LENGTH)) { - CORINFO_FIELD_HANDLE field = fieldSeq->GetFieldHandle(); - if (field != NULL) + // Case 1: ARR_LENGTH(FROZEN_OBJ) + ValueNum addressVN = vnStore->VNNormalValue(tree->gtGetOp1()->gtVNPair.GetLiberal()); + if (vnStore->IsVNHandle(addressVN) && + (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) + { + size_t handle = vnStore->CoercedConstantValue(addressVN); + int len = this->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); + if (len >= 0) + { + ValueNumPair op1vnp; + ValueNumPair op1Xvnp; + vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); + tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); + foldedToConst = true; + } + } + + // Case 2: ARR_LENGTH(static-readonly-field) + VNFuncApp funcApp; + if (!foldedToConst && vnStore->GetVNFunc(addressVN, &funcApp) && + (funcApp.m_func == VNF_InvariantNonNullLoad)) { - uint8_t buffer[TARGET_POINTER_SIZE] = {0}; - if (this->info.compCompHnd->getReadonlyStaticFieldValue(field, buffer, - TARGET_POINTER_SIZE, false)) + ValueNum fieldSeqVN = vnStore->VNNormalValue(funcApp.m_args[0]); + if (vnStore->IsVNHandle(fieldSeqVN) && + (vnStore->GetHandleFlags(fieldSeqVN) == GTF_ICON_FIELD_SEQ)) { - // 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 = this->info.compCompHnd->getArrayOrStringLength(objHandle); - if (len >= 0) + FieldSeq* fieldSeq = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); + if (fieldSeq != nullptr) { - ValueNumPair op1vnp; - ValueNumPair op1Xvnp; - vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); - tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); - return; + CORINFO_FIELD_HANDLE field = fieldSeq->GetFieldHandle(); + if (field != NULL) + { + uint8_t buffer[TARGET_POINTER_SIZE] = {0}; + if (this->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 = this->info.compCompHnd->getArrayOrStringLength(objHandle); + if (len >= 0) + { + ValueNumPair op1vnp; + ValueNumPair op1Xvnp; + vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, + &op1Xvnp); + tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); + tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); + } + } + } } } } } - } - } - } - VNFunc vnf = GetVNFuncForNode(tree); - - if (ValueNumStore::VNFuncIsLegal(vnf)) - { - if (GenTree::OperIsUnary(oper)) - { - 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; } - else + else if (!foldedToConst) { ValueNumPair op1VNP; ValueNumPair op1VNPx; From 07d42e52e40bd1dd60e58f3c453d6959f7b6f86d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 21:18:26 +0200 Subject: [PATCH 38/41] Address feedback --- src/coreclr/jit/valuenum.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index f555187539037b..867d15aa8d2b16 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8849,10 +8849,8 @@ void Compiler::fgValueNumberTree(GenTree* tree) 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. + // 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 = this->info.compCompHnd->getArrayOrStringLength(objHandle); @@ -8864,6 +8862,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) &op1Xvnp); tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); + foldedToConst = true; } } } From 8c2ec2019c94bb03abb8fa9b0b5a4ce5402c6eb4 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 31 Oct 2022 21:31:38 +0200 Subject: [PATCH 39/41] Update src/coreclr/jit/valuenum.cpp Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/valuenum.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 867d15aa8d2b16..8577c9fd1ba911 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8703,7 +8703,8 @@ void Compiler::fgValueNumberTree(GenTree* tree) // 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 != nullptr) && + (addr->AsIntCon()->gtFieldSeq->GetOffset() == addr->AsIntCon()->IconValue()))) { addrNvnp.SetBoth(vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq)); } From 93c11c933ab9a32f98149257d782be2c82074c24 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Mon, 31 Oct 2022 21:49:37 +0200 Subject: [PATCH 40/41] Address feedback --- src/coreclr/jit/valuenum.cpp | 127 ++++++++++++++++------------------- 1 file changed, 58 insertions(+), 69 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 8577c9fd1ba911..2a35562b9505eb 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2083,9 +2083,64 @@ 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) + { + ValueNum op1vn; + ValueNum op1Xvn; + VNUnpackExc(arg0VN, &op1vn, &op1Xvn); + resultVN = VNExcSetUnion(VNForIntCon(len), op1Xvn); + } + } + + // 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) + { + ValueNum op1vn; + ValueNum op1Xvn; + VNUnpackExc(arg0VN, &op1vn, &op1Xvn); + resultVN = VNExcSetUnion(VNForIntCon(len), op1Xvn); + } + } + } + } + } + } + } + // Try to perform constant-folding. // - if (VNEvalCanFoldUnaryFunc(typ, func, arg0VN)) + if ((resultVN == NoVN) && VNEvalCanFoldUnaryFunc(typ, func, arg0VN)) { resultVN = EvalFuncForConstantArgs(typ, func, arg0VN); } @@ -8704,7 +8759,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) // 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()))) + (addr->AsIntCon()->gtFieldSeq->GetOffset() == addr->AsIntCon()->IconValue())) { addrNvnp.SetBoth(vnStore->VNForFieldSeq(addr->AsIntCon()->gtFieldSeq)); } @@ -8806,78 +8861,12 @@ void Compiler::fgValueNumberTree(GenTree* tree) { if (tree->AsOp()->gtOp1 != nullptr) { - bool foldedToConst = false; - - // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable) - if (tree->OperIs(GT_ARR_LENGTH)) - { - // Case 1: ARR_LENGTH(FROZEN_OBJ) - ValueNum addressVN = vnStore->VNNormalValue(tree->gtGetOp1()->gtVNPair.GetLiberal()); - if (vnStore->IsVNHandle(addressVN) && - (vnStore->GetHandleFlags(addressVN) == GTF_ICON_OBJ_HDL)) - { - size_t handle = vnStore->CoercedConstantValue(addressVN); - int len = this->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); - if (len >= 0) - { - ValueNumPair op1vnp; - ValueNumPair op1Xvnp; - vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, &op1Xvnp); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); - tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); - foldedToConst = true; - } - } - - // Case 2: ARR_LENGTH(static-readonly-field) - VNFuncApp funcApp; - if (!foldedToConst && vnStore->GetVNFunc(addressVN, &funcApp) && - (funcApp.m_func == VNF_InvariantNonNullLoad)) - { - ValueNum fieldSeqVN = vnStore->VNNormalValue(funcApp.m_args[0]); - if (vnStore->IsVNHandle(fieldSeqVN) && - (vnStore->GetHandleFlags(fieldSeqVN) == GTF_ICON_FIELD_SEQ)) - { - FieldSeq* fieldSeq = vnStore->FieldSeqVNToFieldSeq(fieldSeqVN); - if (fieldSeq != nullptr) - { - CORINFO_FIELD_HANDLE field = fieldSeq->GetFieldHandle(); - if (field != NULL) - { - uint8_t buffer[TARGET_POINTER_SIZE] = {0}; - if (this->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 = this->info.compCompHnd->getArrayOrStringLength(objHandle); - if (len >= 0) - { - ValueNumPair op1vnp; - ValueNumPair op1Xvnp; - vnStore->VNPUnpackExc(tree->gtGetOp1()->gtVNPair, &op1vnp, - &op1Xvnp); - tree->gtVNPair.SetBoth(vnStore->VNForIntCon(len)); - tree->gtVNPair = vnStore->VNPExcSetUnion(tree->gtVNPair, op1Xvnp); - foldedToConst = true; - } - } - } - } - } - } - } - if (tree->OperIs(GT_NOP)) { // Pass through arg vn. tree->gtVNPair = tree->AsOp()->gtOp1->gtVNPair; } - else if (!foldedToConst) + else { ValueNumPair op1VNP; ValueNumPair op1VNPx; From 19df3e677961a1abd5b4ac6874877d0213f9bdc7 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 31 Oct 2022 22:03:36 +0200 Subject: [PATCH 41/41] Apply suggestions from code review Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/valuenum.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2a35562b9505eb..11ffa8951c7ea6 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2094,10 +2094,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) int len = m_pComp->info.compCompHnd->getArrayOrStringLength((CORINFO_OBJECT_HANDLE)handle); if (len >= 0) { - ValueNum op1vn; - ValueNum op1Xvn; - VNUnpackExc(arg0VN, &op1vn, &op1Xvn); - resultVN = VNExcSetUnion(VNForIntCon(len), op1Xvn); + resultVN = VNForIntCon(len); } } @@ -2126,10 +2123,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) int len = m_pComp->info.compCompHnd->getArrayOrStringLength(objHandle); if (len >= 0) { - ValueNum op1vn; - ValueNum op1Xvn; - VNUnpackExc(arg0VN, &op1vn, &op1Xvn); - resultVN = VNExcSetUnion(VNForIntCon(len), op1Xvn); + resultVN = VNForIntCon(len); } } }