Skip to content

Commit 86dfeb9

Browse files
authored
Remove lazy initialized string literals (#122076)
It seems it's not worth it to avoid allocations on the frozen heap - the lazy string helper has a lock inside (Crst in GetStringLiteral) and it badly impacts performance for `throw Exception(<string literal>)` code (as was reported internally) especially under contention. ```cs static void Foo(bool cond) { throw new Exception("Hello"); } ``` ```diff ; Method Program:Foo(bool) (FullOpts) push rbx sub rsp, 32 mov rcx, 0x7FFBD79E2E10 ; System.Exception call CORINFO_HELP_NEWSFAST mov rbx, rax - mov ecx, 1 - mov rdx, 0x7FFBD7FE0000 - call [CORINFO_HELP_STRCNS] - mov rdx, rax mov rcx, rbx + mov rdx, 0x28922695108 ; 'Hello' call [System.Exception:.ctor(System.String):this] mov rcx, rbx call CORINFO_HELP_THROW int3 -; Total bytes of code: 65 +; Total bytes of code: 51 ```
1 parent 7be0c63 commit 86dfeb9

31 files changed

+54
-270
lines changed

docs/design/coreclr/botr/readytorun-format.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ enum ReadyToRunHelper
872872
READYTORUN_HELPER_MemCpy = 0x41,
873873

874874
// Get string handle lazily
875-
READYTORUN_HELPER_GetString = 0x50,
875+
READYTORUN_HELPER_GetString = 0x50, // Unused since READYTORUN_MAJOR_VERSION 17.0
876876

877877
// Used by /Tuning for Profile optimizations
878878
READYTORUN_HELPER_LogMethodEnter = 0x51, // Unused since READYTORUN_MAJOR_VERSION 10.0

src/coreclr/System.Private.CoreLib/src/System/String.CoreCLR.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,6 @@ namespace System
1010
{
1111
public partial class String
1212
{
13-
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "String_StrCns")]
14-
private static unsafe partial string* StrCnsInternal(uint rid, IntPtr scopeHandle);
15-
16-
// implementation of CORINFO_HELP_STRCNS
17-
[StackTraceHidden]
18-
[DebuggerStepThrough]
19-
[DebuggerHidden]
20-
internal static unsafe string StrCns(uint rid, IntPtr scopeHandle)
21-
{
22-
string* ptr = StrCnsInternal(rid, scopeHandle);
23-
Debug.Assert(ptr != null);
24-
return *ptr;
25-
}
26-
2713
[MethodImpl(MethodImplOptions.InternalCall)]
2814
internal static extern unsafe string FastAllocateString(MethodTable *pMT, nint length);
2915

src/coreclr/inc/corinfo.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ enum CorInfoHelpFunc
367367
CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
368368
CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
369369

370-
CORINFO_HELP_STRCNS, // create a new string literal
371-
372370
/* Object model */
373371

374372
CORINFO_HELP_INITCLASS, // Initialize class if not already initialized
@@ -3237,12 +3235,6 @@ class ICorDynamicInfo : public ICorStaticInfo
32373235
CORINFO_CONST_LOOKUP * pResult
32383236
) = 0;
32393237

3240-
// get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
3241-
// Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
3242-
virtual CorInfoHelpFunc getLazyStringLiteralHelper(
3243-
CORINFO_MODULE_HANDLE handle
3244-
) = 0;
3245-
32463238
virtual CORINFO_MODULE_HANDLE embedModuleHandle(
32473239
CORINFO_MODULE_HANDLE handle,
32483240
void **ppIndirection = NULL

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,6 @@ void getFunctionFixedEntryPoint(
556556
bool isUnsafeFunctionPointer,
557557
CORINFO_CONST_LOOKUP* pResult) override;
558558

559-
CorInfoHelpFunc getLazyStringLiteralHelper(
560-
CORINFO_MODULE_HANDLE handle) override;
561-
562559
CORINFO_MODULE_HANDLE embedModuleHandle(
563560
CORINFO_MODULE_HANDLE handle,
564561
void** ppIndirection) override;

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737

3838
#include <minipal/guid.h>
3939

40-
constexpr GUID JITEEVersionIdentifier = { /* 567f89f4-2ddb-4d80-9107-0ce8c30a18ff */
41-
0x567f89f4,
42-
0x2ddb,
43-
0x4d80,
44-
{0x91, 0x07, 0x0c, 0xe8, 0xc3, 0x0a, 0x18, 0xff}
40+
constexpr GUID JITEEVersionIdentifier = { /* 4a42a64a-d034-44d4-8f0d-b7f67b3ea4dc */
41+
0x4a42a64a,
42+
0xd034,
43+
0x44d4,
44+
{0x8f, 0x0d, 0xb7, 0xf6, 0x7b, 0x3e, 0xa4, 0xdc}
4545
};
4646

4747
#endif // JIT_EE_VERSIONING_GUID_H

src/coreclr/inc/jithelpers.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@
112112
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, RhpNewVariableSizeObject, METHOD__NIL)
113113
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8, RhpNewVariableSizeObject, METHOD__NIL)
114114

