summaryrefslogtreecommitdiff
path: root/src/vm/jitinterface.cpp
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2019-06-14 04:29:25 -0700
committerGitHub <noreply@github.com>2019-06-14 04:29:25 -0700
commite879d9c7b2b7d7a75c0101ff4861d6f87e223bc0 (patch)
tree42eda5c52c5fb00778a5139cced177a6ae8eb43c /src/vm/jitinterface.cpp
parent64ca544ecf55490675e72b853e98ebc8cc75a4fe (diff)
downloadcoreclr-e879d9c7b2b7d7a75c0101ff4861d6f87e223bc0.tar.gz
coreclr-e879d9c7b2b7d7a75c0101ff4861d6f87e223bc0.tar.bz2
coreclr-e879d9c7b2b7d7a75c0101ff4861d6f87e223bc0.zip
Optimize Activator.CreateInstance (#25145)
* Optimize Activator.CreateInstance - Short-circuit Activator.CreateInstance<T>() for value types without default constructor - Cache default constructor delegate on RuntimeType instead of fixed-size singleton cache
Diffstat (limited to 'src/vm/jitinterface.cpp')
-rw-r--r--src/vm/jitinterface.cpp78
1 files changed, 53 insertions, 25 deletions
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index de9538e6c2..d67ad2f251 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -7000,8 +7000,7 @@ bool getILIntrinsicImplementation(MethodDesc * ftn,
{
STANDARD_VM_CONTRACT;
- // Precondition: ftn is a method in mscorlib
- _ASSERTE(ftn->GetModule()->IsSystem());
+ _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__JIT_HELPERS));
mdMethodDef tk = ftn->GetMemberDef();
@@ -7129,8 +7128,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
{
STANDARD_VM_CONTRACT;
- // Precondition: ftn is a method in mscorlib
- _ASSERTE(ftn->GetModule()->IsSystem());
+ _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__UNSAFE));
mdMethodDef tk = ftn->GetMemberDef();
@@ -7371,10 +7369,7 @@ bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn,
// we substitute raw IL bodies for these methods that use the correct volatile instructions.
//
- // Precondition: ftn is a method in mscorlib in the System.Threading.Volatile class
- _ASSERTE(ftn->GetModule()->IsSystem());
_ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__VOLATILE));
- _ASSERTE(strcmp(ftn->GetMethodTable()->GetClass()->GetDebugClassName(), "System.Threading.Volatile") == 0);
const size_t VolatileMethodBodySize = 6;
@@ -7453,20 +7448,14 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn,
{
STANDARD_VM_CONTRACT;
- // Precondition: ftn is a method in mscorlib in the System.Threading.Interlocked class
- _ASSERTE(ftn->GetModule()->IsSystem());
_ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__INTERLOCKED));
// We are only interested if ftn's token and CompareExchange<T> token match
if (ftn->GetMemberDef() != MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_T)->GetMemberDef())
- return false;
-
- // Get MethodDesc for System.Threading.Interlocked.CompareExchangeFast()
- MethodDesc* cmpxchgFast = MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT);
+ return false;
- // The MethodDesc lookup must not fail, and it should have the name "CompareExchangeFast"
- _ASSERTE(cmpxchgFast != NULL);
- _ASSERTE(strcmp(cmpxchgFast->GetName(), "CompareExchange") == 0);
+ // Get MethodDesc for non-generic System.Threading.Interlocked.CompareExchange()
+ MethodDesc* cmpxchgObject = MscorlibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT);
// Setup up the body of the method
static BYTE il[] = {
@@ -7477,12 +7466,12 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn,
CEE_RET
};
- // Get the token for System.Threading.Interlocked.CompareExchangeFast(), and patch [target]
- mdMethodDef cmpxchgFastToken = cmpxchgFast->GetMemberDef();
- il[4] = (BYTE)((int)cmpxchgFastToken >> 0);
- il[5] = (BYTE)((int)cmpxchgFastToken >> 8);
- il[6] = (BYTE)((int)cmpxchgFastToken >> 16);
- il[7] = (BYTE)((int)cmpxchgFastToken >> 24);
+ // Get the token for non-generic System.Threading.Interlocked.CompareExchange(), and patch [target]
+ mdMethodDef cmpxchgObjectToken = cmpxchgObject->GetMemberDef();
+ il[4] = (BYTE)((int)cmpxchgObjectToken >> 0);
+ il[5] = (BYTE)((int)cmpxchgObjectToken >> 8);
+ il[6] = (BYTE)((int)cmpxchgObjectToken >> 16);
+ il[7] = (BYTE)((int)cmpxchgObjectToken >> 24);
// Initialize methInfo
methInfo->ILCode = const_cast<BYTE*>(il);
@@ -7499,8 +7488,7 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn,
{
STANDARD_VM_CONTRACT;
- // Precondition: ftn is a method in mscorlib
- _ASSERTE(ftn->GetModule()->IsSystem());
+ _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__RUNTIME_HELPERS));
mdMethodDef tk = ftn->GetMemberDef();
@@ -7585,6 +7573,37 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn,
return false;
}
+bool getILIntrinsicImplementationForActivator(MethodDesc* ftn,
+ CORINFO_METHOD_INFO* methInfo,
+ SigPointer* pSig)
+{
+ STANDARD_VM_CONTRACT;
+
+ _ASSERTE(MscorlibBinder::IsClass(ftn->GetMethodTable(), CLASS__ACTIVATOR));
+
+ // We are only interested if ftn's token and CreateInstance<T> token match
+ if (ftn->GetMemberDef() != MscorlibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_INSTANCE_OF_T)->GetMemberDef())
+ return false;
+
+ _ASSERTE(ftn->HasMethodInstantiation());
+ Instantiation inst = ftn->GetMethodInstantiation();
+
+ _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
+ TypeHandle typeHandle = inst[0];
+ MethodTable* methodTable = typeHandle.GetMethodTable();
+
+ if (!methodTable->IsValueType() || methodTable->HasDefaultConstructor())
+ return false;
+
+ // Replace the body with implementation that just returns "default"
+ MethodDesc* createDefaultInstance = MscorlibBinder::GetMethod(METHOD__ACTIVATOR__CREATE_DEFAULT_INSTANCE_OF_T);
+ COR_ILMETHOD_DECODER header(createDefaultInstance->GetILHeader(FALSE), createDefaultInstance->GetMDImport(), NULL);
+ getMethodInfoILMethodHeaderHelper(&header, methInfo);
+ *pSig = SigPointer(header.LocalVarSig, header.cbLocalVarSig);
+
+ return true;
+}
+
//---------------------------------------------------------------------------------------
//
//static
@@ -7640,6 +7659,15 @@ getMethodInfoHelper(
{
fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo);
}
+ else if (MscorlibBinder::IsClass(pMT, CLASS__ACTIVATOR))
+ {
+ SigPointer localSig;
+ fILIntrinsic = getILIntrinsicImplementationForActivator(ftn, methInfo, &localSig);
+ if (fILIntrinsic)
+ {
+ localSig.GetSignature(&pLocalSig, &cbLocalSig);
+ }
+ }
}
if (!fILIntrinsic)
@@ -7653,7 +7681,7 @@ getMethodInfoHelper(
{
_ASSERTE(ftn->IsDynamicMethod());
- DynamicResolver * pResolver = ftn->AsDynamicMethodDesc()->GetResolver();
+ DynamicResolver * pResolver = ftn->AsDynamicMethodDesc()->GetResolver();
unsigned int EHCount;
methInfo->ILCode = pResolver->GetCodeInfo(&methInfo->ILCodeSize,
&methInfo->maxStack,