diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index fccf2dcfdbbcbb..63b83a9f507422 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2240,10 +2240,11 @@ class ICorStaticInfo // Returns string length and content (can be null for dynamic context) // for given metaTOK and module, length `-1` means input is incorrect - virtual const char16_t * getStringLiteral ( + virtual int getStringLiteral ( CORINFO_MODULE_HANDLE module, /* IN */ unsigned metaTOK, /* IN */ - int* length /* OUT */ + char16_t* buffer, /* OUT */ + int bufferSize /* IN */ ) = 0; /**********************************************************************************/ diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 057c1a2b9cc6ab..496a84c69dd091 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -165,10 +165,11 @@ bool isValidStringRef( CORINFO_MODULE_HANDLE module, unsigned metaTOK) override; -const char16_t* getStringLiteral( +int getStringLiteral( CORINFO_MODULE_HANDLE module, unsigned metaTOK, - int* length) override; + char16_t* buffer, + int bufferSize) override; CorInfoType asCorInfoType( CORINFO_CLASS_HANDLE cls) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index b1b0f06a4ece9c..59a16ece8cca0d 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 = { /* 206a7aa6-9f5c-47c1-b63b-54f4cb169ee3 */ - 0x206a7aa6, - 0x9f5c, - 0x47c1, - {0xb6, 0x3b, 0x54, 0xf4, 0xcb, 0x16, 0x9e, 0xe3} +constexpr GUID JITEEVersionIdentifier = { /* b0719856-6fe6-407c-bf40-7a57e22b2382 */ + 0xb0719856, + 0x6fe6, + 0x407c, + {0xbf, 0x40, 0x7a, 0x57, 0xe2, 0x2b, 0x23, 0x82} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 40c58a309166ea..51d97b94b726ef 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -353,13 +353,14 @@ bool WrapICorJitInfo::isValidStringRef( return temp; } -const char16_t* WrapICorJitInfo::getStringLiteral( +int WrapICorJitInfo::getStringLiteral( CORINFO_MODULE_HANDLE module, unsigned metaTOK, - int* length) + char16_t* buffer, + int bufferSize) { API_ENTER(getStringLiteral); - const char16_t* temp = wrapHnd->getStringLiteral(module, metaTOK, length); + int temp = wrapHnd->getStringLiteral(module, metaTOK, buffer, bufferSize); API_LEAVE(getStringLiteral); return temp; } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 90b01ad16af626..60638201421243 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -6957,21 +6957,11 @@ GenTreeIntCon* Compiler::gtNewStringLiteralLength(GenTreeStrCon* node) return gtNewIconNode(0); } - int length = -1; - const char16_t* str = info.compCompHnd->getStringLiteral(node->gtScpHnd, node->gtSconCPX, &length); + int length = info.compCompHnd->getStringLiteral(node->gtScpHnd, node->gtSconCPX, nullptr, 0); if (length >= 0) { GenTreeIntCon* iconNode = gtNewIconNode(length); - - // str can be NULL for dynamic context - if (str != nullptr) - { - JITDUMP("Folded '\"%ws\".Length' to '%d'\n", str, length) - } - else - { - JITDUMP("Folded 'CNS_STR.Length' to '%d'\n", length) - } + JITDUMP("Folded 'CNS_STR.Length' to '%d'\n", length) return iconNode; } return nullptr; diff --git a/src/coreclr/jit/importer_vectorization.cpp b/src/coreclr/jit/importer_vectorization.cpp index 44adc0c441eb0b..d947ee4ea4fe37 100644 --- a/src/coreclr/jit/importer_vectorization.cpp +++ b/src/coreclr/jit/importer_vectorization.cpp @@ -6,6 +6,9 @@ #pragma hdrstop #endif +// For now the max possible size is Vector256.Count * 2 +#define MaxPossibleUnrollSize 32 + //------------------------------------------------------------------------ // importer_vectorization.cpp // @@ -145,8 +148,7 @@ static GenTreeHWIntrinsic* CreateConstVector(Compiler* comp, var_types simdType, GenTree* Compiler::impExpandHalfConstEqualsSIMD( GenTreeLclVar* data, WCHAR* cns, int len, int dataOffset, StringComparison cmpMode) { - constexpr int maxPossibleLength = 32; - assert(len >= 8 && len <= maxPossibleLength); + assert(len >= 8 && len <= MaxPossibleUnrollSize); if (!IsBaselineSimdIsaSupported()) { @@ -170,8 +172,8 @@ GenTree* Compiler::impExpandHalfConstEqualsSIMD( // Optimization: don't use two vectors for Length == 8 or 16 bool useSingleVector = false; - WCHAR cnsValue[maxPossibleLength] = {}; - WCHAR toLowerMask[maxPossibleLength] = {}; + WCHAR cnsValue[MaxPossibleUnrollSize] = {}; + WCHAR toLowerMask[MaxPossibleUnrollSize] = {}; memcpy((UINT8*)cnsValue, (UINT8*)cns, len * sizeof(WCHAR)); @@ -678,8 +680,8 @@ GenTree* Compiler::impStringEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO needsNullcheck = false; } - int cnsLength = -1; - const char16_t* str = nullptr; + int cnsLength; + char16_t str[MaxPossibleUnrollSize]; if (cnsStr->IsStringEmptyField()) { // check for fake "" first @@ -688,13 +690,13 @@ GenTree* Compiler::impStringEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO } else { - str = info.compCompHnd->getStringLiteral(cnsStr->gtScpHnd, cnsStr->gtSconCPX, &cnsLength); - if ((cnsLength < 0) || (str == nullptr)) + cnsLength = info.compCompHnd->getStringLiteral(cnsStr->gtScpHnd, cnsStr->gtSconCPX, str, MaxPossibleUnrollSize); + if ((cnsLength < 0) || (cnsLength > MaxPossibleUnrollSize)) { // We were unable to get the literal (e.g. dynamic context) return nullptr; } - JITDUMP("Trying to unroll String.Equals|StartsWith(op1, \"%ws\")...\n", str) + JITDUMP("Trying to unroll String.Equals|StartsWith(op1, \"cns\")...\n") } // Create a temp which is safe to gtClone for varStr @@ -816,8 +818,8 @@ GenTree* Compiler::impSpanEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO* spanObj = op1; } - int cnsLength = -1; - const char16_t* str = nullptr; + int cnsLength = -1; + char16_t str[MaxPossibleUnrollSize]; if (cnsStr->IsStringEmptyField()) { // check for fake "" first @@ -826,8 +828,8 @@ GenTree* Compiler::impSpanEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO* } else { - str = info.compCompHnd->getStringLiteral(cnsStr->gtScpHnd, cnsStr->gtSconCPX, &cnsLength); - if (cnsLength < 0 || str == nullptr) + cnsLength = info.compCompHnd->getStringLiteral(cnsStr->gtScpHnd, cnsStr->gtSconCPX, str, MaxPossibleUnrollSize); + if ((cnsLength < 0) || (cnsLength > MaxPossibleUnrollSize)) { // We were unable to get the literal (e.g. dynamic context) return nullptr; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 45e56476487a72..1a90f298be026f 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -4854,10 +4854,11 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) const int cnsIndex = static_cast(asIndex->Index()->AsIntConCommon()->IconValue()); if (cnsIndex >= 0) { - int length; - const char16_t* str = info.compCompHnd->getStringLiteral(asIndex->Arr()->AsStrCon()->gtScpHnd, - asIndex->Arr()->AsStrCon()->gtSconCPX, &length); - if ((cnsIndex < length) && (str != nullptr)) + const int maxStrSize = 1024; + char16_t str[maxStrSize]; + int length = info.compCompHnd->getStringLiteral(asIndex->Arr()->AsStrCon()->gtScpHnd, + asIndex->Arr()->AsStrCon()->gtSconCPX, str, maxStrSize); + if ((cnsIndex < length)) { GenTree* cnsCharNode = gtNewIconNode(str[cnsIndex], TYP_INT); INDEBUG(cnsCharNode->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index c3efb9bc7151e0..5dc8f3b12c6a26 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -525,12 +525,12 @@ static byte _isValidStringRef(IntPtr thisHandle, IntPtr* ppException, CORINFO_MO } [UnmanagedCallersOnly] - static char* _getStringLiteral(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint metaTOK, int* length) + static int _getStringLiteral(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint metaTOK, char* buffer, int bufferSize) { var _this = GetThis(thisHandle); try { - return _this.getStringLiteral(module, metaTOK, ref *length); + return _this.getStringLiteral(module, metaTOK, buffer, bufferSize); } catch (Exception ex) { @@ -2604,7 +2604,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[32] = (delegate* unmanaged)&_getTokenTypeAsHandle; callbacks[33] = (delegate* unmanaged)&_isValidToken; callbacks[34] = (delegate* unmanaged)&_isValidStringRef; - callbacks[35] = (delegate* unmanaged)&_getStringLiteral; + callbacks[35] = (delegate* unmanaged)&_getStringLiteral; callbacks[36] = (delegate* unmanaged)&_asCorInfoType; callbacks[37] = (delegate* unmanaged)&_getClassName; callbacks[38] = (delegate* unmanaged)&_getClassNameFromMetadata; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 8af0179381d0ce..14dc7927e58cc3 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1875,12 +1875,19 @@ private bool isValidToken(CORINFO_MODULE_STRUCT_* module, uint metaTOK) private bool isValidStringRef(CORINFO_MODULE_STRUCT_* module, uint metaTOK) { throw new NotImplementedException("isValidStringRef"); } - private char* getStringLiteral(CORINFO_MODULE_STRUCT_* module, uint metaTOK, ref int length) + private int getStringLiteral(CORINFO_MODULE_STRUCT_* module, uint metaTOK, char* buffer, int size) { + Debug.Assert(size >= 0); + MethodILScope methodIL = HandleToObject(module); - string s = (string)methodIL.GetObject((int)metaTOK); - length = (int)s.Length; - return (char*)GetPin(s); + string str = (string)methodIL.GetObject((int)metaTOK); + + if (buffer != null) + { + // Copy str's content to buffer + str.AsSpan(0, Math.Min(size, str.Length)).CopyTo(new Span(buffer, size)); + } + return str.Length; } private CorInfoType asCorInfoType(CORINFO_CLASS_STRUCT_* cls) diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 5596a645f5e8d4..74e786a995b1f2 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -188,7 +188,7 @@ FUNCTIONS CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken) bool isValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK) bool isValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK) - const char16_t * getStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int* length) + int getStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize) 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.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index f8a06e45cb069b..2b6e0c1483787a 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -46,7 +46,7 @@ struct JitInterfaceCallbacks CORINFO_CLASS_HANDLE (* getTokenTypeAsHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken); bool (* isValidToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK); bool (* isValidStringRef)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK); - const char16_t* (* getStringLiteral)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK, int* length); + int (* getStringLiteral)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize); 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); @@ -540,13 +540,14 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual const char16_t* getStringLiteral( + virtual int getStringLiteral( CORINFO_MODULE_HANDLE module, unsigned metaTOK, - int* length) + char16_t* buffer, + int bufferSize) { CorInfoExceptionClass* pException = nullptr; - const char16_t* temp = _callbacks->getStringLiteral(_thisHandle, &pException, module, metaTOK, length); + int temp = _callbacks->getStringLiteral(_thisHandle, &pException, module, metaTOK, buffer, bufferSize); 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 87a438307c848f..b36dd825507531 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -146,7 +146,7 @@ LWM(IsFieldStatic, DWORDLONG, DWORD) LWM(IsIntrinsicType, DWORDLONG, DWORD) LWM(IsSDArray, DWORDLONG, DWORD) LWM(IsValidStringRef, DLD, DWORD) -LWM(GetStringLiteral, DLD, DD) +LWM(GetStringLiteral, DLDD, DD) LWM(IsValidToken, DLD, DWORD) LWM(IsValueClass, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 7cca8b9adc482a..92e119f9a9af86 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -4765,20 +4765,20 @@ bool MethodContext::repIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned m return value != 0; } - -void MethodContext::recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int length, const char16_t* result) +void MethodContext::recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int length) { if (GetStringLiteral == nullptr) - GetStringLiteral = new LightWeightMap(); + GetStringLiteral = new LightWeightMap(); - DLD key; + DLDD key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.A = CastHandle(module); key.B = (DWORD)metaTOK; + key.C = (DWORD)bufferSize; DWORD strBuf = (DWORD)-1; - if (result != nullptr) - strBuf = (DWORD)GetStringLiteral->AddBuffer((unsigned char*)result, (unsigned int)((wcslen((LPCWSTR)result) * 2) + 2)); + if (buffer != nullptr) + strBuf = (DWORD)GetStringLiteral->AddBuffer((unsigned char*)buffer, (unsigned int)bufferSize); DD value; value.A = (DWORD)length; @@ -4788,39 +4788,39 @@ void MethodContext::recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned m DEBUG_REC(dmpGetStringLiteral(key, value)); } -void MethodContext::dmpGetStringLiteral(DLD key, DD value) +void MethodContext::dmpGetStringLiteral(DLDD key, DD value) { - printf("GetStringLiteral key mod-%016llX tok-%08X, result-%s, len-%u", key.A, key.B, - GetStringLiteral->GetBuffer(value.B), value.A); + printf("GetStringLiteral key mod-%016llX tok-%08X, bufSize-%u, len-%u", key.A, key.B, key.C, value.A); GetStringLiteral->Unlock(); } -const char16_t* MethodContext::repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int* length) +int MethodContext::repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize) { if (GetStringLiteral == nullptr) { - *length = -1; - return nullptr; + return -1; } - DLD key; + DLDD key; ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding key.A = CastHandle(module); key.B = (DWORD)metaTOK; + key.C = (DWORD)bufferSize; int itemIndex = GetStringLiteral->GetIndex(key); if (itemIndex < 0) { - *length = -1; - return nullptr; + return -1; } else { DD value = GetStringLiteral->Get(key); DEBUG_REP(dmpGetStringLiteral(key, value)); - - *length = (int)value.A; - return (const char16_t*)GetStringLiteral->GetBuffer(value.B); + if (buffer != nullptr) + { + memcpy(buffer, GetStringLiteral->GetBuffer(value.B), bufferSize * sizeof(char16_t)); + } + return (int)value.A; } } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 589d6d85b2c65c..78617b6b2c4982 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -600,9 +600,9 @@ class MethodContext void dmpIsValidStringRef(DLD key, DWORD value); bool repIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK); - void recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int length, const char16_t* result); - void dmpGetStringLiteral(DLD key, DD value); - const char16_t* repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int* length); + void recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int length); + void dmpGetStringLiteral(DLDD key, DD value); + int repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize); 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 0ff9e9391369d0..3e7c8562355add 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -434,14 +434,15 @@ bool interceptor_ICJI::isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN */ return temp; } -const char16_t* interceptor_ICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN */ - unsigned metaTOK, /* IN */ - int* length /* OUT */ - ) +int interceptor_ICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN */ + unsigned metaTOK, /* IN */ + char16_t* buffer, /* OUT */ + int bufferSize /* IN */ + ) { mc->cr->AddCall("getStringLiteral"); - const char16_t* temp = original_ICorJitInfo->getStringLiteral(module, metaTOK, length); - mc->recGetStringLiteral(module, metaTOK, *length, temp); + int temp = original_ICorJitInfo->getStringLiteral(module, metaTOK, buffer, bufferSize); + mc->recGetStringLiteral(module, metaTOK, buffer, bufferSize, temp); return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 6fe72d81a72251..df7d67a6a0fe30 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -296,13 +296,14 @@ bool interceptor_ICJI::isValidStringRef( return original_ICorJitInfo->isValidStringRef(module, metaTOK); } -const char16_t* interceptor_ICJI::getStringLiteral( +int interceptor_ICJI::getStringLiteral( CORINFO_MODULE_HANDLE module, unsigned metaTOK, - int* length) + char16_t* buffer, + int bufferSize) { mcs->AddCall("getStringLiteral"); - return original_ICorJitInfo->getStringLiteral(module, metaTOK, length); + return original_ICorJitInfo->getStringLiteral(module, metaTOK, buffer, bufferSize); } CorInfoType interceptor_ICJI::asCorInfoType( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 8606fe0915e5ba..5efd8516cecf5b 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -261,12 +261,13 @@ bool interceptor_ICJI::isValidStringRef( return original_ICorJitInfo->isValidStringRef(module, metaTOK); } -const char16_t* interceptor_ICJI::getStringLiteral( +int interceptor_ICJI::getStringLiteral( CORINFO_MODULE_HANDLE module, unsigned metaTOK, - int* length) + char16_t* buffer, + int bufferSize) { - return original_ICorJitInfo->getStringLiteral(module, metaTOK, length); + return original_ICorJitInfo->getStringLiteral(module, metaTOK, buffer, bufferSize); } CorInfoType interceptor_ICJI::asCorInfoType( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 32827ecda7b1db..ebfb397b3b87ec 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -373,13 +373,14 @@ bool MyICJI::isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN */ return jitInstance->mc->repIsValidStringRef(module, metaTOK); } -const char16_t* MyICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN */ - unsigned metaTOK, /* IN */ - int* length /* OUT */ - ) +int MyICJI::getStringLiteral(CORINFO_MODULE_HANDLE module, /* IN */ + unsigned metaTOK, /* IN */ + char16_t* buffer, /* OUT */ + int bufferSize /* IN */ + ) { jitInstance->mc->cr->AddCall("getStringLiteral"); - return jitInstance->mc->repGetStringLiteral(module, metaTOK, length); + return jitInstance->mc->repGetStringLiteral(module, metaTOK, buffer, bufferSize); } /**********************************************************************************/ diff --git a/src/coreclr/vm/dynamicmethod.cpp b/src/coreclr/vm/dynamicmethod.cpp index 4ee05faaafd8a9..b937fd97858036 100644 --- a/src/coreclr/vm/dynamicmethod.cpp +++ b/src/coreclr/vm/dynamicmethod.cpp @@ -1230,26 +1230,11 @@ LCGMethodResolver::IsValidStringRef(mdToken metaTok) return GetStringLiteral(metaTok) != NULL; } -int -LCGMethodResolver::GetStringLiteralLength(mdToken metaTok) -{ - STANDARD_VM_CONTRACT; - - GCX_COOP(); - - STRINGREF str = GetStringLiteral(metaTok); - if (str != NULL) - { - return str->GetStringLength(); - } - return -1; -} - //--------------------------------------------------------------------------------------- // STRINGREF LCGMethodResolver::GetStringLiteral( - mdToken token) + mdToken metaTok) { CONTRACTL { THROWS; @@ -1264,7 +1249,7 @@ LCGMethodResolver::GetStringLiteral( ARG_SLOT args[] = { ObjToArgSlot(resolver), - token, + metaTok, }; return getStringLiteral.Call_RetSTRINGREF(args); } diff --git a/src/coreclr/vm/dynamicmethod.h b/src/coreclr/vm/dynamicmethod.h index 3690d55d41ce74..f467fcbcd91dd7 100644 --- a/src/coreclr/vm/dynamicmethod.h +++ b/src/coreclr/vm/dynamicmethod.h @@ -77,7 +77,7 @@ class DynamicResolver // jit interface api virtual OBJECTHANDLE ConstructStringLiteral(mdToken metaTok) = 0; virtual BOOL IsValidStringRef(mdToken metaTok) = 0; - virtual int GetStringLiteralLength(mdToken metaTok) = 0; + virtual STRINGREF GetStringLiteral(mdToken metaTok) = 0; virtual void ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD) = 0; virtual SigPointer ResolveSignature(mdToken token) = 0; virtual SigPointer ResolveSignatureForVarArg(mdToken token) = 0; @@ -127,7 +127,6 @@ class LCGMethodResolver : public DynamicResolver OBJECTHANDLE ConstructStringLiteral(mdToken metaTok); BOOL IsValidStringRef(mdToken metaTok); - int GetStringLiteralLength(mdToken metaTok); void ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD); SigPointer ResolveSignature(mdToken token); SigPointer ResolveSignatureForVarArg(mdToken token); @@ -138,7 +137,7 @@ class LCGMethodResolver : public DynamicResolver void SetManagedResolver(OBJECTHANDLE obj) { LIMITED_METHOD_CONTRACT; m_managedResolver = obj; } void * GetRecordCodePointer() { LIMITED_METHOD_CONTRACT; return m_recordCodePointer; } - STRINGREF GetStringLiteral(mdToken token); + STRINGREF GetStringLiteral(mdToken metaTok); STRINGREF * GetOrInternString(STRINGREF *pString); void AddToUsedIndCellList(BYTE * indcell); #ifdef FEATURE_PGO diff --git a/src/coreclr/vm/ilstubresolver.cpp b/src/coreclr/vm/ilstubresolver.cpp index 76f6df6a4fbedc..2721afdf2bf30a 100644 --- a/src/coreclr/vm/ilstubresolver.cpp +++ b/src/coreclr/vm/ilstubresolver.cpp @@ -104,11 +104,11 @@ BOOL ILStubResolver::IsValidStringRef(mdToken metaTok) return FALSE; } -int ILStubResolver::GetStringLiteralLength(mdToken metaTok) +STRINGREF ILStubResolver::GetStringLiteral(mdToken metaTok) { - STANDARD_VM_CONTRACT; + LIMITED_METHOD_CONTRACT; _ASSERTE(FALSE); - return -1; + return NULL; } void ILStubResolver::ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD) diff --git a/src/coreclr/vm/ilstubresolver.h b/src/coreclr/vm/ilstubresolver.h index dd20255c8d09ca..99f6f406363fa5 100644 --- a/src/coreclr/vm/ilstubresolver.h +++ b/src/coreclr/vm/ilstubresolver.h @@ -32,7 +32,7 @@ class ILStubResolver : DynamicResolver OBJECTHANDLE ConstructStringLiteral(mdToken metaTok); BOOL IsValidStringRef(mdToken metaTok); - int GetStringLiteralLength(mdToken metaTok); + STRINGREF GetStringLiteral(mdToken metaTok); void ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD); SigPointer ResolveSignature(mdToken token); SigPointer ResolveSignatureForVarArg(mdToken token); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 6c78beebdffa2c..d5a3c11e3575c2 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -661,10 +661,11 @@ bool CEEInfo::isValidStringRef ( return result; } -const char16_t* CEEInfo::getStringLiteral ( +int CEEInfo::getStringLiteral ( CORINFO_MODULE_HANDLE moduleHnd, mdToken metaTOK, - int* length) + char16_t* buffer, + int bufferSize) { CONTRACTL{ THROWS; @@ -674,13 +675,25 @@ const char16_t* CEEInfo::getStringLiteral ( Module* module = GetModule(moduleHnd); - const char16_t* result = nullptr; + _ASSERTE(bufferSize >= 0); + + int result = -1; JIT_TO_EE_TRANSITION(); if (IsDynamicScope(moduleHnd)) { - *length = GetDynamicResolver(moduleHnd)->GetStringLiteralLength(metaTOK); + GCX_COOP(); + STRINGREF strRef = GetDynamicResolver(moduleHnd)->GetStringLiteral(metaTOK); + if (strRef != NULL) + { + StringObject* strObj = STRINGREFToObject(strRef); + result = (int)strObj->GetStringLength(); + if (buffer != NULL) + { + memcpyNoGCRefs(buffer, strObj->GetBuffer(), min(bufferSize, result) * sizeof(char16_t)); + } + } } else { @@ -688,13 +701,12 @@ const char16_t* CEEInfo::getStringLiteral ( LPCWSTR pString; if (!FAILED((module)->GetMDImport()->GetUserString(metaTOK, &dwCharCount, NULL, &pString))) { - // For string.Empty pString will be null - *length = dwCharCount; - result = (const char16_t *)pString; - } - else - { - *length = -1; + _ASSERTE(dwCharCount >= 0 && dwCharCount <= INT_MAX); + result = (int)dwCharCount; + if (buffer != NULL) + { + memcpyNoGCRefs(buffer, pString, min(bufferSize, result) * sizeof(char16_t)); + } } }