115-
DYNAMICJITHELPER(CORINFO_HELP_STRCNS, NULL, METHOD__STRING__STRCNS)
116-
117115
// Object model
118116
DYNAMICJITHELPER(CORINFO_HELP_INITCLASS, NULL, METHOD__INITHELPERS__INITCLASS)
119117
DYNAMICJITHELPER(CORINFO_HELP_INITINSTCLASS, NULL, METHOD__INITHELPERS__INITINSTANTIATEDCLASS)

src/coreclr/inc/readytorun.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ enum ReadyToRunHelper
360360
READYTORUN_HELPER_ReversePInvokeExit = 0x46,
361361

362362
// Get string handle lazily
363-
READYTORUN_HELPER_GetString = 0x50,
363+
READYTORUN_HELPER_GetString = 0x50, // No longer supported as of READYTORUN_MAJOR_VERSION 17.0
364364

365365
// Used by /Tuning for Profile optimizations
366366
READYTORUN_HELPER_LogMethodEnter = 0x51, // No longer supported as of READYTORUN_MAJOR_VERSION 10.0

src/coreclr/jit/ICorJitInfo_names_generated.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ DEF_CLR_API(getAddrOfCaptureThreadGlobal)
137137
DEF_CLR_API(getHelperFtn)
138138
DEF_CLR_API(getFunctionEntryPoint)
139139
DEF_CLR_API(getFunctionFixedEntryPoint)
140-
DEF_CLR_API(getLazyStringLiteralHelper)
141140
DEF_CLR_API(embedModuleHandle)
142141
DEF_CLR_API(embedClassHandle)
143142
DEF_CLR_API(embedMethodHandle)

src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,15 +1310,6 @@ void WrapICorJitInfo::getFunctionFixedEntryPoint(
13101310
API_LEAVE(getFunctionFixedEntryPoint);
13111311
}
13121312

1313-
CorInfoHelpFunc WrapICorJitInfo::getLazyStringLiteralHelper(
1314-
CORINFO_MODULE_HANDLE handle)
1315-
{
1316-
API_ENTER(getLazyStringLiteralHelper);
1317-
CorInfoHelpFunc temp = wrapHnd->getLazyStringLiteralHelper(handle);
1318-
API_LEAVE(getLazyStringLiteralHelper);
1319-
return temp;
1320-
}
1321-
13221313
CORINFO_MODULE_HANDLE WrapICorJitInfo::embedModuleHandle(
13231314
CORINFO_MODULE_HANDLE handle,
13241315
void** ppIndirection)

src/coreclr/jit/compiler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4057,7 +4057,7 @@ inline bool Compiler::IsSharedStaticHelper(GenTree* tree)
40574057
bool result1 =
40584058
// More helpers being added to IsSharedStaticHelper (that have similar behaviors but are not true
40594059
// ShareStaticHelpers)
4060-
helper == CORINFO_HELP_STRCNS || helper == CORINFO_HELP_BOX ||
4060+
helper == CORINFO_HELP_BOX ||
40614061

40624062
// helpers being added to IsSharedStaticHelper
40634063
helper == CORINFO_HELP_GETSTATICFIELDADDR_TLS ||

0 commit comments

Comments
 (0)