diff --git a/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs index 2f148da67aa575..25200d0062cf43 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Text; @@ -9,6 +10,20 @@ namespace System { public partial class String { + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "String_StrCns")] + private static unsafe partial string* StrCnsInternal(uint rid, IntPtr scopeHandle); + + // implementation of CORINFO_HELP_STRCNS + [StackTraceHidden] + [DebuggerStepThrough] + [DebuggerHidden] + internal static unsafe string StrCns(uint rid, IntPtr scopeHandle) + { + string* ptr = StrCnsInternal(rid, scopeHandle); + Debug.Assert(ptr != null); + return *ptr; + } + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern string FastAllocateString(int length); diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index 38114a9bbfcada..72748e42cbde03 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -92,7 +92,7 @@ DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, JIT_NewArr1,METHOD__NIL) - JITHELPER(CORINFO_HELP_STRCNS, JIT_StrCns, METHOD__NIL) + DYNAMICJITHELPER(CORINFO_HELP_STRCNS, NULL, METHOD__STRING__STRCNS) // Object model DYNAMICJITHELPER(CORINFO_HELP_INITCLASS, NULL, METHOD__INITHELPERS__INITCLASS) @@ -150,7 +150,7 @@ // GC support DYNAMICJITHELPER(CORINFO_HELP_STOP_FOR_GC, JIT_RareDisableHelper, METHOD__NIL) DYNAMICJITHELPER(CORINFO_HELP_POLL_GC, JIT_PollGC, METHOD__THREAD__POLLGC) - + JITHELPER(CORINFO_HELP_CHECK_OBJ, JIT_CheckObj, METHOD__NIL) // GC Write barrier support diff --git a/src/coreclr/vm/appdomainnative.cpp b/src/coreclr/vm/appdomainnative.cpp index ada5e6c7b689a0..f8cae6a32ea273 100644 --- a/src/coreclr/vm/appdomainnative.cpp +++ b/src/coreclr/vm/appdomainnative.cpp @@ -129,6 +129,22 @@ extern "C" void QCALLTYPE String_IsInterned(QCall::StringHandleOnStack str) END_QCALL; } +extern "C" STRINGREF* QCALLTYPE String_StrCns(UINT32 rid, CORINFO_MODULE_HANDLE scopeHnd) +{ + QCALL_CONTRACT; + + STRINGREF* hndStr = NULL; + + BEGIN_QCALL; + + // Retrieve the handle to the CLR string object. + hndStr = ConstructStringLiteral(scopeHnd, RidToToken(rid, mdtString)); + + END_QCALL; + + return hndStr; +} + extern "C" void QCALLTYPE String_Intern(QCall::StringHandleOnStack str) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/appdomainnative.hpp b/src/coreclr/vm/appdomainnative.hpp index 7fb86136bf196b..921af74fa9d909 100644 --- a/src/coreclr/vm/appdomainnative.hpp +++ b/src/coreclr/vm/appdomainnative.hpp @@ -16,6 +16,7 @@ #include "qcall.h" +extern "C" STRINGREF* QCALLTYPE String_StrCns(UINT32 rid, CORINFO_MODULE_HANDLE scopeHnd); extern "C" void QCALLTYPE String_Intern(QCall::StringHandleOnStack str); extern "C" void QCALLTYPE String_IsInterned(QCall::StringHandleOnStack str); diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index ffdd7dd2246cfa..567c5b03d91fb7 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -2191,21 +2191,18 @@ void ModuleBase::InitializeStringData(DWORD token, EEStringData *pstrData, CQuic } -OBJECTHANDLE ModuleBase::ResolveStringRef(DWORD token, void** ppPinnedString) +STRINGREF* ModuleBase::ResolveStringRef(DWORD token, void** ppPinnedString) { CONTRACTL { INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; INJECT_FAULT(COMPlusThrowOM()); PRECONDITION(TypeFromToken(token) == mdtString); } CONTRACTL_END; EEStringData strData; - OBJECTHANDLE string = NULL; #if !BIGENDIAN InitializeStringData(token, &strData, NULL); @@ -2215,14 +2212,8 @@ OBJECTHANDLE ModuleBase::ResolveStringRef(DWORD token, void** ppPinnedString) #endif // !!BIGENDIAN GCX_COOP(); - - LoaderAllocator *pLoaderAllocator; - - pLoaderAllocator = this->GetLoaderAllocator(); - - string = (OBJECTHANDLE)pLoaderAllocator->GetStringObjRefPtrFromUnicodeString(&strData, ppPinnedString); - - return string; + LoaderAllocator* pLoaderAllocator = this->GetLoaderAllocator(); + return pLoaderAllocator->GetStringObjRefPtrFromUnicodeString(&strData, ppPinnedString); } mdToken Module::GetEntryPointToken() diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index 9f6c87e5d787e5..fa11dd2ce20e36 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -578,7 +578,7 @@ class ModuleBase } // Resolving - OBJECTHANDLE ResolveStringRef(DWORD Token, void** ppPinnedString = nullptr); + STRINGREF* ResolveStringRef(DWORD Token, void** ppPinnedString = nullptr); private: // string helper void InitializeStringData(DWORD token, EEStringData *pstrData, CQuickBytes *pqb); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index e483a08eb1d670..a5d9eb2037b536 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -835,6 +835,7 @@ DEFINE_METHOD(STRING, CTORF_SBYTEPTR_START_LEN_ENCODING, Ctor, DEFINE_METHOD(STRING, INTERNAL_COPY, InternalCopy, SM_Str_IntPtr_Int_RetVoid) DEFINE_METHOD(STRING, WCSLEN, wcslen, SM_PtrChar_RetInt) DEFINE_METHOD(STRING, STRLEN, strlen, SM_PtrByte_RetInt) +DEFINE_METHOD(STRING, STRCNS, StrCns, SM_UInt_IntPtr_RetStr) DEFINE_PROPERTY(STRING, LENGTH, Length, Int) DEFINE_CLASS(STRING_BUILDER, Text, StringBuilder) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 28ac102756360d..927268a4769291 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -902,39 +902,15 @@ HCIMPL1(StringObject*, FramedAllocateString, DWORD stringLength) HCIMPLEND /*********************************************************************/ -OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void** ppPinnedString) +STRINGREF* ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void** ppPinnedString) { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; + STANDARD_VM_CONTRACT; _ASSERTE(TypeFromToken(metaTok) == mdtString); - Module* module = GetModule(scopeHnd); return module->ResolveStringRef(metaTok, ppPinnedString); } -/*********************************************************************/ -HCIMPL2(Object *, JIT_StrCns, unsigned rid, CORINFO_MODULE_HANDLE scopeHnd) -{ - FCALL_CONTRACT; - - OBJECTHANDLE hndStr = 0; - - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - // Retrieve the handle to the CLR string object. - hndStr = ConstructStringLiteral(scopeHnd, RidToToken(rid, mdtString)); - HELPER_METHOD_FRAME_END(); - - // Don't use ObjectFromHandle; this isn't a real handle - return *(Object**)hndStr; -} -HCIMPLEND - - //======================================================================== // // ARRAY HELPERS @@ -3384,21 +3360,21 @@ HCIMPL3_RAW(void, JIT_ReversePInvokeEnterTrackTransitions, ReversePInvokeFrame* frame->pMD = pMD; Thread* thread = GetThreadNULLOk(); - + // If a thread instance exists and is in the // correct GC mode attempt a quick transition. if (thread != NULL && !thread->PreemptiveGCDisabled()) { frame->currentThread = thread; - + #ifdef PROFILING_SUPPORTED if (CORProfilerTrackTransitions()) { ProfilerUnmanagedToManagedTransitionMD(frame->pMD, COR_PRF_TRANSITION_CALL); } #endif - + // Manually inline the fast path in Thread::DisablePreemptiveGC(). thread->m_fPreemptiveGCDisabled.StoreWithoutBarrier(1); if (g_TrapReturningThreads != 0) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5d85d98fc4acbc..2e58e15933427d 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11738,7 +11738,7 @@ InfoAccessType CEEJitInfo::constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd { // If ConstructStringLiteral returns a pinned reference we can return it by value (IAT_VALUE) void* ppPinnedString = nullptr; - void** ptr = (void**)ConstructStringLiteral(scopeHnd, metaTok, &ppPinnedString); + STRINGREF* ptr = ConstructStringLiteral(scopeHnd, metaTok, &ppPinnedString); if (ppPinnedString != nullptr) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 7f1835e458a53a..4b647b25430cdb 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1029,7 +1029,7 @@ void DoGcStress (PT_CONTEXT regs, NativeCodeVersion nativeCodeVersion); // ppPinnedString: If the string is pinned (e.g. allocated in frozen heap), // the pointer to the pinned string is returned in *ppPinnedPointer. ppPinnedPointer == nullptr // means that the caller does not care whether the string is pinned or not. -OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void** ppPinnedString = nullptr); +STRINGREF* ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void** ppPinnedString = nullptr); FCDECL2(Object*, JIT_Box_MP_FastPortable, CORINFO_CLASS_HANDLE type, void* data); FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data); diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 3d279240f0cbb3..2883b95ac39afa 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -220,6 +220,7 @@ DEFINE_METASIG(SM(RetUInt, _, K)) DEFINE_METASIG(SM(RetBool, _, F)) DEFINE_METASIG(SM(IntPtr_RetStr, I, s)) DEFINE_METASIG(SM(IntPtr_RetBool, I, F)) +DEFINE_METASIG(SM(UInt_IntPtr_RetStr, K I, s)) DEFINE_METASIG_T(SM(RuntimeType_RuntimeMethodHandleInternal_RetMethodBase, C(CLASS) g(METHOD_HANDLE_INTERNAL), C(METHOD_BASE) )) DEFINE_METASIG_T(SM(RuntimeType_IRuntimeFieldInfo_RetFieldInfo, C(CLASS) C(I_RT_FIELD_INFO), C(FIELD_INFO) )) DEFINE_METASIG(SM(Char_Bool_Bool_RetByte, u F F, b)) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 085468f030e9b1..5ac5a3889f9386 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -271,6 +271,7 @@ static const Entry s_QCall[] = DllImportEntry(MultiCoreJIT_InternalStartProfile) #endif DllImportEntry(LoaderAllocator_Destroy) + DllImportEntry(String_StrCns) DllImportEntry(String_Intern) DllImportEntry(String_IsInterned) DllImportEntry(AppDomain_CreateDynamicAssembly)