diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index b25afff5a6fdaa..97ae2304b965c4 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -1393,6 +1393,8 @@ bool Compiler::s_dspMemStats = false; const bool Compiler::Options::compNoPInvokeInlineCB = false; #endif +unsigned Compiler::s_emptyStringSconCPX = 0; + /***************************************************************************** * * One time initialization code diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 6539b755a45c09..6b94178449b4cc 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9491,6 +9491,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //-------------------------- Global Compiler Data ------------------------------------ + static unsigned s_emptyStringSconCPX; + #ifdef DEBUG private: static LONG s_compMethodsCount; // to produce unique label names diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index aa75207070bd37..7332ab7e4fcbf9 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -14842,9 +14842,16 @@ void Compiler::impImportBlockCode(BasicBlock* block) { assert(aflags & CORINFO_ACCESS_GET); - LPVOID pValue; - InfoAccessType iat = info.compCompHnd->emptyStringLiteral(&pValue); - op1 = gtNewStringLiteralNode(iat, pValue); + if (s_emptyStringSconCPX != 0) + { + op1 = gtNewSconNode(s_emptyStringSconCPX, info.compCompHnd->getClassModule(impGetObjectClass())); + } + else + { + LPVOID pValue; + InfoAccessType iat = info.compCompHnd->emptyStringLiteral(&pValue); + op1 = gtNewStringLiteralNode(iat, pValue); + } goto FIELD_DONE; } break; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 9dc357b19bcdf0..8f013f82e88665 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -9270,13 +9270,16 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) return tree; } + CORINFO_MODULE_HANDLE scpHnd = tree->AsStrCon()->gtScpHnd; + unsigned sconCPX = tree->AsStrCon()->gtSconCPX; + // TODO-CQ: Do this for compCurBB->isRunRarely(). Doing that currently will // guarantee slow performance for that block. Instead cache the return value // of CORINFO_HELP_STRCNS and go to cache first giving reasonable perf. if (compCurBB->bbJumpKind == BBJ_THROW) { - CorInfoHelpFunc helper = info.compCompHnd->getLazyStringLiteralHelper(tree->AsStrCon()->gtScpHnd); + CorInfoHelpFunc helper = info.compCompHnd->getLazyStringLiteralHelper(scpHnd); if (helper != CORINFO_HELP_UNDEF) { // For un-important blocks, we want to construct the string lazily @@ -9284,12 +9287,12 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) GenTreeCall::Use* args; if (helper == CORINFO_HELP_STRCNS_CURRENT_MODULE) { - args = gtNewCallArgs(gtNewIconNode(RidFromToken(tree->AsStrCon()->gtSconCPX), TYP_INT)); + args = gtNewCallArgs(gtNewIconNode(RidFromToken(sconCPX), TYP_INT)); } else { - args = gtNewCallArgs(gtNewIconNode(RidFromToken(tree->AsStrCon()->gtSconCPX), TYP_INT), - gtNewIconEmbScpHndNode(tree->AsStrCon()->gtScpHnd)); + args = gtNewCallArgs(gtNewIconNode(RidFromToken(sconCPX), TYP_INT), + gtNewIconEmbScpHndNode(scpHnd)); } tree = gtNewHelperCallNode(helper, TYP_REF, args); @@ -9297,11 +9300,22 @@ GenTree* Compiler::fgMorphConst(GenTree* tree) } } - assert(tree->AsStrCon()->gtScpHnd == info.compScopeHnd || !IsUninitialized(tree->AsStrCon()->gtScpHnd)); + assert(scpHnd == info.compScopeHnd || !IsUninitialized(scpHnd)); + + // Save SconCPX to s_emptyStringSconCPX if it's "" (empty string). + if ((s_emptyStringSconCPX == 0) && + (scpHnd == info.compCompHnd->getClassModule(impGetObjectClass()))) + { + int length = -1; + info.compCompHnd->getStringLiteral(scpHnd, sconCPX, &length); + if (length == 0) + { + s_emptyStringSconCPX = sconCPX; + } + } LPVOID pValue; - InfoAccessType iat = - info.compCompHnd->constructStringLiteral(tree->AsStrCon()->gtScpHnd, tree->AsStrCon()->gtSconCPX, &pValue); + InfoAccessType iat = info.compCompHnd->constructStringLiteral(scpHnd, sconCPX, &pValue); tree = gtNewStringLiteralNode(iat, pValue);