From ac345794d1ead351be0cb460e53970acf2a235fd Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 10:56:29 -0700 Subject: [PATCH 01/26] Remove unused "shared custom marshaler helper" code --- src/coreclr/vm/custommarshalerinfo.cpp | 55 ---------------------- src/coreclr/vm/custommarshalerinfo.h | 62 ------------------------ src/coreclr/vm/mlinfo.cpp | 65 -------------------------- src/coreclr/vm/mlinfo.h | 4 -- 4 files changed, 186 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 4c7a93441fcf38..0e6b07425d2314 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -591,61 +591,6 @@ void NonSharedCustomMarshalerHelper::operator delete(void *pMem) LIMITED_METHOD_CONTRACT; } - -SharedCustomMarshalerHelper::SharedCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) -: m_pAssembly(pAssembly) -, m_hndManagedType(hndManagedType) -, m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) -, m_strMarshalerTypeName(strMarshalerTypeName) -, m_cCookieStrBytes(cCookieStrBytes) -, m_strCookie(strCookie) -{ - WRAPPER_NO_CONTRACT; -} - - -void *SharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - } - CONTRACTL_END; - - return pHeap->AllocMem(S_SIZE_T(sizeof(SharedCustomMarshalerHelper))); -} - - -void SharedCustomMarshalerHelper::operator delete(void *pMem) -{ - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. - LIMITED_METHOD_CONTRACT; -} - - -CustomMarshalerInfo *SharedCustomMarshalerHelper::GetCustomMarshalerInfo() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // Retrieve the marshalling data for the current app domain. - EEMarshalingData *pMarshalingData = AppDomain::GetCurrentDomain()->GetLoaderAllocator()->GetMarshalingData(); - - // Retrieve the custom marshaling information for the current shared custom - // marshaling helper. - return pMarshalingData->GetCustomMarshalerInfo(this); -} - extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 802918dcd675f9..d1ed7633c11493 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -253,68 +253,6 @@ class NonSharedCustomMarshalerHelper : public CustomMarshalerHelper CustomMarshalerInfo* m_pCMInfo; }; - -class SharedCustomMarshalerHelper : public CustomMarshalerHelper -{ -public: - // Constructor. - SharedCustomMarshalerHelper(Assembly* pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); - - // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void* operator new(size_t size, LoaderHeap* pHeap); - void operator delete(void* pMem); - - // Accessors. - inline Assembly* GetAssembly() - { - LIMITED_METHOD_CONTRACT; - return m_pAssembly; - } - - inline TypeHandle GetManagedType() - { - LIMITED_METHOD_CONTRACT; - return m_hndManagedType; - } - - inline DWORD GetMarshalerTypeNameByteCount() - { - LIMITED_METHOD_CONTRACT; - return m_cMarshalerTypeNameBytes; - } - - inline LPCSTR GetMarshalerTypeName() - { - LIMITED_METHOD_CONTRACT; - return m_strMarshalerTypeName; - } - - inline LPCSTR GetCookieString() - { - LIMITED_METHOD_CONTRACT; - return m_strCookie; - } - - inline ULONG GetCookieStringByteCount() - { - LIMITED_METHOD_CONTRACT; - return m_cCookieStrBytes; - } - -protected: - // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo(); - -private: - Assembly* m_pAssembly; - TypeHandle m_hndManagedType; - DWORD m_cMarshalerTypeNameBytes; - LPCUTF8 m_strMarshalerTypeName; - DWORD m_cCookieStrBytes; - LPCUTF8 m_strCookie; -}; - extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject); #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 8131e4fd3053a4..3bcf1cb9aaf50b 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -822,7 +822,6 @@ EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) LockOwner lock = {pCrst, IsOwnerOfCrst}; m_structILStubCache.Init(INITIAL_NUM_STRUCT_ILSTUB_HASHTABLE_BUCKETS, &lock); m_CMHelperHashtable.Init(INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS, &lock); - m_SharedCMHelperToCMInfoMap.Init(INITIAL_NUM_CMINFO_HASHTABLE_BUCKETS, &lock); } @@ -971,70 +970,6 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss RETURN pNewCMHelper; } -CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper) -{ - CONTRACT (CustomMarshalerInfo*) - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - CustomMarshalerInfo *pCMInfo = NULL; - NewHolder pNewCMInfo(NULL); - TypeHandle hndCustomMarshalerType; - - // Lookup the custom marshaler helper in the hashtable. - if (m_SharedCMHelperToCMInfoMap.GetValue(pSharedCMHelper, (HashDatum*)&pCMInfo)) - RETURN pCMInfo; - - // Append a NULL terminator to the marshaler type name. - CQuickArray strCMMarshalerTypeName; - DWORD strLen = pSharedCMHelper->GetMarshalerTypeNameByteCount(); - strCMMarshalerTypeName.ReSizeThrows(pSharedCMHelper->GetMarshalerTypeNameByteCount() + 1); - memcpy(strCMMarshalerTypeName.Ptr(), pSharedCMHelper->GetMarshalerTypeName(), strLen); - strCMMarshalerTypeName[strLen] = 0; - - // Load the custom marshaler class. - hndCustomMarshalerType = TypeName::GetTypeReferencedByCustomAttribute(strCMMarshalerTypeName.Ptr(), pSharedCMHelper->GetAssembly()); - if (hndCustomMarshalerType.IsGenericTypeDefinition()) - { - // Instantiate generic custom marshalers using the instantiation of the type being marshaled. - hndCustomMarshalerType = hndCustomMarshalerType.Instantiate(pSharedCMHelper->GetManagedType().GetInstantiation()); - } - - // Create the custom marshaler info in the specified heap. - pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, - hndCustomMarshalerType, - pSharedCMHelper->GetManagedType(), - pSharedCMHelper->GetCookieString(), - pSharedCMHelper->GetCookieStringByteCount()); - - { - CrstHolder lock(m_lock); - - // Verify that the custom marshaler info has not already been added by another thread. - if (m_SharedCMHelperToCMInfoMap.GetValue(pSharedCMHelper, (HashDatum*)&pCMInfo)) - { - RETURN pCMInfo; - } - - // Add the custom marshaler helper to the hash table. - m_SharedCMHelperToCMInfoMap.InsertValue(pSharedCMHelper, pNewCMInfo, FALSE); - - // Add the custom marshaler into the linked list. - m_pCMInfoList.InsertHead(pNewCMInfo); - - // Release the lock and return the custom marshaler info. - } - - pNewCMInfo.SuppressRelease(); - RETURN pNewCMInfo; -} - #ifdef FEATURE_COMINTEROP OleColorMarshalingInfo *EEMarshalingData::GetOleColorMarshalingInfo() { diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 93a0f554d30af4..5d8d267c0c979f 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -264,9 +264,6 @@ class EEMarshalingData // CM info has not been created yet for this pair then it will be created and returned. CustomMarshalerHelper *GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); - // This method returns the custom marshaling info associated with shared CM helper. - CustomMarshalerInfo *GetCustomMarshalerInfo(SharedCustomMarshalerHelper *pSharedCMHelper); - #ifdef FEATURE_COMINTEROP // This method retrieves OLE_COLOR marshaling info. OleColorMarshalingInfo *GetOleColorMarshalingInfo(); @@ -275,7 +272,6 @@ class EEMarshalingData private: EEPtrHashTable m_structILStubCache; EECMHelperHashTable m_CMHelperHashtable; - EEPtrHashTable m_SharedCMHelperToCMInfoMap; LoaderAllocator* m_pAllocator; LoaderHeap* m_pHeap; CMINFOLIST m_pCMInfoList; From 3093d4a6dbb0d116d556fb78d6d8365c49824a5d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 11:01:13 -0700 Subject: [PATCH 02/26] Collapse together the custom marshaller helper types --- src/coreclr/vm/custommarshalerinfo.cpp | 6 ++-- src/coreclr/vm/custommarshalerinfo.h | 42 ++++++++------------------ src/coreclr/vm/mlinfo.cpp | 2 +- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 0e6b07425d2314..ee42af1c28a1e5 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -568,7 +568,7 @@ void CustomMarshalerHelper::InvokeCleanUpManagedMeth(OBJECTREF MngObj) } -void *NonSharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) +void *CustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) { CONTRACTL { @@ -580,11 +580,11 @@ void *NonSharedCustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHea } CONTRACTL_END; - return pHeap->AllocMem(S_SIZE_T(sizeof(NonSharedCustomMarshalerHelper))); + return pHeap->AllocMem(S_SIZE_T(sizeof(CustomMarshalerHelper))); } -void NonSharedCustomMarshalerHelper::operator delete(void *pMem) +void CustomMarshalerHelper::operator delete(void *pMem) { // Instances of this class are always allocated on the loader heap so // the delete operator has nothing to do. diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index d1ed7633c11493..b2a7959d100634 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -182,9 +182,20 @@ class EECMHelperHashtableHelper typedef EEHashTable EECMHelperHashTable; -class CustomMarshalerHelper +class CustomMarshalerHelper final { public: + CustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) + : m_pCMInfo(pCMInfo) + { + WRAPPER_NO_CONTRACT; + } + + // CustomMarshalerHelpers are always allocated on the loader heap so we need to redefine + // the new and delete operators to ensure this. + void *operator new(size_t size, LoaderHeap *pHeap); + void operator delete(void* pMem); + // Helpers used to invoke the different methods in the ICustomMarshaler interface. OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); @@ -217,35 +228,8 @@ class CustomMarshalerHelper } // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo() = 0; - -protected: - ~CustomMarshalerHelper( void ) - { - LIMITED_METHOD_CONTRACT; - } -}; - - -class NonSharedCustomMarshalerHelper : public CustomMarshalerHelper -{ -public: - // Constructor. - NonSharedCustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) : m_pCMInfo(pCMInfo) - { - WRAPPER_NO_CONTRACT; - } - - // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void *operator new(size_t size, LoaderHeap *pHeap); - void operator delete(void* pMem); - -protected: - // Helper function to retrieve the custom marshaler object. - virtual CustomMarshalerInfo* GetCustomMarshalerInfo() + CustomMarshalerInfo* GetCustomMarshalerInfo() { - LIMITED_METHOD_CONTRACT; return m_pCMInfo; } diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 3bcf1cb9aaf50b..b858b2b34cd3ae 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -942,7 +942,7 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, hndCustomMarshalerType, hndManagedType, strCookie, cCookieStrBytes); // Create the custom marshaler helper in the specified heap. - pNewCMHelper = new (m_pHeap) NonSharedCustomMarshalerHelper(pNewCMInfo); + pNewCMHelper = new (m_pHeap) CustomMarshalerHelper(pNewCMInfo); } { From 094b807f76b9a317d308ba83909c4ee3136fb9e6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 11:23:08 -0700 Subject: [PATCH 03/26] Remove CustomMarshalerHelper abstraction --- src/coreclr/vm/custommarshalerinfo.cpp | 157 +++---------------------- src/coreclr/vm/custommarshalerinfo.h | 75 ++---------- src/coreclr/vm/dispparammarshaler.cpp | 8 +- src/coreclr/vm/dispparammarshaler.h | 8 +- src/coreclr/vm/mlinfo.cpp | 54 ++++----- src/coreclr/vm/mlinfo.h | 8 +- 6 files changed, 60 insertions(+), 250 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index ee42af1c28a1e5..09a38f035ee865 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -230,35 +230,6 @@ void *CustomMarshalerInfo::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) return RetVal; } - -void CustomMarshalerInfo::InvokeCleanUpNativeMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pNative, NULL_OK)); - } - CONTRACTL_END; - - if (!pNative) - return; - - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite cleanUpNativeData(m_pCleanUpNativeDataMD, &customMarshaler); - - ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - PtrToArgSlot(pNative) - }; - - cleanUpNativeData.Call(Args); - GCPROTECT_END(); -} - - void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) { CONTRACTL @@ -361,7 +332,7 @@ MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods // Implementation of the custom marshaler hashtable helper. //========================================================================== -EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey *pKey, BOOL bDeepCopy, void* pHeap) +EEHashEntry_t * EECMInfoHashtableHelper::AllocateEntry(EECMInfoHashtableKey *pKey, BOOL bDeepCopy, void* pHeap) { CONTRACTL { @@ -376,11 +347,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey if (bDeepCopy) { - S_SIZE_T cbEntry = S_SIZE_T(sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)); + S_SIZE_T cbEntry = S_SIZE_T(sizeof(EEHashEntry) - 1 + sizeof(EECMInfoHashtableKey)); cbEntry += S_SIZE_T(pKey->GetMarshalerTypeNameByteCount()); cbEntry += S_SIZE_T(pKey->GetCookieStringByteCount()); cbEntry += S_SIZE_T(pKey->GetMarshalerInstantiation().GetNumArgs()) * S_SIZE_T(sizeof(LPVOID)); - cbEntry += S_SIZE_T(sizeof(LPVOID)); // For EECMHelperHashtableKey::m_invokingAssembly + cbEntry += S_SIZE_T(sizeof(LPVOID)); // For EECMInfoHashtableKey::m_invokingAssembly if (cbEntry.IsOverflow()) return NULL; @@ -389,11 +360,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey if (!pEntry) return NULL; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); - pEntryKey->m_strMarshalerTypeName = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey); + pEntryKey->m_strMarshalerTypeName = (LPSTR) pEntry->Key + sizeof(EECMInfoHashtableKey); pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); - pEntryKey->m_strCookie = (LPSTR) pEntry->Key + sizeof(EECMHelperHashtableKey) + pEntryKey->m_cMarshalerTypeNameBytes; + pEntryKey->m_strCookie = (LPSTR) pEntry->Key + sizeof(EECMInfoHashtableKey) + pEntryKey->m_cMarshalerTypeNameBytes; pEntryKey->m_Instantiation = Instantiation( (TypeHandle *) (pEntryKey->m_strCookie + pEntryKey->m_cCookieStrBytes), pKey->GetMarshalerInstantiation().GetNumArgs()); @@ -406,11 +377,11 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey else { pEntry = (EEHashEntry_t *) - new (nothrow) BYTE[sizeof(EEHashEntry) - 1 + sizeof(EECMHelperHashtableKey)]; + new (nothrow) BYTE[sizeof(EEHashEntry) - 1 + sizeof(EECMInfoHashtableKey)]; if (!pEntry) return NULL; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; pEntryKey->m_cMarshalerTypeNameBytes = pKey->GetMarshalerTypeNameByteCount(); pEntryKey->m_strMarshalerTypeName = pKey->GetMarshalerTypeName(); pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); @@ -423,7 +394,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey } -void EECMHelperHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) +void EECMInfoHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) { CONTRACTL { @@ -438,7 +409,7 @@ void EECMHelperHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) } -BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHashtableKey *pKey) +BOOL EECMInfoHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMInfoHashtableKey *pKey) { CONTRACTL { @@ -450,7 +421,7 @@ BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHas } CONTRACTL_END; - EECMHelperHashtableKey *pEntryKey = (EECMHelperHashtableKey *) pEntry->Key; + EECMInfoHashtableKey *pEntryKey = (EECMInfoHashtableKey *) pEntry->Key; if (pEntryKey->GetMarshalerTypeNameByteCount() != pKey->GetMarshalerTypeNameByteCount()) return FALSE; @@ -481,7 +452,7 @@ BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHas } -DWORD EECMHelperHashtableHelper::Hash(EECMHelperHashtableKey *pKey) +DWORD EECMInfoHashtableHelper::Hash(EECMInfoHashtableKey *pKey) { WRAPPER_NO_CONTRACT; @@ -491,113 +462,13 @@ DWORD EECMHelperHashtableHelper::Hash(EECMHelperHashtableKey *pKey) HashBytes((const BYTE *) pKey->GetMarshalerInstantiation().GetRawArgs(), pKey->GetMarshalerInstantiation().GetNumArgs() * sizeof(LPVOID))); } - -OBJECTREF CustomMarshalerHelper::InvokeMarshalNativeToManagedMeth(void *pNative) -{ - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->InvokeMarshalNativeToManagedMeth(pNative); -} - - -void *CustomMarshalerHelper::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - void *RetVal = NULL; - - GCPROTECT_BEGIN(MngObj) - { - CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); - RetVal = pCMInfo->InvokeMarshalManagedToNativeMeth(MngObj); - } - GCPROTECT_END(); - - return RetVal; -} - - -void CustomMarshalerHelper::InvokeCleanUpNativeMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - OBJECTREF ExceptionObj = NULL; - GCPROTECT_BEGIN(ExceptionObj) - { - EX_TRY - { - GetCustomMarshalerInfo()->InvokeCleanUpNativeMeth(pNative); - } - EX_CATCH - { - ExceptionObj = GET_THROWABLE(); - } - EX_END_CATCH(SwallowAllExceptions); - } - GCPROTECT_END(); -} - - -void CustomMarshalerHelper::InvokeCleanUpManagedMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - GCPROTECT_BEGIN(MngObj) - { - CustomMarshalerInfo *pCMInfo = GetCustomMarshalerInfo(); - pCMInfo->InvokeCleanUpManagedMeth(MngObj); - } - GCPROTECT_END(); -} - - -void *CustomMarshalerHelper::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - } - CONTRACTL_END; - - return pHeap->AllocMem(S_SIZE_T(sizeof(CustomMarshalerHelper))); -} - - -void CustomMarshalerHelper::operator delete(void *pMem) -{ - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. - LIMITED_METHOD_CONTRACT; -} - -extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject) +extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerInfo* pCMHelper, QCall::ObjectHandleOnStack retObject) { QCALL_CONTRACT; BEGIN_QCALL; GCX_COOP(); - retObject.Set(pCMHelper->GetCustomMarshalerInfo()->GetCustomMarshaler()); + retObject.Set(pCMHelper->GetCustomMarshaler()); END_QCALL; } diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index b2a7959d100634..8ccec45ded8e35 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -31,7 +31,7 @@ enum EnumCustomMarshalerMethods }; -class CustomMarshalerInfo +class CustomMarshalerInfo final { public: // Constructor and destructor. @@ -46,7 +46,6 @@ class CustomMarshalerInfo // Helpers used to invoke the different methods in the ICustomMarshaler interface. OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); - void InvokeCleanUpNativeMeth(void* pNative); void InvokeCleanUpManagedMeth(OBJECTREF MngObj); // Accessors. @@ -115,10 +114,10 @@ typedef SList CMINFOLIST; class Assembly; -class EECMHelperHashtableKey +class EECMInfoHashtableKey { public: - EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation, Assembly* invokingAssembly) + EECMInfoHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation, Assembly* invokingAssembly) : m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) , m_strMarshalerTypeName(strMarshalerTypeName) , m_cCookieStrBytes(cCookieStrBytes) @@ -169,74 +168,18 @@ class EECMHelperHashtableKey }; -class EECMHelperHashtableHelper +class EECMInfoHashtableHelper { public: - static EEHashEntry_t* AllocateEntry(EECMHelperHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap); + static EEHashEntry_t* AllocateEntry(EECMInfoHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap); static void DeleteEntry(EEHashEntry_t* pEntry, AllocationHeap Heap); - static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMHelperHashtableKey* pKey); - static DWORD Hash(EECMHelperHashtableKey* pKey); + static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMInfoHashtableKey* pKey); + static DWORD Hash(EECMInfoHashtableKey* pKey); }; -typedef EEHashTable EECMHelperHashTable; +typedef EEHashTable EECMInfoHashTable; - -class CustomMarshalerHelper final -{ -public: - CustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) - : m_pCMInfo(pCMInfo) - { - WRAPPER_NO_CONTRACT; - } - - // CustomMarshalerHelpers are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void *operator new(size_t size, LoaderHeap *pHeap); - void operator delete(void* pMem); - - // Helpers used to invoke the different methods in the ICustomMarshaler interface. - OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); - void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); - void InvokeCleanUpNativeMeth(void* pNative); - void InvokeCleanUpManagedMeth(OBJECTREF MngObj); - - // Accessors. - int GetNativeSize() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetNativeSize(); - } - - int GetManagedSize() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetManagedSize(); - } - - TypeHandle GetManagedType() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->GetManagedType(); - } - - BOOL IsDataByValue() - { - WRAPPER_NO_CONTRACT; - return GetCustomMarshalerInfo()->IsDataByValue(); - } - - // Helper function to retrieve the custom marshaler object. - CustomMarshalerInfo* GetCustomMarshalerInfo() - { - return m_pCMInfo; - } - -private: - CustomMarshalerInfo* m_pCMInfo; -}; - -extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerHelper* pCMHelper, QCall::ObjectHandleOnStack retObject); +extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerInfo* pCMHelper, QCall::ObjectHandleOnStack retObject); #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index 9286bd1ec39fab..49044c051380dd 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -556,7 +556,7 @@ void DispParamCustomMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECTRE IUnknown *pUnk = bByref ? *V_UNKNOWNREF(pSrcVar) : V_UNKNOWN(pSrcVar); // Marshal the contents of the VARIANT using the custom marshaler. - *pDestObj = m_pCMHelper->InvokeMarshalNativeToManagedMeth(pUnk); + *pDestObj = m_pCMInfo->InvokeMarshalNativeToManagedMeth(pUnk); } void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT *pDestVar) @@ -577,7 +577,7 @@ void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIAN SafeVariantClear(pDestVar); // Invoke the MarshalManagedToNative method. - pUnk = (IUnknown*)m_pCMHelper->InvokeMarshalManagedToNativeMeth(*pSrcObj); + pUnk = (IUnknown*)m_pCMInfo->InvokeMarshalManagedToNativeMeth(*pSrcObj); if (!pUnk) { // Put a null IDispatch pointer in the VARIANT. @@ -631,7 +631,7 @@ void DispParamCustomMarshaler::MarshalManagedToNativeRef(OBJECTREF *pSrcObj, VAR SafeVariantClear(&vtmp); // Convert the object using the custom marshaler. - V_UNKNOWN(&vtmp) = (IUnknown*)m_pCMHelper->InvokeMarshalManagedToNativeMeth(*pSrcObj); + V_UNKNOWN(&vtmp) = (IUnknown*)m_pCMInfo->InvokeMarshalManagedToNativeMeth(*pSrcObj); V_VT(&vtmp) = m_vt; // Call VariantChangeType if required. @@ -661,5 +661,5 @@ void DispParamCustomMarshaler::CleanUpManaged(OBJECTREF *pObj) MODE_COOPERATIVE; } CONTRACTL_END; - m_pCMHelper->InvokeCleanUpManagedMeth(*pObj); + m_pCMInfo->InvokeCleanUpManagedMeth(*pObj); } diff --git a/src/coreclr/vm/dispparammarshaler.h b/src/coreclr/vm/dispparammarshaler.h index 5bf22445dbedc9..51d4a359da420e 100644 --- a/src/coreclr/vm/dispparammarshaler.h +++ b/src/coreclr/vm/dispparammarshaler.h @@ -196,8 +196,8 @@ class DispParamDelegateMarshaler : public DispParamMarshaler class DispParamCustomMarshaler : public DispParamMarshaler { public: - DispParamCustomMarshaler(CustomMarshalerHelper *pCMHelper, VARTYPE vt) : - m_pCMHelper(pCMHelper), + DispParamCustomMarshaler(CustomMarshalerInfo *pCMHelper, VARTYPE vt) : + m_pCMInfo(pCMHelper), m_vt(vt) { WRAPPER_NO_CONTRACT; @@ -215,8 +215,8 @@ class DispParamCustomMarshaler : public DispParamMarshaler virtual void CleanUpManaged(OBJECTREF *pObj); private: - CustomMarshalerHelper* m_pCMHelper; - VARTYPE m_vt; + CustomMarshalerInfo* m_pCMInfo; + VARTYPE m_vt; }; #endif // _DISPPARAMMARSHALER_H diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index b858b2b34cd3ae..c7ce800a94b652 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -387,9 +387,9 @@ namespace //========================================================================== // Set's up the custom marshaler information. //========================================================================== -CustomMarshalerHelper *SetupCustomMarshalerHelper(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) +CustomMarshalerInfo *SetupCustomMarshalerInfo(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) { - CONTRACT (CustomMarshalerHelper*) + CONTRACT (CustomMarshalerInfo*) { STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pAssembly)); @@ -403,7 +403,7 @@ CustomMarshalerHelper *SetupCustomMarshalerHelper(LPCUTF8 strMarshalerTypeName, pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); // Retrieve the custom marshaler helper from the EE marshaling data. - RETURN pMarshalingData->GetCustomMarshalerHelper(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); + RETURN pMarshalingData->GetCustomMarshalerInfo(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); } namespace @@ -821,7 +821,7 @@ EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) LockOwner lock = {pCrst, IsOwnerOfCrst}; m_structILStubCache.Init(INITIAL_NUM_STRUCT_ILSTUB_HASHTABLE_BUCKETS, &lock); - m_CMHelperHashtable.Init(INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS, &lock); + m_CMInfoHashTable.Init(INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS, &lock); } @@ -894,9 +894,9 @@ void EEMarshalingData::CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD) } -CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) +CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes) { - CONTRACT (CustomMarshalerHelper*) + CONTRACT (CustomMarshalerInfo*) { THROWS; GC_TRIGGERS; @@ -907,18 +907,17 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss } CONTRACT_END; - CustomMarshalerHelper *pCMHelper = NULL; - CustomMarshalerHelper* pNewCMHelper = NULL; + CustomMarshalerInfo *pCMInfo = NULL; NewHolder pNewCMInfo(NULL); TypeHandle hndCustomMarshalerType; // Create the key that will be used to lookup in the hashtable. - EECMHelperHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation(), pAssembly); + EECMInfoHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation(), pAssembly); // Lookup the custom marshaler helper in the hashtable. - if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) - RETURN pCMHelper; + if (m_CMInfoHashTable.GetValue(&Key, (HashDatum*)&pCMInfo)) + RETURN pCMInfo; { GCX_COOP(); @@ -940,22 +939,19 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss // Create the custom marshaler info in the specified heap. pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, hndCustomMarshalerType, hndManagedType, strCookie, cCookieStrBytes); - - // Create the custom marshaler helper in the specified heap. - pNewCMHelper = new (m_pHeap) CustomMarshalerHelper(pNewCMInfo); } { CrstHolder lock(m_lock); // Verify that the custom marshaler helper has not already been added by another thread. - if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) + if (m_CMInfoHashTable.GetValue(&Key, (HashDatum*)&pCMInfo)) { - RETURN pCMHelper; + RETURN pCMInfo; } // Add the custom marshaler helper to the hash table. - m_CMHelperHashtable.InsertValue(&Key, pNewCMHelper, FALSE); + m_CMInfoHashTable.InsertValue(&Key, pNewCMInfo, FALSE); // If we create the CM info, then add it to the linked list. if (pNewCMInfo) @@ -967,7 +963,7 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss // Release the lock and return the custom marshaler info. } - RETURN pNewCMHelper; + RETURN pNewCMInfo; } #ifdef FEATURE_COMINTEROP @@ -1192,7 +1188,7 @@ MarshalInfo::MarshalInfo(Module* pModule, m_ms = ms; m_fAnsi = (ms == MARSHAL_SCENARIO_NDIRECT || ms == MARSHAL_SCENARIO_FIELD) && (nlType == nltAnsi); m_nativeArgSize = 0; - m_pCMHelper = NULL; + m_pCMInfo = NULL; m_CMVt = VT_EMPTY; m_args.m_pMarshalInfo = this; m_args.m_pMT = NULL; @@ -1389,7 +1385,7 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(E_FAIL, lFail); } - // Set m_type to MARSHAL_TYPE_UNKNOWN in case SetupCustomMarshalerHelper throws. + // Set m_type to MARSHAL_TYPE_UNKNOWN in case SetupCustomMarshalerInfo throws. m_type = MARSHAL_TYPE_UNKNOWN; if (fLoadCustomMarshal) @@ -1399,7 +1395,7 @@ MarshalInfo::MarshalInfo(Module* pModule, if (!fEmitsIL) { - m_pCMHelper = SetupCustomMarshalerHelper(ParamInfo.m_strCMMarshalerTypeName, + m_pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, ParamInfo.m_cCMMarshalerTypeNameBytes, ParamInfo.m_strCMCookie, ParamInfo.m_cCMCookieStrBytes, @@ -1408,7 +1404,7 @@ MarshalInfo::MarshalInfo(Module* pModule, } else { - m_pCMHelper = NULL; + m_pCMInfo = NULL; MethodDesc* pMDforModule = pMD; if (pMD->IsILStub()) { @@ -1887,7 +1883,7 @@ MarshalInfo::MarshalInfo(Module* pModule, { if (!fEmitsIL) { - m_pCMHelper = SetupCustomMarshalerHelper(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, + m_pCMInfo = SetupCustomMarshalerInfo(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, @@ -1895,7 +1891,7 @@ MarshalInfo::MarshalInfo(Module* pModule, } else { - m_pCMHelper = NULL; + m_pCMInfo = NULL; MethodDesc* pMDforModule = pMD; if (pMD->IsILStub()) { @@ -3562,7 +3558,7 @@ DispParamMarshaler *MarshalInfo::GenerateDispParamMarshaler() break; case MARSHAL_TYPE_REFERENCECUSTOMMARSHALER: - pDispParamMarshaler = new DispParamCustomMarshaler(m_pCMHelper, m_CMVt); + pDispParamMarshaler = new DispParamCustomMarshaler(m_pCMInfo, m_CMVt); break; } @@ -4018,7 +4014,7 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p { QCALL_CONTRACT; - CustomMarshalerHelper* pCMHelper = NULL; + CustomMarshalerInfo* pCMInfo = NULL; BEGIN_QCALL; @@ -4029,7 +4025,7 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p if (!hndManagedType.IsTypeDesc() && IsTypeRefOrDef(g_CollectionsEnumeratorClassName, hndManagedType.GetModule(), hndManagedType.GetCl())) { - pCMHelper = SetupCustomMarshalerHelper(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, + pCMInfo = SetupCustomMarshalerInfo(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, @@ -4053,7 +4049,7 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p CONSISTENCY_CHECK(ParamInfo.m_NativeType == NATIVE_TYPE_CUSTOMMARSHALER); // Set up the custom marshaler info. - pCMHelper = SetupCustomMarshalerHelper(ParamInfo.m_strCMMarshalerTypeName, + pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, ParamInfo.m_cCMMarshalerTypeNameBytes, ParamInfo.m_strCMCookie, ParamInfo.m_cCMCookieStrBytes, @@ -4063,6 +4059,6 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p END_QCALL; - return (void*)pCMHelper; + return (void*)pCMInfo; } diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 5d8d267c0c979f..2e08afa382f431 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -260,9 +260,9 @@ class EEMarshalingData void CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD); #endif - // This method returns the custom marshaling helper associated with the name cookie pair. If the + // This method returns the custom marshaling info associated with the name cookie pair. If the // CM info has not been created yet for this pair then it will be created and returned. - CustomMarshalerHelper *GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); + CustomMarshalerInfo *GetCustomMarshalerInfo(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); #ifdef FEATURE_COMINTEROP // This method retrieves OLE_COLOR marshaling info. @@ -271,7 +271,7 @@ class EEMarshalingData private: EEPtrHashTable m_structILStubCache; - EECMHelperHashTable m_CMHelperHashtable; + EECMInfoHashTable m_CMInfoHashTable; LoaderAllocator* m_pAllocator; LoaderHeap* m_pHeap; CMINFOLIST m_pCMInfoList; @@ -542,7 +542,7 @@ class MarshalInfo #endif // FEATURE_COMINTEROP // Information used by NT_CUSTOMMARSHALER. - CustomMarshalerHelper* m_pCMHelper; + CustomMarshalerInfo* m_pCMInfo; VARTYPE m_CMVt; OverrideProcArgs m_args; From 3b8a5b9566c2b25e5110f89fca53c4d5fc615f45 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 11:40:16 -0700 Subject: [PATCH 04/26] ICustomMarshaler will never support by-value marshalling, so remove the checks outside of the exception path. --- src/coreclr/vm/custommarshalerinfo.cpp | 20 ++++---------------- src/coreclr/vm/custommarshalerinfo.h | 7 ------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 09a38f035ee865..cd3af6f40abeb1 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -30,7 +30,6 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type , m_pMarshalManagedToNativeMD(NULL) , m_pCleanUpNativeDataMD(NULL) , m_pCleanUpManagedDataMD(NULL) -, m_bDataIsByValue(FALSE) { CONTRACTL { @@ -51,11 +50,8 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); } - // Determine if this type is a value class. - m_bDataIsByValue = m_hndManagedType.GetMethodTable()->IsValueType(); - - // Custom marshalling of value classes is not currently supported. - if (m_bDataIsByValue) + // Custom marshalling of value classes is not supported. + if (m_hndManagedType.GetMethodTable()->IsValueType()) COMPlusThrow(kNotSupportedException, W("NotSupported_ValueClassCM")); // Run the on the marshaler since it might not have run yet. @@ -114,16 +110,8 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type m_hndCustomMarshaler = pLoaderAllocator->AllocateHandle(CustomMarshalerObj); GCPROTECT_END(); - // Retrieve the size of the native data. - if (m_bDataIsByValue) - { - // @TODO(DM): Call GetNativeDataSize() to retrieve the size of the native data. - _ASSERTE(!"Value classes are not yet supported by the custom marshaler!"); - } - else - { - m_NativeSize = sizeof(void *); - } + // We only support non-value classes, so the native size is the size of a pointer. + m_NativeSize = sizeof(void *); GCPROTECT_END(); } diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 8ccec45ded8e35..4bafd3951ce1ca 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -67,12 +67,6 @@ class CustomMarshalerInfo final return m_hndManagedType; } - BOOL IsDataByValue() - { - LIMITED_METHOD_CONTRACT; - return m_bDataIsByValue; - } - OBJECTREF GetCustomMarshaler() { LIMITED_METHOD_CONTRACT; @@ -106,7 +100,6 @@ class CustomMarshalerInfo final MethodDesc* m_pMarshalManagedToNativeMD; MethodDesc* m_pCleanUpNativeDataMD; MethodDesc* m_pCleanUpManagedDataMD; - BOOL m_bDataIsByValue; }; From d4e3e08bed7d86d38ce08392f3ef58c577fc8a7c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 13:03:35 -0700 Subject: [PATCH 05/26] Remove native size local as we always set it to the same thing --- src/coreclr/vm/custommarshalerinfo.cpp | 7 +------ src/coreclr/vm/custommarshalerinfo.h | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index cd3af6f40abeb1..6c25191d923b02 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -22,8 +22,7 @@ //========================================================================== CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) -: m_NativeSize(0) -, m_hndManagedType(hndManagedType) +: m_hndManagedType(hndManagedType) , m_pLoaderAllocator(pLoaderAllocator) , m_hndCustomMarshaler{} , m_pMarshalNativeToManagedMD(NULL) @@ -109,10 +108,6 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type m_hndCustomMarshaler = pLoaderAllocator->AllocateHandle(CustomMarshalerObj); GCPROTECT_END(); - - // We only support non-value classes, so the native size is the size of a pointer. - m_NativeSize = sizeof(void *); - GCPROTECT_END(); } diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 4bafd3951ce1ca..9a4febba2b8d95 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -52,7 +52,8 @@ class CustomMarshalerInfo final int GetNativeSize() { LIMITED_METHOD_CONTRACT; - return m_NativeSize; + // [COMPAT] We only support non-value classes, so the native size is the size of a pointer. + return sizeof(void*); } int GetManagedSize() @@ -92,7 +93,6 @@ class CustomMarshalerInfo final SLink m_Link; private: - int m_NativeSize; TypeHandle m_hndManagedType; LoaderAllocator* m_pLoaderAllocator; LOADERHANDLE m_hndCustomMarshaler; From aa0894cae2ec52c7ac6918a3f5b08099aac8ff6b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 13:37:34 -0700 Subject: [PATCH 06/26] Remove unused methods --- src/coreclr/vm/custommarshalerinfo.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 9a4febba2b8d95..d744b2e687125a 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -49,19 +49,6 @@ class CustomMarshalerInfo final void InvokeCleanUpManagedMeth(OBJECTREF MngObj); // Accessors. - int GetNativeSize() - { - LIMITED_METHOD_CONTRACT; - // [COMPAT] We only support non-value classes, so the native size is the size of a pointer. - return sizeof(void*); - } - - int GetManagedSize() - { - WRAPPER_NO_CONTRACT; - return m_hndManagedType.GetSize(); - } - TypeHandle GetManagedType() { LIMITED_METHOD_CONTRACT; @@ -74,18 +61,6 @@ class CustomMarshalerInfo final return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); } - TypeHandle GetCustomMarshalerType() - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - } - CONTRACTL_END; - return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler)->GetTypeHandle(); - } - // Helper function to retrieve a custom marshaler method desc. static MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype); From f2e869d2f33b88491c3ff56db8d866861f9b6141 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 14:17:37 -0700 Subject: [PATCH 07/26] Remove more unused code --- src/coreclr/vm/corelib.h | 2 - src/coreclr/vm/custommarshalerinfo.cpp | 155 ++++++++++++------------- src/coreclr/vm/custommarshalerinfo.h | 22 ---- 3 files changed, 76 insertions(+), 103 deletions(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 745d762e832209..6745c740d8a19d 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -390,9 +390,7 @@ DEFINE_METHOD(ICUSTOM_ATTR_PROVIDER,GET_CUSTOM_ATTRIBUTES, GetCustomAttributes, DEFINE_CLASS(ICUSTOM_MARSHALER, Interop, ICustomMarshaler) DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_NATIVE_TO_MANAGED,MarshalNativeToManaged, IM_IntPtr_RetObj) DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_MANAGED_TO_NATIVE,MarshalManagedToNative, IM_Obj_RetIntPtr) -DEFINE_METHOD(ICUSTOM_MARSHALER, CLEANUP_NATIVE_DATA, CleanUpNativeData, IM_IntPtr_RetVoid) DEFINE_METHOD(ICUSTOM_MARSHALER, CLEANUP_MANAGED_DATA, CleanUpManagedData, IM_Obj_RetVoid) -DEFINE_METHOD(ICUSTOM_MARSHALER, GET_NATIVE_DATA_SIZE, GetNativeDataSize, IM_RetInt) DEFINE_CLASS(ICUSTOMADAPTER, Interop, ICustomAdapter) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 6c25191d923b02..48712efa042d02 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -17,17 +17,85 @@ #include "mlinfo.h" #include "sigbuilder.h" +namespace +{ + enum class CustomMarshalerMethod + { + MarshalNativeToManaged, + MarshalManagedToNative, + CleanUpManagedData, + GetInstance + }; + + MethodDesc * GetCustomMarshalerMD(CustomMarshalerMethod Method, TypeHandle hndCustomMarshalertype) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + + MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); + + _ASSERTE(pMT->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); + + MethodDesc *pMD = NULL; + + switch (Method) + { + case CustomMarshalerMethod::MarshalNativeToManaged: + pMD = pMT->GetMethodDescForInterfaceMethod( + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), + TRUE /* throwOnConflict */); + break; + case CustomMarshalerMethod::MarshalManagedToNative: + pMD = pMT->GetMethodDescForInterfaceMethod( + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), + TRUE /* throwOnConflict */); + break; + + case CustomMarshalerMethod::CleanUpManagedData: + pMD = pMT->GetMethodDescForInterfaceMethod( + CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), + TRUE /* throwOnConflict */); + break; + case CustomMarshalerMethod::GetInstance: + // Must look this up by name since it's static + pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); + if (!pMD) + { + DefineFullyQualifiedNameForClassW() + COMPlusThrow(kApplicationException, + IDS_EE_GETINSTANCENOTIMPL, + GetFullyQualifiedNameForClassW(pMT)); + } + break; + default: + _ASSERTE(!"Unknown custom marshaler method"); + } + + _ASSERTE(pMD && "Unable to find specified CustomMarshaler method"); + + // Ensure that the value types in the signature are loaded. + MetaSig::EnsureSigValueTypesLoaded(pMD); + + // Return the specified method desc. + return pMD; + } +} + //========================================================================== // Implementation of the custom marshaler info class. //========================================================================== CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) -: m_hndManagedType(hndManagedType) -, m_pLoaderAllocator(pLoaderAllocator) +: m_pLoaderAllocator(pLoaderAllocator) , m_hndCustomMarshaler{} , m_pMarshalNativeToManagedMD(NULL) , m_pMarshalManagedToNativeMD(NULL) -, m_pCleanUpNativeDataMD(NULL) , m_pCleanUpManagedDataMD(NULL) { CONTRACTL @@ -50,7 +118,7 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type } // Custom marshalling of value classes is not supported. - if (m_hndManagedType.GetMethodTable()->IsValueType()) + if (hndManagedType.GetMethodTable()->IsValueType()) COMPlusThrow(kNotSupportedException, W("NotSupported_ValueClassCM")); // Run the on the marshaler since it might not have run yet. @@ -61,7 +129,7 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type STRINGREF CookieStringObj = StringObject::NewString(strCookie, cCookieStrBytes); GCPROTECT_BEGIN(CookieStringObj); // Load the method desc for the static method to retrieve the instance. - MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethods_GetInstance, hndCustomMarshalerType); + MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethod::GetInstance, hndCustomMarshalerType); // If the GetInstance method is generic, get an instantiating stub for it - // the CallDescr infrastructure doesn't know how to pass secret generic arguments. @@ -101,10 +169,9 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type // Load the method desc's for all the methods in the ICustomMarshaler interface based on the type of the marshaler object. TypeHandle customMarshalerObjType = CustomMarshalerObj->GetMethodTable(); - m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalNativeToManaged, customMarshalerObjType); - m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethods_MarshalManagedToNative, customMarshalerObjType); - m_pCleanUpNativeDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpNativeData, customMarshalerObjType); - m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethods_CleanUpManagedData, customMarshalerObjType); + m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethod::MarshalNativeToManaged, customMarshalerObjType); + m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethod::MarshalManagedToNative, customMarshalerObjType); + m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethod::CleanUpManagedData, customMarshalerObjType); m_hndCustomMarshaler = pLoaderAllocator->AllocateHandle(CustomMarshalerObj); GCPROTECT_END(); @@ -241,76 +308,6 @@ void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) GCPROTECT_END (); } -MethodDesc *CustomMarshalerInfo::GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - - MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); - - _ASSERTE(pMT->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); - - MethodDesc *pMD = NULL; - - switch (Method) - { - case CustomMarshalerMethods_MarshalNativeToManaged: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_MarshalManagedToNative: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_CleanUpNativeData: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_NATIVE_DATA), - TRUE /* throwOnConflict */); - break; - - case CustomMarshalerMethods_CleanUpManagedData: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_GetNativeDataSize: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__GET_NATIVE_DATA_SIZE), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethods_GetInstance: - // Must look this up by name since it's static - pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); - if (!pMD) - { - DefineFullyQualifiedNameForClassW() - COMPlusThrow(kApplicationException, - IDS_EE_GETINSTANCENOTIMPL, - GetFullyQualifiedNameForClassW(pMT)); - } - break; - default: - _ASSERTE(!"Unknown custom marshaler method"); - } - - _ASSERTE(pMD && "Unable to find specified CustomMarshaler method"); - - // Ensure that the value types in the signature are loaded. - MetaSig::EnsureSigValueTypesLoaded(pMD); - - // Return the specified method desc. - return pMD; -} - - //========================================================================== // Implementation of the custom marshaler hashtable helper. //========================================================================== diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index d744b2e687125a..cb0a7b86a6a8cb 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -19,17 +19,6 @@ // This enumeration is used to retrieve a method desc from CustomMarshalerInfo::GetCustomMarshalerMD(). -enum EnumCustomMarshalerMethods -{ - CustomMarshalerMethods_MarshalNativeToManaged = 0, - CustomMarshalerMethods_MarshalManagedToNative, - CustomMarshalerMethods_CleanUpNativeData, - CustomMarshalerMethods_CleanUpManagedData, - CustomMarshalerMethods_GetNativeDataSize, - CustomMarshalerMethods_GetInstance, - CustomMarshalerMethods_LastMember -}; - class CustomMarshalerInfo final { @@ -49,31 +38,20 @@ class CustomMarshalerInfo final void InvokeCleanUpManagedMeth(OBJECTREF MngObj); // Accessors. - TypeHandle GetManagedType() - { - LIMITED_METHOD_CONTRACT; - return m_hndManagedType; - } - OBJECTREF GetCustomMarshaler() { LIMITED_METHOD_CONTRACT; return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); } - // Helper function to retrieve a custom marshaler method desc. - static MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype); - // Link used to contain this CM info in a linked list. SLink m_Link; private: - TypeHandle m_hndManagedType; LoaderAllocator* m_pLoaderAllocator; LOADERHANDLE m_hndCustomMarshaler; MethodDesc* m_pMarshalNativeToManagedMD; MethodDesc* m_pMarshalManagedToNativeMD; - MethodDesc* m_pCleanUpNativeDataMD; MethodDesc* m_pCleanUpManagedDataMD; }; From fd9dfefce5ea55180857de850dd1d00f5daba5f2 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 14:23:13 -0700 Subject: [PATCH 08/26] Use the same helpers in CustomMarshalerInfo as the IL stubs use --- src/coreclr/vm/corelib.h | 3 - src/coreclr/vm/custommarshalerinfo.cpp | 84 +++++++++++--------------- src/coreclr/vm/custommarshalerinfo.h | 3 - src/coreclr/vm/metasig.h | 2 - 4 files changed, 35 insertions(+), 57 deletions(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 6745c740d8a19d..b58363a7e68ea3 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -388,9 +388,6 @@ DEFINE_CLASS(ICUSTOM_ATTR_PROVIDER, Reflection, ICustomAttributeProv DEFINE_METHOD(ICUSTOM_ATTR_PROVIDER,GET_CUSTOM_ATTRIBUTES, GetCustomAttributes, IM_Type_RetArrObj) DEFINE_CLASS(ICUSTOM_MARSHALER, Interop, ICustomMarshaler) -DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_NATIVE_TO_MANAGED,MarshalNativeToManaged, IM_IntPtr_RetObj) -DEFINE_METHOD(ICUSTOM_MARSHALER, MARSHAL_MANAGED_TO_NATIVE,MarshalManagedToNative, IM_Obj_RetIntPtr) -DEFINE_METHOD(ICUSTOM_MARSHALER, CLEANUP_MANAGED_DATA, CleanUpManagedData, IM_Obj_RetVoid) DEFINE_CLASS(ICUSTOMADAPTER, Interop, ICustomAdapter) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 48712efa042d02..57a632b91d8d9c 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -21,9 +21,6 @@ namespace { enum class CustomMarshalerMethod { - MarshalNativeToManaged, - MarshalManagedToNative, - CleanUpManagedData, GetInstance }; @@ -46,22 +43,6 @@ namespace switch (Method) { - case CustomMarshalerMethod::MarshalNativeToManaged: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_NATIVE_TO_MANAGED), - TRUE /* throwOnConflict */); - break; - case CustomMarshalerMethod::MarshalManagedToNative: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__MARSHAL_MANAGED_TO_NATIVE), - TRUE /* throwOnConflict */); - break; - - case CustomMarshalerMethod::CleanUpManagedData: - pMD = pMT->GetMethodDescForInterfaceMethod( - CoreLibBinder::GetMethod(METHOD__ICUSTOM_MARSHALER__CLEANUP_MANAGED_DATA), - TRUE /* throwOnConflict */); - break; case CustomMarshalerMethod::GetInstance: // Must look this up by name since it's static pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); @@ -94,9 +75,6 @@ namespace CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) : m_pLoaderAllocator(pLoaderAllocator) , m_hndCustomMarshaler{} -, m_pMarshalNativeToManagedMD(NULL) -, m_pMarshalManagedToNativeMD(NULL) -, m_pCleanUpManagedDataMD(NULL) { CONTRACTL { @@ -166,12 +144,6 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type IDS_EE_NOCUSTOMMARSHALER, GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); } - // Load the method desc's for all the methods in the ICustomMarshaler interface based on the type of the marshaler object. - TypeHandle customMarshalerObjType = CustomMarshalerObj->GetMethodTable(); - - m_pMarshalNativeToManagedMD = GetCustomMarshalerMD(CustomMarshalerMethod::MarshalNativeToManaged, customMarshalerObjType); - m_pMarshalManagedToNativeMD = GetCustomMarshalerMD(CustomMarshalerMethod::MarshalManagedToNative, customMarshalerObjType); - m_pCleanUpManagedDataMD = GetCustomMarshalerMD(CustomMarshalerMethod::CleanUpManagedData, customMarshalerObjType); m_hndCustomMarshaler = pLoaderAllocator->AllocateHandle(CustomMarshalerObj); GCPROTECT_END(); @@ -230,21 +202,25 @@ OBJECTREF CustomMarshalerInfo::InvokeMarshalNativeToManagedMeth(void *pNative) if (!pNative) return NULL; - OBJECTREF managedObject; + struct { + OBJECTREF managedObject; + OBJECTREF customMarshaler; + } gc = { NULL, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite marshalNativeToManaged(m_pMarshalNativeToManagedMD, &customMarshaler); + GCPROTECT_BEGIN (gc); + MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_MANAGED); ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - PtrToArgSlot(pNative) + ObjToArgSlot(gc.customMarshaler), + PtrToArgSlot(&gc.managedObject), + PtrToArgSlot(&pNative) }; - managedObject = marshalNativeToManaged.Call_RetOBJECTREF(Args); + marshalNativeToManaged.Call(Args); GCPROTECT_END (); - return managedObject; + return gc.managedObject; } @@ -263,18 +239,22 @@ void *CustomMarshalerInfo::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) if (!MngObj) return NULL; - GCPROTECT_BEGIN (MngObj); + struct { + OBJECTREF managedObject; + OBJECTREF customMarshaler; + } gc = { MngObj, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; + OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite marshalManagedToNative(m_pMarshalManagedToNativeMD, &customMarshaler); + GCPROTECT_BEGIN (gc); + MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - ObjToArgSlot(MngObj) + ObjToArgSlot(gc.customMarshaler), + PtrToArgSlot(&gc.managedObject), + PtrToArgSlot(&RetVal) }; - RetVal = marshalManagedToNative.Call_RetLPVOID(Args); - GCPROTECT_END (); + marshalNativeToManaged.Call(Args); GCPROTECT_END (); return RetVal; @@ -293,18 +273,24 @@ void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) if (!MngObj) return; - GCPROTECT_BEGIN (MngObj); + struct { + OBJECTREF managedObject; + OBJECTREF customMarshaler; + } gc = { MngObj, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; + OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (customMarshaler); - MethodDescCallSite cleanUpManagedData(m_pCleanUpManagedDataMD, &customMarshaler); + GCPROTECT_BEGIN (gc); + MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CLEAR_MANAGED); + + void* dummyNative = nullptr; ARG_SLOT Args[] = { - ObjToArgSlot(customMarshaler), - ObjToArgSlot(MngObj) + ObjToArgSlot(gc.customMarshaler), + PtrToArgSlot(&gc.managedObject), + PtrToArgSlot(&dummyNative) }; - cleanUpManagedData.Call(Args); - GCPROTECT_END (); + marshalNativeToManaged.Call(Args); GCPROTECT_END (); } diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index cb0a7b86a6a8cb..bb0fb51eeec2c6 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -50,9 +50,6 @@ class CustomMarshalerInfo final private: LoaderAllocator* m_pLoaderAllocator; LOADERHANDLE m_hndCustomMarshaler; - MethodDesc* m_pMarshalNativeToManagedMD; - MethodDesc* m_pMarshalManagedToNativeMD; - MethodDesc* m_pCleanUpManagedDataMD; }; diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 0a9f50a7a912cd..7e2fb8cb6ea389 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -449,12 +449,10 @@ DEFINE_METASIG_T(IM(Obj_EventArgs_RetVoid, j C(EVENT_ARGS), v)) DEFINE_METASIG_T(IM(Exception_RetVoid, C(EXCEPTION), v)) -DEFINE_METASIG(IM(IntPtr_RetObj, I, j)) DEFINE_METASIG(IM(IntPtr_RetVoid, I, v)) DEFINE_METASIG_T(IM(RefGuid_RetIntPtr, r(g(GUID)), I)) DEFINE_METASIG(IM(Obj_RetInt, j, i)) -DEFINE_METASIG(IM(Obj_RetIntPtr, j, I)) DEFINE_METASIG(IM(Obj_RetVoid, j, v)) DEFINE_METASIG(IM(Obj_RetObj, j, j)) DEFINE_METASIG(IM(Obj_IntPtr_RetVoid, j I, v)) From dcfe926d93d1a5f937bc76f72cb7ccc0c427fbee Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 14:28:16 -0700 Subject: [PATCH 09/26] The only method we look up is GetInstance, so clean that up --- src/coreclr/vm/custommarshalerinfo.cpp | 69 ++++++++++---------------- 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 57a632b91d8d9c..f2d3da4a467f9f 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -19,12 +19,7 @@ namespace { - enum class CustomMarshalerMethod - { - GetInstance - }; - - MethodDesc * GetCustomMarshalerMD(CustomMarshalerMethod Method, TypeHandle hndCustomMarshalertype) + MethodDesc * FindGetInstanceMethod(TypeHandle hndCustomMarshalerType) { CONTRACTL { @@ -35,31 +30,32 @@ namespace CONTRACTL_END; - MethodTable *pMT = hndCustomMarshalertype.AsMethodTable(); - - _ASSERTE(pMT->CanCastToInterface(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); - - MethodDesc *pMD = NULL; + MethodTable *pMT = hndCustomMarshalerType.AsMethodTable(); - switch (Method) + MethodDesc *pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); + if (!pMD) { - case CustomMarshalerMethod::GetInstance: - // Must look this up by name since it's static - pMD = MemberLoader::FindMethod(pMT, "GetInstance", &gsig_SM_Str_RetICustomMarshaler); - if (!pMD) - { - DefineFullyQualifiedNameForClassW() - COMPlusThrow(kApplicationException, - IDS_EE_GETINSTANCENOTIMPL, - GetFullyQualifiedNameForClassW(pMT)); - } - break; - default: - _ASSERTE(!"Unknown custom marshaler method"); + DefineFullyQualifiedNameForClassW() + COMPlusThrow(kApplicationException, + IDS_EE_GETINSTANCENOTIMPL, + GetFullyQualifiedNameForClassW(pMT)); + }; + + // If the GetInstance method is generic, get an instantiating stub for it - + // the CallDescr infrastructure doesn't know how to pass secret generic arguments. + if (pMD->RequiresInstMethodTableArg()) + { + pMD = MethodDesc::FindOrCreateAssociatedMethodDesc( + pMD, + hndCustomMarshalerType.GetMethodTable(), + FALSE, // forceBoxedEntryPoint + Instantiation(), // methodInst + FALSE, // allowInstParam + FALSE); // forceRemotableMethod + + _ASSERTE(!pMD->RequiresInstMethodTableArg()); } - _ASSERTE(pMD && "Unable to find specified CustomMarshaler method"); - // Ensure that the value types in the signature are loaded. MetaSig::EnsureSigValueTypesLoaded(pMD); @@ -103,26 +99,11 @@ CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, Type hndCustomMarshalerType.GetMethodTable()->EnsureInstanceActive(); hndCustomMarshalerType.GetMethodTable()->CheckRunClassInitThrowing(); - // Create a COM+ string that will contain the string cookie. + // Create a .NET string that will contain the string cookie. STRINGREF CookieStringObj = StringObject::NewString(strCookie, cCookieStrBytes); GCPROTECT_BEGIN(CookieStringObj); // Load the method desc for the static method to retrieve the instance. - MethodDesc *pGetCustomMarshalerMD = GetCustomMarshalerMD(CustomMarshalerMethod::GetInstance, hndCustomMarshalerType); - - // If the GetInstance method is generic, get an instantiating stub for it - - // the CallDescr infrastructure doesn't know how to pass secret generic arguments. - if (pGetCustomMarshalerMD->RequiresInstMethodTableArg()) - { - pGetCustomMarshalerMD = MethodDesc::FindOrCreateAssociatedMethodDesc( - pGetCustomMarshalerMD, - hndCustomMarshalerType.GetMethodTable(), - FALSE, // forceBoxedEntryPoint - Instantiation(), // methodInst - FALSE, // allowInstParam - FALSE); // forceRemotableMethod - - _ASSERTE(!pGetCustomMarshalerMD->RequiresInstMethodTableArg()); - } + MethodDesc *pGetCustomMarshalerMD = FindGetInstanceMethod(hndCustomMarshalerType); MethodDescCallSite getCustomMarshaler(pGetCustomMarshalerMD, (OBJECTREF*)&CookieStringObj); From 1841ea5b20077fa263b366c1c040dcec28dda87b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 14:48:26 -0700 Subject: [PATCH 10/26] Move ICustomMarshaler method invocation into the only usage location in the runtime --- src/coreclr/vm/custommarshalerinfo.cpp | 106 ------------------------- src/coreclr/vm/custommarshalerinfo.h | 8 -- src/coreclr/vm/dispparammarshaler.cpp | 58 +++++++++++++- 3 files changed, 54 insertions(+), 118 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index f2d3da4a467f9f..0fc6aa74e7a42d 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -169,112 +169,6 @@ void CustomMarshalerInfo::operator delete(void *pMem) LIMITED_METHOD_CONTRACT; } -OBJECTREF CustomMarshalerInfo::InvokeMarshalNativeToManagedMeth(void *pNative) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pNative, NULL_OK)); - } - CONTRACTL_END; - - if (!pNative) - return NULL; - - struct { - OBJECTREF managedObject; - OBJECTREF customMarshaler; - } gc = { NULL, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; - - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (gc); - MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_MANAGED); - - ARG_SLOT Args[] = { - ObjToArgSlot(gc.customMarshaler), - PtrToArgSlot(&gc.managedObject), - PtrToArgSlot(&pNative) - }; - - marshalNativeToManaged.Call(Args); - GCPROTECT_END (); - - return gc.managedObject; -} - - -void *CustomMarshalerInfo::InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - void *RetVal = NULL; - - if (!MngObj) - return NULL; - - struct { - OBJECTREF managedObject; - OBJECTREF customMarshaler; - } gc = { MngObj, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; - - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (gc); - MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); - - ARG_SLOT Args[] = { - ObjToArgSlot(gc.customMarshaler), - PtrToArgSlot(&gc.managedObject), - PtrToArgSlot(&RetVal) - }; - - marshalNativeToManaged.Call(Args); - GCPROTECT_END (); - - return RetVal; -} - -void CustomMarshalerInfo::InvokeCleanUpManagedMeth(OBJECTREF MngObj) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - if (!MngObj) - return; - - struct { - OBJECTREF managedObject; - OBJECTREF customMarshaler; - } gc = { MngObj, m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler) }; - - OBJECTREF customMarshaler = m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); - GCPROTECT_BEGIN (gc); - MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CLEAR_MANAGED); - - void* dummyNative = nullptr; - - ARG_SLOT Args[] = { - ObjToArgSlot(gc.customMarshaler), - PtrToArgSlot(&gc.managedObject), - PtrToArgSlot(&dummyNative) - }; - - marshalNativeToManaged.Call(Args); - GCPROTECT_END (); -} - //========================================================================== // Implementation of the custom marshaler hashtable helper. //========================================================================== diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index bb0fb51eeec2c6..73c0418b04b568 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -17,9 +17,6 @@ #include "vars.hpp" #include "slist.h" - -// This enumeration is used to retrieve a method desc from CustomMarshalerInfo::GetCustomMarshalerMD(). - class CustomMarshalerInfo final { public: @@ -32,11 +29,6 @@ class CustomMarshalerInfo final void* operator new(size_t size, LoaderHeap* pHeap); void operator delete(void* pMem); - // Helpers used to invoke the different methods in the ICustomMarshaler interface. - OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); - void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); - void InvokeCleanUpManagedMeth(OBJECTREF MngObj); - // Accessors. OBJECTREF GetCustomMarshaler() { diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index 49044c051380dd..0f6aabb48bbb82 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -556,7 +556,18 @@ void DispParamCustomMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECTRE IUnknown *pUnk = bByref ? *V_UNKNOWNREF(pSrcVar) : V_UNKNOWN(pSrcVar); // Marshal the contents of the VARIANT using the custom marshaler. - *pDestObj = m_pCMInfo->InvokeMarshalNativeToManagedMeth(pUnk); + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalNativeToManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_MANAGED); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pDestObj), + PtrToArgSlot(&pUnk) + }; + + marshalNativeToManaged.Call(Args); + GCPROTECT_END (); } void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT *pDestVar) @@ -577,7 +588,21 @@ void DispParamCustomMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIAN SafeVariantClear(pDestVar); // Invoke the MarshalManagedToNative method. - pUnk = (IUnknown*)m_pCMInfo->InvokeMarshalManagedToNativeMeth(*pSrcObj); + IUnknown* pUnkRaw = nullptr; + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalManagedToNative(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pSrcObj), + PtrToArgSlot(&pUnkRaw) + }; + + marshalManagedToNative.Call(Args); + GCPROTECT_END(); + pUnk = pUnkRaw; + if (!pUnk) { // Put a null IDispatch pointer in the VARIANT. @@ -631,7 +656,18 @@ void DispParamCustomMarshaler::MarshalManagedToNativeRef(OBJECTREF *pSrcObj, VAR SafeVariantClear(&vtmp); // Convert the object using the custom marshaler. - V_UNKNOWN(&vtmp) = (IUnknown*)m_pCMInfo->InvokeMarshalManagedToNativeMeth(*pSrcObj); + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite marshalManagedToNative(METHOD__MNGD_REF_CUSTOM_MARSHALER__CONVERT_CONTENTS_TO_NATIVE); + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pSrcObj), + PtrToArgSlot(V_UNKNOWN(&vtmp)) + }; + + marshalManagedToNative.Call(Args); + GCPROTECT_END(); V_VT(&vtmp) = m_vt; // Call VariantChangeType if required. @@ -661,5 +697,19 @@ void DispParamCustomMarshaler::CleanUpManaged(OBJECTREF *pObj) MODE_COOPERATIVE; } CONTRACTL_END; - m_pCMInfo->InvokeCleanUpManagedMeth(*pObj); + + OBJECTREF customMarshaler = m_pCMInfo->GetCustomMarshaler(); + GCPROTECT_BEGIN (customMarshaler); + MethodDescCallSite clearManaged(METHOD__MNGD_REF_CUSTOM_MARSHALER__CLEAR_MANAGED); + + void* dummyNative = nullptr; + + ARG_SLOT Args[] = { + ObjToArgSlot(customMarshaler), + PtrToArgSlot(pObj), + PtrToArgSlot(&dummyNative) + }; + + clearManaged.Call(Args); + GCPROTECT_END (); } From 3321129e8874f414549eff2e2fd39b8aa8eca9d6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 15:12:10 -0700 Subject: [PATCH 11/26] Remove CustomMarshalerInfo abstraction from P/Invoke IL stubs (inline the indirection into the stub helper) --- .../src/System/StubHelpers.cs | 21 ++++++++----------- src/coreclr/vm/corelib.h | 2 +- src/coreclr/vm/custommarshalerinfo.cpp | 11 ---------- src/coreclr/vm/custommarshalerinfo.h | 2 -- src/coreclr/vm/ilmarshalers.cpp | 7 ++----- src/coreclr/vm/metasig.h | 2 +- src/coreclr/vm/mlinfo.cpp | 10 ++++----- src/coreclr/vm/qcallentrypoints.cpp | 3 +-- src/coreclr/vm/stubhelpers.h | 2 +- 9 files changed, 20 insertions(+), 40 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 4d04557565c3ca..551b43c9b25e8b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -792,16 +792,6 @@ internal static void ClearNative(IntPtr pMarshalState, in object pManagedHome, I internal static unsafe partial class MngdRefCustomMarshaler { - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomMarshaler_GetMarshalerObject")] - private static partial void GetMarshaler(IntPtr pCMHelper, ObjectHandleOnStack retMarshaler); - - internal static ICustomMarshaler GetMarshaler(IntPtr pCMHelper) - { - ICustomMarshaler? marshaler = null; - GetMarshaler(pCMHelper, ObjectHandleOnStack.Create(ref marshaler)); - return marshaler!; - } - internal static unsafe void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome) { // COMPAT: We never pass null to MarshalManagedToNative. @@ -1463,8 +1453,15 @@ internal static void SetPendingExceptionObject(Exception? exception) s_pendingExceptionObject = exception; } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshalerHelper")] - internal static partial IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshaler")] + internal static partial void CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType, ObjectHandleOnStack customMarshaler); + + internal static object CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType) + { + object? retVal = null; + CreateCustomMarshaler(pMD, paramToken, hndManagedType, ObjectHandleOnStack.Create(ref retVal)); + return retVal!; + } //------------------------------------------------------- // SafeHandle Helpers diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index b58363a7e68ea3..32afcfd15aa9dd 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -929,7 +929,7 @@ DEFINE_METHOD(STUBHELPERS, KEEP_ALIVE_VIA_CLEANUP_LIST, KeepAliveVia DEFINE_METHOD(STUBHELPERS, DESTROY_CLEANUP_LIST, DestroyCleanupList, SM_RefCleanupWorkListElement_RetVoid) DEFINE_METHOD(STUBHELPERS, GET_HR_EXCEPTION_OBJECT, GetHRExceptionObject, SM_Int_RetException) DEFINE_METHOD(STUBHELPERS, GET_PENDING_EXCEPTION_OBJECT, GetPendingExceptionObject, SM_RetException) -DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER_HELPER, CreateCustomMarshalerHelper, SM_IntPtr_Int_IntPtr_RetIntPtr) +DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER, CreateCustomMarshaler, SM_IntPtr_Int_IntPtr_RetObj) DEFINE_METHOD(STUBHELPERS, CHECK_STRING_LENGTH, CheckStringLength, SM_Int_RetVoid) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 0fc6aa74e7a42d..6f214a56255fae 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -302,14 +302,3 @@ DWORD EECMInfoHashtableHelper::Hash(EECMInfoHashtableKey *pKey) HashBytes((const BYTE *) pKey->GetCookieString(), pKey->GetCookieStringByteCount()) + HashBytes((const BYTE *) pKey->GetMarshalerInstantiation().GetRawArgs(), pKey->GetMarshalerInstantiation().GetNumArgs() * sizeof(LPVOID))); } - -extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerInfo* pCMHelper, QCall::ObjectHandleOnStack retObject) -{ - QCALL_CONTRACT; - BEGIN_QCALL; - GCX_COOP(); - - retObject.Set(pCMHelper->GetCustomMarshaler()); - - END_QCALL; -} diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 73c0418b04b568..ef2e3e6777592e 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -115,6 +115,4 @@ class EECMInfoHashtableHelper typedef EEHashTable EECMInfoHashTable; -extern "C" void QCALLTYPE CustomMarshaler_GetMarshalerObject(CustomMarshalerInfo* pCMHelper, QCall::ObjectHandleOnStack retObject); - #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 75d979076bd3a9..0da47a32c279ac 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -4974,7 +4974,7 @@ void ILReferenceCustomMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit m_dwMngdMarshalerLocalNum = pslILEmit->NewLocal(LocalDesc(CoreLibBinder::GetClass(CLASS__ICUSTOM_MARSHALER))); // - // call CreateCustomMarshalerHelper + // call CreateCustomMarshaler // pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(m_pargs->rcm.m_pMD)); @@ -4985,10 +4985,7 @@ void ILReferenceCustomMarshaler::EmitCreateMngdMarshaler(ILCodeStream* pslILEmit pslILEmit->EmitLDTOKEN(pslILEmit->GetToken(TypeHandle::FromPtr(m_pargs->rcm.m_hndManagedType))); pslILEmit->EmitCALL(METHOD__RT_TYPE_HANDLE__TO_INTPTR, 1, 1); - pslILEmit->EmitCALL(METHOD__STUBHELPERS__CREATE_CUSTOM_MARSHALER_HELPER, 3, 1); // Create the CustomMarshalerHelper - - // Get the managed ICustomMarshaler object from the helper - pslILEmit->EmitCALL(METHOD__MNGD_REF_CUSTOM_MARSHALER__GET_MARSHALER, 1, 1); + pslILEmit->EmitCALL(METHOD__STUBHELPERS__CREATE_CUSTOM_MARSHALER, 3, 1); // Create the ICustomMarshaler pslILEmit->EmitSTLOC(m_dwMngdMarshalerLocalNum); // Store the ICustomMarshaler as our marshaler state } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 7e2fb8cb6ea389..70bd3e2a82848d 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -208,7 +208,7 @@ DEFINE_METASIG(SM(IntPtr_IntPtr_Obj_RetIntPtr, I I j, I)) DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Obj_RetIntPtr, I I i j, I)) DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_RetVoid, I I I, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_IntPtr_UShrt_IntPtr_RetVoid, I I I H I, v)) -DEFINE_METASIG(SM(IntPtr_Int_IntPtr_RetIntPtr, I i I, I)) +DEFINE_METASIG(SM(IntPtr_Int_IntPtr_RetObj, I i I, j)) DEFINE_METASIG(SM(IntPtr_IntPtr_Int_Bool_IntPtr_RetVoid, I I i F I, v)) DEFINE_METASIG(SM(IntPtr_IntPtr_Obj_RetVoid, I I j, v)) DEFINE_METASIG_T(SM(Obj_Array_RetVoid, j C(ARRAY), v)) diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index c7ce800a94b652..80502ba9d762d8 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -4010,14 +4010,14 @@ bool IsUnsupportedTypedrefReturn(MetaSig& msig) #include "stubhelpers.h" -extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType) +extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType, QCall::ObjectHandleOnStack retObject) { QCALL_CONTRACT; - CustomMarshalerInfo* pCMInfo = NULL; - BEGIN_QCALL; + CustomMarshalerInfo* pCMInfo = NULL; + Module* pModule = pMD->GetModule(); Assembly* pAssembly = pModule->GetAssembly(); @@ -4057,8 +4057,8 @@ extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* p hndManagedType); } - END_QCALL; + retObject.Set(pCMInfo->GetCustomMarshaler()); - return (void*)pCMInfo; + END_QCALL; } diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 13f95076df6468..6dc6e90b9e9a42 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -225,7 +225,6 @@ static const Entry s_QCall[] = DllImportEntry(MultiCoreJIT_InternalStartProfile) #endif DllImportEntry(LoaderAllocator_Destroy) - DllImportEntry(CustomMarshaler_GetMarshalerObject) DllImportEntry(String_Intern) DllImportEntry(String_IsInterned) DllImportEntry(AppDomain_CreateDynamicAssembly) @@ -422,7 +421,7 @@ static const Entry s_QCall[] = #if defined(TARGET_X86) || defined(TARGET_AMD64) DllImportEntry(X86BaseCpuId) #endif - DllImportEntry(StubHelpers_CreateCustomMarshalerHelper) + DllImportEntry(StubHelpers_CreateCustomMarshaler) DllImportEntry(StubHelpers_SetStringTrailByte) DllImportEntry(StubHelpers_ThrowInteropParamException) #if defined(FEATURE_COMINTEROP) diff --git a/src/coreclr/vm/stubhelpers.h b/src/coreclr/vm/stubhelpers.h index 3a5c1f30e5781a..639d1ae3a1e303 100644 --- a/src/coreclr/vm/stubhelpers.h +++ b/src/coreclr/vm/stubhelpers.h @@ -80,7 +80,7 @@ class StubHelpers static FCDECL0(void*, NextCallReturnAddress); }; -extern "C" void* QCALLTYPE StubHelpers_CreateCustomMarshalerHelper(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType); +extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdToken paramToken, TypeHandle hndManagedType, QCall::ObjectHandleOnStack retObject); #ifdef FEATURE_COMINTEROP extern "C" void QCALLTYPE ObjectMarshaler_ConvertToNative(QCall::ObjectHandleOnStack pSrcUNSAFE, VARIANT* pDest); From 8bdde74dff35cba734b742988a1f76141ccc741a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 15:18:17 -0700 Subject: [PATCH 12/26] Change default deep copy option to the one we use in the one case we insert --- src/coreclr/vm/custommarshalerinfo.h | 2 +- src/coreclr/vm/mlinfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index ef2e3e6777592e..15dc48203ac633 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -113,6 +113,6 @@ class EECMInfoHashtableHelper }; -typedef EEHashTable EECMInfoHashTable; +typedef EEHashTable EECMInfoHashTable; #endif // _CUSTOMMARSHALERINFO_H_ diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 80502ba9d762d8..7d8e031316e027 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -951,7 +951,7 @@ CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembl } // Add the custom marshaler helper to the hash table. - m_CMInfoHashTable.InsertValue(&Key, pNewCMInfo, FALSE); + m_CMInfoHashTable.InsertValue(&Key, pNewCMInfo); // If we create the CM info, then add it to the linked list. if (pNewCMInfo) From 0a185b4c42f66ba3c786f72e76b23d8332ccc35e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 19 Aug 2024 17:12:47 -0700 Subject: [PATCH 13/26] Move IEnumerator marshaller support up to managed code only --- .../src/System/StubHelpers.cs | 11 ++ src/coreclr/vm/corelib.h | 3 + src/coreclr/vm/custommarshalerinfo.cpp | 33 ++++ src/coreclr/vm/custommarshalerinfo.h | 15 +- src/coreclr/vm/mlinfo.cpp | 159 ++++++++++-------- src/coreclr/vm/mlinfo.h | 3 +- 6 files changed, 146 insertions(+), 78 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 551b43c9b25e8b..b148a7b7debf72 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -4,7 +4,9 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.CustomMarshalers; using System.Runtime.InteropServices.Marshalling; +using System.Runtime.Versioning; using System.Text; namespace System.StubHelpers @@ -1456,8 +1458,17 @@ internal static void SetPendingExceptionObject(Exception? exception) [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshaler")] internal static partial void CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType, ObjectHandleOnStack customMarshaler); + [SupportedOSPlatform("windows")] + internal static object GetIEnumeratorToEnumVariantMarshaler() => EnumeratorToEnumVariantMarshaler.GetInstance(string.Empty); + internal static object CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType) { + if (hndManagedType == typeof(System.Collections.IEnumerator).TypeHandle.Value + && OperatingSystem.IsWindows()) + { + return GetIEnumeratorToEnumVariantMarshaler(); + } + object? retVal = null; CreateCustomMarshaler(pMD, paramToken, hndManagedType, ObjectHandleOnStack.Create(ref retVal)); return retVal!; diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 32afcfd15aa9dd..52e36418447bb3 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -930,6 +930,9 @@ DEFINE_METHOD(STUBHELPERS, DESTROY_CLEANUP_LIST, DestroyCleanupList, DEFINE_METHOD(STUBHELPERS, GET_HR_EXCEPTION_OBJECT, GetHRExceptionObject, SM_Int_RetException) DEFINE_METHOD(STUBHELPERS, GET_PENDING_EXCEPTION_OBJECT, GetPendingExceptionObject, SM_RetException) DEFINE_METHOD(STUBHELPERS, CREATE_CUSTOM_MARSHALER, CreateCustomMarshaler, SM_IntPtr_Int_IntPtr_RetObj) +#ifdef FEATURE_COMINTEROP +DEFINE_METHOD(STUBHELPERS, GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER, GetIEnumeratorToEnumVariantMarshaler, SM_RetObj) +#endif // FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, CHECK_STRING_LENGTH, CheckStringLength, SM_Int_RetVoid) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 6f214a56255fae..2324e2d7292f84 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -169,6 +169,35 @@ void CustomMarshalerInfo::operator delete(void *pMem) LIMITED_METHOD_CONTRACT; } +#ifdef FEATURE_COMINTEROP +CustomMarshalerInfo* CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(LoaderHeap* pHeap, LoaderAllocator* pLoaderAllocator) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(pHeap)); + PRECONDITION(CheckPointer(pLoaderAllocator)); + } + CONTRACTL_END; + + CustomMarshalerInfo* pInfo = nullptr; + OBJECTREF IEnumeratorMarshalerObj = nullptr; + + GCPROTECT_BEGIN(IEnumeratorMarshalerObj); + + MethodDescCallSite getMarshaler(METHOD__STUBHELPERS__GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER); + IEnumeratorMarshalerObj = getMarshaler.Call_RetOBJECTREF(NULL); + + pInfo = new (pHeap) CustomMarshalerInfo(pLoaderAllocator, pLoaderAllocator->AllocateHandle(IEnumeratorMarshalerObj)); + + GCPROTECT_END(); + + return pInfo; +} +#endif + //========================================================================== // Implementation of the custom marshaler hashtable helper. //========================================================================== @@ -246,6 +275,10 @@ void EECMInfoHashtableHelper::DeleteEntry(EEHashEntry_t *pEntry, void* pHeap) } CONTRACTL_END; + CustomMarshalerInfo* pInfo = reinterpret_cast(pEntry->Data); + + delete pInfo; + delete[] (BYTE*)pEntry; } diff --git a/src/coreclr/vm/custommarshalerinfo.h b/src/coreclr/vm/custommarshalerinfo.h index 15dc48203ac633..98dd71858a0a9b 100644 --- a/src/coreclr/vm/custommarshalerinfo.h +++ b/src/coreclr/vm/custommarshalerinfo.h @@ -36,16 +36,21 @@ class CustomMarshalerInfo final return m_pLoaderAllocator->GetHandleValue(m_hndCustomMarshaler); } - // Link used to contain this CM info in a linked list. - SLink m_Link; +#ifdef FEATURE_COMINTEROP + static CustomMarshalerInfo* CreateIEnumeratorMarshalerInfo(LoaderHeap* pHeap, LoaderAllocator* pLoaderAllocator); +#endif // FEATURE_COMINTEROP private: LoaderAllocator* m_pLoaderAllocator; LOADERHANDLE m_hndCustomMarshaler; -}; - -typedef SList CMINFOLIST; + CustomMarshalerInfo(LoaderAllocator* pLoaderAllocator, LOADERHANDLE hndCustomMarshaler) + : m_pLoaderAllocator(pLoaderAllocator) + , m_hndCustomMarshaler(hndCustomMarshaler) + { + LIMITED_METHOD_CONTRACT; + } +}; class Assembly; diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 7d8e031316e027..921dd071edcb94 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -26,12 +26,6 @@ #endif // FEATURE_COMINTEROP #ifdef FEATURE_COMINTEROP - DEFINE_ASM_QUAL_TYPE_NAME(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, g_EnumeratorToEnumClassName, g_CorelibAsmName); - - static const int ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN = ARRAY_SIZE(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME); - static const char ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE[] = {""}; - static const int ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN = ARRAY_SIZE(ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE); - DEFINE_ASM_QUAL_TYPE_NAME(COLOR_TRANSLATOR_ASM_QUAL_TYPE_NAME, g_ColorTranslatorClassName, g_DrawingAsmName); DEFINE_ASM_QUAL_TYPE_NAME(COLOR_ASM_QUAL_TYPE_NAME, g_ColorClassName, g_DrawingAsmName); @@ -382,32 +376,50 @@ namespace } } } -} -//========================================================================== -// Set's up the custom marshaler information. -//========================================================================== -CustomMarshalerInfo *SetupCustomMarshalerInfo(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) -{ - CONTRACT (CustomMarshalerInfo*) + //========================================================================== + // Sets up the custom marshaler information. + //========================================================================== + CustomMarshalerInfo *SetupCustomMarshalerInfo(LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes, Assembly *pAssembly, TypeHandle hndManagedType) { - STANDARD_VM_CHECK; - PRECONDITION(CheckPointer(pAssembly)); - POSTCONDITION(CheckPointer(RETVAL)); + CONTRACT (CustomMarshalerInfo*) + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pAssembly)); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; + + EEMarshalingData *pMarshalingData = NULL; + + // The assembly is not shared so we use the current app domain's marshaling data. + pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + + // Retrieve the custom marshaler helper from the EE marshaling data. + RETURN pMarshalingData->GetCustomMarshalerInfo(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); } - CONTRACT_END; - EEMarshalingData *pMarshalingData = NULL; +#ifdef FEATURE_COMINTEROP + CustomMarshalerInfo *GetIEnumeratorCustomMarshalerInfo(Assembly *pAssembly) + { + CONTRACT (CustomMarshalerInfo*) + { + STANDARD_VM_CHECK; + PRECONDITION(CheckPointer(pAssembly)); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; - // The assembly is not shared so we use the current app domain's marshaling data. - pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + EEMarshalingData *pMarshalingData = NULL; - // Retrieve the custom marshaler helper from the EE marshaling data. - RETURN pMarshalingData->GetCustomMarshalerInfo(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); -} + // The assembly is not shared so we use the current app domain's marshaling data. + pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); + + // Retrieve the custom marshaler helper from the EE marshaling data. + RETURN pMarshalingData->GetIEnumeratorMarshalerInfo(); + } +#endif // FEATURE_COMINTEROP -namespace -{ //========================================================================== // Return: S_OK if there is valid data to compress // S_FALSE if at end of data block @@ -829,17 +841,6 @@ EEMarshalingData::~EEMarshalingData() { WRAPPER_NO_CONTRACT; - CustomMarshalerInfo *pCMInfo; - - // @TODO(DM): Remove the linked list of CMInfo's and instead hang the OBJECTHANDLE - // contained inside the CMInfo off the AppDomain directly. The AppDomain can have - // a list of tasks to do when it gets teared down and we could leverage that - // to release the object handles. - - // Walk through the linked list and delete all the custom marshaler info's. - while ((pCMInfo = m_pCMInfoList.RemoveHead()) != NULL) - delete pCMInfo; - #ifdef FEATURE_COMINTEROP if (m_pOleColorInfo) { @@ -954,11 +955,7 @@ CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembl m_CMInfoHashTable.InsertValue(&Key, pNewCMInfo); // If we create the CM info, then add it to the linked list. - if (pNewCMInfo) - { - m_pCMInfoList.InsertHead(pNewCMInfo); - pNewCMInfo.SuppressRelease(); - } + pNewCMInfo.SuppressRelease(); // Release the lock and return the custom marshaler info. } @@ -967,6 +964,34 @@ CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembl } #ifdef FEATURE_COMINTEROP +CustomMarshalerInfo *EEMarshalingData::GetIEnumeratorMarshalerInfo() +{ + CONTRACT (CustomMarshalerInfo*) + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + INJECT_FAULT(COMPlusThrowOM()); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; + + if (m_pIEnumeratorMarshalerInfo == NULL) + { + CustomMarshalerInfo *pMarshalerInfo = CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(m_pHeap, m_pAllocator); + + if (InterlockedCompareExchangeT(&m_pIEnumeratorMarshalerInfo, pMarshalerInfo, NULL) != NULL) + { + // Another thread beat us to it. Delete on CustomMarshalerInfo is an empty operation + // which is OK, since the possible leak is rare, small, and constant. This is the same + // pattern as in code:GetCustomMarshalerInfo. + delete pMarshalerInfo; + } + } + + RETURN m_pIEnumeratorMarshalerInfo; +} + OleColorMarshalingInfo *EEMarshalingData::GetOleColorMarshalingInfo() { CONTRACT (OleColorMarshalingInfo*) @@ -1883,11 +1908,7 @@ MarshalInfo::MarshalInfo(Module* pModule, { if (!fEmitsIL) { - m_pCMInfo = SetupCustomMarshalerInfo(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, - ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, - pAssembly, sigTH); + m_pCMInfo = GetIEnumeratorCustomMarshalerInfo(pAssembly); } else { @@ -4025,37 +4046,31 @@ extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdT if (!hndManagedType.IsTypeDesc() && IsTypeRefOrDef(g_CollectionsEnumeratorClassName, hndManagedType.GetModule(), hndManagedType.GetCl())) { - pCMInfo = SetupCustomMarshalerInfo(ENUMERATOR_TO_ENUM_VARIANT_CM_NAME, - ENUMERATOR_TO_ENUM_VARIANT_CM_NAME_LEN, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE, - ENUMERATOR_TO_ENUM_VARIANT_CM_COOKIE_LEN, - pAssembly, hndManagedType); + _ASSERTE(!"Setting the custom marshaler for IEnumerator should be done on the managed side."); } - else #endif // FEATURE_COMINTEROP - { - // - // Retrieve the native type for the current parameter. - // - BOOL result; - NativeTypeParamInfo ParamInfo; - result = ParseNativeTypeInfo(paramToken, pModule->GetMDImport(), &ParamInfo); + // + // Retrieve the native type for the current parameter. + // - // - // this should all have been done at stub creation time - // - CONSISTENCY_CHECK(result != 0); - CONSISTENCY_CHECK(ParamInfo.m_NativeType == NATIVE_TYPE_CUSTOMMARSHALER); + BOOL result; + NativeTypeParamInfo ParamInfo; + result = ParseNativeTypeInfo(paramToken, pModule->GetMDImport(), &ParamInfo); - // Set up the custom marshaler info. - pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, - ParamInfo.m_cCMMarshalerTypeNameBytes, - ParamInfo.m_strCMCookie, - ParamInfo.m_cCMCookieStrBytes, - pAssembly, - hndManagedType); - } + // + // this should all have been done at stub creation time + // + CONSISTENCY_CHECK(result != 0); + CONSISTENCY_CHECK(ParamInfo.m_NativeType == NATIVE_TYPE_CUSTOMMARSHALER); + + // Set up the custom marshaler info. + pCMInfo = SetupCustomMarshalerInfo(ParamInfo.m_strCMMarshalerTypeName, + ParamInfo.m_cCMMarshalerTypeNameBytes, + ParamInfo.m_strCMCookie, + ParamInfo.m_cCMCookieStrBytes, + pAssembly, + hndManagedType); retObject.Set(pCMInfo->GetCustomMarshaler()); diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 2e08afa382f431..339d72a97893e2 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -265,6 +265,7 @@ class EEMarshalingData CustomMarshalerInfo *GetCustomMarshalerInfo(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); #ifdef FEATURE_COMINTEROP + CustomMarshalerInfo *GetIEnumeratorMarshalerInfo(); // This method retrieves OLE_COLOR marshaling info. OleColorMarshalingInfo *GetOleColorMarshalingInfo(); #endif // FEATURE_COMINTEROP @@ -274,8 +275,8 @@ class EEMarshalingData EECMInfoHashTable m_CMInfoHashTable; LoaderAllocator* m_pAllocator; LoaderHeap* m_pHeap; - CMINFOLIST m_pCMInfoList; #ifdef FEATURE_COMINTEROP + CustomMarshalerInfo* m_pIEnumeratorMarshalerInfo; OleColorMarshalingInfo* m_pOleColorInfo; #endif // FEATURE_COMINTEROP CrstBase* m_lock; From 12c5607d51cee370709a18217067840d2356b44e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 20 Aug 2024 13:06:15 -0700 Subject: [PATCH 14/26] Move reflection lookup and handling for Color marshalling to managed code as much as possible. --- .../src/System/StubHelpers.cs | 34 ++++++ src/coreclr/vm/callhelpers.h | 1 - src/coreclr/vm/corelib.h | 5 + src/coreclr/vm/dispparammarshaler.cpp | 8 +- src/coreclr/vm/ilmarshalers.cpp | 18 +-- src/coreclr/vm/interoputil.cpp | 53 +++++--- src/coreclr/vm/interoputil.h | 4 +- src/coreclr/vm/metasig.h | 1 + src/coreclr/vm/mlinfo.cpp | 115 ++---------------- src/coreclr/vm/mlinfo.h | 49 ++------ src/coreclr/vm/stubgen.cpp | 5 + src/coreclr/vm/stubgen.h | 1 + 12 files changed, 108 insertions(+), 186 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index b148a7b7debf72..f0b55912c33686 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.CustomMarshalers; @@ -1631,4 +1632,37 @@ internal static unsafe void LayoutDestroyNativeInternal(object obj, byte* pNativ [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IntPtr NextCallReturnAddress(); } // class StubHelpers + +#if FEATURE_COMINTEROP + internal static class ColorMarshaler + { + private static readonly MethodInvoker OleColorToDrawingColorMethod; + private static readonly MethodInvoker DrawingColorToOleColorMethod; + + internal static readonly IntPtr ColorType; + +#pragma warning disable CA1810 // explicit static cctor + static ColorMarshaler() + { + Type colorTranslatorType = Type.GetType("System.Drawing.ColorTranslator, System.Drawing.Primitives", throwOnError: true)!; + Type colorType = Type.GetType("System.Drawing.Color, System.Drawing.Primitives", throwOnError: true)!; + + ColorType = colorType.TypeHandle.Value; + + OleColorToDrawingColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("FromOle", [typeof(int)])!); + DrawingColorToOleColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("ToOle", [colorType])!); + } +#pragma warning restore CA1810 // explicit static cctor + + internal static object ConvertToManaged(int managedColor) + { + return OleColorToDrawingColorMethod.Invoke(null, managedColor)!; + } + + internal static int ConvertToNative(object? managedColor) + { + return (int)DrawingColorToOleColorMethod.Invoke(null, managedColor)!; + } + } +#endif } diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index b39586d82c341f..0e7f16dc0210cb 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -473,7 +473,6 @@ class MethodDescCallSite MDCALLDEF_VOID( CallWithValueTypes, TRUE) MDCALLDEF_ARGSLOT( CallWithValueTypes, _RetArgSlot) MDCALLDEF_REFTYPE( CallWithValueTypes, TRUE, _RetOBJECTREF, Object*, OBJECTREF) - MDCALLDEF( CallWithValueTypes, TRUE, _RetOleColor, OLE_COLOR, OTHER_ELEMENT_TYPE) #undef OTHER_ELEMENT_TYPE #undef MDCALL_ARG_SIG_STD_RETTYPES #undef MDCALLDEF diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 52e36418447bb3..a944fb56eedf7c 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1005,6 +1005,11 @@ DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertCon DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_SPACE_TO_MANAGED, ConvertSpaceToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid) DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RefObj_IntPtr_RetVoid) + +DEFINE_CLASS(COLORMARSHALER, StubHelpers, ColorMarshaler) +DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Obj_RetInt) +DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Int_RetObj) +DEFINE_FIELD(COLORMARSHALER, COLOR_TYPE, ColorType) #endif // FEATURE_COMINTEROP END_ILLINK_FEATURE_SWITCH() diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index 0f6aabb48bbb82..2dce9db089c77e 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -97,13 +97,7 @@ void DispParamOleColorMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECT // Convert the OLECOLOR to a System.Drawing.Color. SYSTEMCOLOR MngColor; - ConvertOleColorToSystemColor(OleColor, &MngColor); - - // Box the System.Drawing.Color value class and give back the boxed object. - TypeHandle hndColorType = - AppDomain::GetCurrentDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); - - *pDestObj = hndColorType.GetMethodTable()->Box(&MngColor); + ConvertOleColorToSystemColor(OleColor, pDestObj); } void DispParamOleColorMarshaler::MarshalManagedToNative(OBJECTREF *pSrcObj, VARIANT *pDestVar) diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 0da47a32c279ac..b92f7e331241dd 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1477,25 +1477,18 @@ LocalDesc ILOleColorMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - TypeHandle hndColorType = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); - // // value class // - return LocalDesc(hndColorType); // System.Drawing.Color + return LocalDesc(m_pargs->color.m_pColorType); } void ILOleColorMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); - EmitLoadManagedValue(pslILEmit); - // int System.Drawing.ColorTranslator.ToOle(System.Drawing.Color c) - pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); + pslILEmit->EmitCALL(METHOD__COLORMARSHALER__CONVERT_TO_NATIVE, 1, 1); EmitStoreNativeValue(pslILEmit); } @@ -1503,12 +1496,9 @@ void ILOleColorMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit { STANDARD_VM_CONTRACT; - LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); - MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); - EmitLoadNativeValue(pslILEmit); - // System.Drawing.Color System.Drawing.ColorTranslator.FromOle(int oleColor) - pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); + pslILEmit->EmitCALL(METHOD__COLORMARSHALER__CONVERT_TO_MANAGED, 1, 1); + pslILEmit->EmitUNBOX_ANY(pslILEmit->GetToken(m_pargs->color.m_pColorType)); EmitStoreManagedValue(pslILEmit); } diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 957d13fe5024be..63ffc4cc410f2b 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -2199,21 +2199,34 @@ void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysCo } CONTRACTL_END; - // Retrieve the method desc to use for the current AD. - MethodDesc *pOleColorToSystemColorMD = - GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); + OBJECTREF boxedSysColor = NULL; - MethodDescCallSite oleColorToSystemColor(pOleColorToSystemColorMD); + GCPROTECT_BEGIN(boxedSysColor); - _ASSERTE(pOleColorToSystemColorMD->HasRetBuffArg()); + ConvertOleColorToSystemColor(SrcOleColor, &boxedSysColor); + + CopyValueClass(pDestSysColor, boxedSysColor->UnBox(), boxedSysColor->GetMethodTable()); + GCPROTECT_END(); +} + +void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, OBJECTREF *pDestSysColor) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + MethodDescCallSite oleColorToSystemColor(METHOD__COLORMARSHALER__CONVERT_TO_MANAGED); ARG_SLOT Args[] = { - PtrToArgSlot(pDestSysColor), - PtrToArgSlot(SrcOleColor) + PtrToArgSlot(&SrcOleColor) }; - oleColorToSystemColor.Call(Args); + *pDestSysColor = oleColorToSystemColor.Call_RetOBJECTREF(Args); } //-------------------------------------------------------------------------------- @@ -2228,14 +2241,24 @@ OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj) } CONTRACTL_END; - // Retrieve the method desc to use for the current AD. - MethodDesc *pSystemColorToOleColorMD = - GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); - MethodDescCallSite systemColorToOleColor(pSystemColorToOleColorMD); + OLE_COLOR result; + OBJECTREF sysColor = nullptr; + + GCPROTECT_BEGIN(sysColor); - // Set up the args and call the method. - SYSTEMCOLOR *pSrcSysColor = (SYSTEMCOLOR *)(*pSrcObj)->UnBox(); - return systemColorToOleColor.CallWithValueTypes_RetOleColor((const ARG_SLOT *)&pSrcSysColor); + sysColor = *pSrcObj; + + MethodDescCallSite sysColorToOleColor(METHOD__COLORMARSHALER__CONVERT_TO_NATIVE); + + ARG_SLOT Args[] = + { + ObjToArgSlot(sysColor) + }; + + result = (OLE_COLOR)sysColorToOleColor.Call_RetI4(Args); + + GCPROTECT_END(); + return result; } //-------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/interoputil.h b/src/coreclr/vm/interoputil.h index 3bc78c1e1ff0f6..608663e0c0281f 100644 --- a/src/coreclr/vm/interoputil.h +++ b/src/coreclr/vm/interoputil.h @@ -278,6 +278,7 @@ void GetComSourceInterfacesForClass(MethodTable *pClassMT, CQuickArrayIsStatic() && "The translator method to convert an OLE_COLOR to a System.Drawing.Color must be static!"); - - // Retrieve the method to convert a System.Drawing.Color to an OLE_COLOR. - m_SystemColorToOleColorMD = MemberLoader::FindMethodByName(hndColorTranslatorType.GetMethodTable(), SYSTEMCOLOR_TO_OLECOLOR_METH_NAME); - _ASSERTE(m_SystemColorToOleColorMD && "Unable to find the translator method to convert a System.Drawing.Color to an OLE_COLOR!"); - _ASSERTE(m_SystemColorToOleColorMD->IsStatic() && "The translator method to convert a System.Drawing.Color to an OLE_COLOR must be static!"); -} - - -void *OleColorMarshalingInfo::operator new(size_t size, LoaderHeap *pHeap) -{ - CONTRACT (void*) - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pHeap)); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - void* mem = pHeap->AllocMem(S_SIZE_T(size)); - - RETURN mem; -} - - -void OleColorMarshalingInfo::operator delete(void *pMem) -{ - LIMITED_METHOD_CONTRACT; - // Instances of this class are always allocated on the loader heap so - // the delete operator has nothing to do. -} - -#endif // FEATURE_COMINTEROP - EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) : m_pAllocator(pAllocator), m_pHeap(pAllocator->GetLowFrequencyHeap()), @@ -842,10 +769,10 @@ EEMarshalingData::~EEMarshalingData() WRAPPER_NO_CONTRACT; #ifdef FEATURE_COMINTEROP - if (m_pOleColorInfo) + if (m_pIEnumeratorMarshalerInfo) { - delete m_pOleColorInfo; - m_pOleColorInfo = NULL; + delete m_pIEnumeratorMarshalerInfo; + m_pIEnumeratorMarshalerInfo = NULL; } #endif } @@ -991,34 +918,6 @@ CustomMarshalerInfo *EEMarshalingData::GetIEnumeratorMarshalerInfo() RETURN m_pIEnumeratorMarshalerInfo; } - -OleColorMarshalingInfo *EEMarshalingData::GetOleColorMarshalingInfo() -{ - CONTRACT (OleColorMarshalingInfo*) - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END; - - if (m_pOleColorInfo == NULL) - { - OleColorMarshalingInfo *pOleColorInfo = new (m_pHeap) OleColorMarshalingInfo(); - - if (InterlockedCompareExchangeT(&m_pOleColorInfo, pOleColorInfo, NULL) != NULL) - { - // Another thread beat us to it. Delete on OleColorMarshalingInfo is an empty operation - // which is OK, since the possible leak is rare, small, and constant. This is the same - // pattern as in code:GetCustomMarshalerInfo. - delete pOleColorInfo; - } - } - - RETURN m_pOleColorInfo; -} #endif // FEATURE_COMINTEROP bool IsValidForGenericMarshalling(MethodTable* pMT, bool isFieldScenario, bool builtInMarshallingEnabled) @@ -2247,6 +2146,14 @@ MarshalInfo::MarshalInfo(Module* pModule, IfFailGoto(E_FAIL, lFail); } + GCX_COOP(); + + FieldDesc* pColorTypeField = CoreLibBinder::GetField(FIELD__COLORMARSHALER__COLOR_TYPE); + pColorTypeField->CheckRunClassInitThrowing(); + void* colorTypeHandle = pColorTypeField->GetStaticValuePtr(); + + m_args.color.m_pColorType = TypeHandle::FromPtr(colorTypeHandle).GetMethodTable(); + m_type = MARSHAL_TYPE_OLECOLOR; } #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/vm/mlinfo.h b/src/coreclr/vm/mlinfo.h index 339d72a97893e2..b248b99a1434b8 100644 --- a/src/coreclr/vm/mlinfo.h +++ b/src/coreclr/vm/mlinfo.h @@ -103,6 +103,13 @@ struct OverrideProcArgs { UINT32 fixedStringLength; } fs; + +#ifdef FEATURE_COMINTEROP + struct + { + MethodTable* m_pColorType; + } color; +#endif }; }; @@ -190,45 +197,6 @@ BOOL ParseNativeTypeInfo(mdToken token, BOOL IsFixedBuffer(mdFieldDef field, IMDInternalImport* pInternalImport); #endif -#ifdef FEATURE_COMINTEROP -class OleColorMarshalingInfo -{ -public: - // Constructor. - OleColorMarshalingInfo(); - - // OleColorMarshalingInfo's are always allocated on the loader heap so we need to redefine - // the new and delete operators to ensure this. - void *operator new(size_t size, LoaderHeap *pHeap); - void operator delete(void *pMem); - - // Accessors. - TypeHandle GetColorType() - { - LIMITED_METHOD_CONTRACT; - return m_hndColorType; - } - MethodDesc *GetOleColorToSystemColorMD() - { - LIMITED_METHOD_CONTRACT; - return m_OleColorToSystemColorMD; - } - MethodDesc *GetSystemColorToOleColorMD() - { - LIMITED_METHOD_CONTRACT; - return m_SystemColorToOleColorMD; - } - - -private: - TypeHandle m_hndColorType; - MethodDesc* m_OleColorToSystemColorMD; - MethodDesc* m_SystemColorToOleColorMD; -}; - -#endif // FEATURE_COMINTEROP - - class EEMarshalingData { public: @@ -266,8 +234,6 @@ class EEMarshalingData #ifdef FEATURE_COMINTEROP CustomMarshalerInfo *GetIEnumeratorMarshalerInfo(); - // This method retrieves OLE_COLOR marshaling info. - OleColorMarshalingInfo *GetOleColorMarshalingInfo(); #endif // FEATURE_COMINTEROP private: @@ -277,7 +243,6 @@ class EEMarshalingData LoaderHeap* m_pHeap; #ifdef FEATURE_COMINTEROP CustomMarshalerInfo* m_pIEnumeratorMarshalerInfo; - OleColorMarshalingInfo* m_pOleColorInfo; #endif // FEATURE_COMINTEROP CrstBase* m_lock; }; diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index 283b6d3fa2d883..cdffc49c2f50e6 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -1812,6 +1812,11 @@ void ILCodeStream::EmitUNALIGNED(BYTE alignment) Emit(CEE_UNALIGNED, 0, alignment); } +void ILCodeStream::EmitUNBOX_ANY(int token) +{ + WRAPPER_NO_CONTRACT; + Emit(CEE_UNBOX_ANY, 0, token); +} void ILCodeStream::EmitNEWOBJ(BinderMethodID id, int numInArgs) { diff --git a/src/coreclr/vm/stubgen.h b/src/coreclr/vm/stubgen.h index 968e5f9b48291f..48cfbd366db1c7 100644 --- a/src/coreclr/vm/stubgen.h +++ b/src/coreclr/vm/stubgen.h @@ -932,6 +932,7 @@ class ILCodeStream void EmitSUB (); void EmitTHROW (); void EmitUNALIGNED (BYTE alignment); + void EmitUNBOX_ANY (int token); // Overloads to simplify common usage patterns void EmitNEWOBJ (BinderMethodID id, int numInArgs); From 539f0eb8e98aba383d9fd0f9ac823b04adbccefe Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 20 Aug 2024 15:34:03 -0700 Subject: [PATCH 15/26] Fix tests --- src/coreclr/vm/corelib.h | 1 - src/coreclr/vm/ilmarshalers.cpp | 1 + src/coreclr/vm/metasig.h | 1 - src/coreclr/vm/stubgen.cpp | 5 +++++ src/coreclr/vm/stubgen.h | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index a944fb56eedf7c..0aa3cbce1a7b47 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1044,7 +1044,6 @@ DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_NATIVE, ConvertCon DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_NATIVE, ClearNative, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, CLEAR_MANAGED, ClearManaged, SM_ICustomMarshaler_RefObj_PtrIntPtr_RetVoid) -DEFINE_METHOD(MNGD_REF_CUSTOM_MARSHALER, GET_MARSHALER, GetMarshaler, SM_IntPtr_RetICustomMarshaler) DEFINE_CLASS(ASANY_MARSHALER, StubHelpers, AsAnyMarshaler) DEFINE_METHOD(ASANY_MARSHALER, CTOR, .ctor, IM_IntPtr_RetVoid) diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index b92f7e331241dd..315b18b921ea3a 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -1488,6 +1488,7 @@ void ILOleColorMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit STANDARD_VM_CONTRACT; EmitLoadManagedValue(pslILEmit); + pslILEmit->EmitBOX(pslILEmit->GetToken(m_pargs->color.m_pColorType)); pslILEmit->EmitCALL(METHOD__COLORMARSHALER__CONVERT_TO_NATIVE, 1, 1); EmitStoreNativeValue(pslILEmit); } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index e9d30189d8b768..24649c3b557969 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -254,7 +254,6 @@ DEFINE_METASIG(SM(Obj_Int_RetVoid, j i,v)) DEFINE_METASIG(SM(PtrVoid_Obj_RetObj, P(v) j, j)) DEFINE_METASIG(SM(PtrVoid_Obj_RetRefByte, P(v) j, r(b))) DEFINE_METASIG_T(SM(ICustomMarshaler_RefObj_PtrIntPtr_RetVoid, C(ICUSTOM_MARSHALER) r(j) P(I), v)) -DEFINE_METASIG_T(SM(IntPtr_RetICustomMarshaler, I, C(ICUSTOM_MARSHALER))) DEFINE_METASIG(SM(RefDbl_Dbl_RetDbl, r(d) d, d)) DEFINE_METASIG(SM(RefDbl_Dbl_Dbl_RetDbl, r(d) d d, d)) diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index cdffc49c2f50e6..c7d8c39673b581 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -1177,6 +1177,11 @@ void ILCodeStream::EmitBNE_UN(ILCodeLabel* pCodeLabel) WRAPPER_NO_CONTRACT; Emit(CEE_BNE_UN, -2, (UINT_PTR)pCodeLabel); } +void ILCodeStream::EmitBOX(int token) +{ + WRAPPER_NO_CONTRACT; + Emit(CEE_BOX, 0, token); +} void ILCodeStream::EmitBR(ILCodeLabel* pCodeLabel) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/vm/stubgen.h b/src/coreclr/vm/stubgen.h index 48cfbd366db1c7..41df675def9299 100644 --- a/src/coreclr/vm/stubgen.h +++ b/src/coreclr/vm/stubgen.h @@ -841,6 +841,7 @@ class ILCodeStream void EmitBLE_UN (ILCodeLabel* pCodeLabel); void EmitBLT (ILCodeLabel* pCodeLabel); void EmitBNE_UN (ILCodeLabel* pCodeLabel); + void EmitBOX (int token); void EmitBR (ILCodeLabel* pCodeLabel); void EmitBREAK (); void EmitBRFALSE (ILCodeLabel* pCodeLabel); From 1ec3beff2844032e8f6609acf50007212fd6eb24 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 20 Aug 2024 15:48:09 -0700 Subject: [PATCH 16/26] Fix contract --- src/coreclr/vm/custommarshalerinfo.cpp | 3 ++- src/coreclr/vm/mlinfo.cpp | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 2324e2d7292f84..784fb0168a6f21 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -176,7 +176,7 @@ CustomMarshalerInfo* CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(LoaderH { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_ANY; PRECONDITION(CheckPointer(pHeap)); PRECONDITION(CheckPointer(pLoaderAllocator)); } @@ -185,6 +185,7 @@ CustomMarshalerInfo* CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(LoaderH CustomMarshalerInfo* pInfo = nullptr; OBJECTREF IEnumeratorMarshalerObj = nullptr; + GCX_COOP(); GCPROTECT_BEGIN(IEnumeratorMarshalerObj); MethodDescCallSite getMarshaler(METHOD__STUBHELPERS__GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER); diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 83dc3a5aa4fdac..9c4a5bf51ef939 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -394,7 +394,9 @@ namespace { CONTRACT (CustomMarshalerInfo*) { - STANDARD_VM_CHECK; + THROWS; + GC_TRIGGERS; + MODE_ANY; PRECONDITION(CheckPointer(pAssembly)); POSTCONDITION(CheckPointer(RETVAL)); } From 4a33197607231c6ea2d7a9400e509020f1e8d05e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 20 Aug 2024 16:27:53 -0700 Subject: [PATCH 17/26] Fix non-Windows build --- .../System.Private.CoreLib/src/System/StubHelpers.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index f0b55912c33686..73016ec84988d6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -5,7 +5,9 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#if FEATURE_COMINTEROP using System.Runtime.InteropServices.CustomMarshalers; +#endif using System.Runtime.InteropServices.Marshalling; using System.Runtime.Versioning; using System.Text; @@ -1459,16 +1461,20 @@ internal static void SetPendingExceptionObject(Exception? exception) [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_CreateCustomMarshaler")] internal static partial void CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType, ObjectHandleOnStack customMarshaler); +#if FEATURE_COMINTEROP [SupportedOSPlatform("windows")] internal static object GetIEnumeratorToEnumVariantMarshaler() => EnumeratorToEnumVariantMarshaler.GetInstance(string.Empty); +#endif internal static object CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType) { +#if FEATURE_COMINTEROP if (hndManagedType == typeof(System.Collections.IEnumerator).TypeHandle.Value && OperatingSystem.IsWindows()) { return GetIEnumeratorToEnumVariantMarshaler(); } +#endif object? retVal = null; CreateCustomMarshaler(pMD, paramToken, hndManagedType, ObjectHandleOnStack.Create(ref retVal)); From 7e9f7dbccce35682da1dbd85575a5d01e2273313 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 20 Aug 2024 16:59:43 -0700 Subject: [PATCH 18/26] Remove unused variable --- src/coreclr/vm/dispparammarshaler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/dispparammarshaler.cpp b/src/coreclr/vm/dispparammarshaler.cpp index 2dce9db089c77e..6c495472526201 100644 --- a/src/coreclr/vm/dispparammarshaler.cpp +++ b/src/coreclr/vm/dispparammarshaler.cpp @@ -96,7 +96,6 @@ void DispParamOleColorMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECT OLE_COLOR OleColor = bByref ? *V_UI4REF(pSrcVar) : V_UI4(pSrcVar); // Convert the OLECOLOR to a System.Drawing.Color. - SYSTEMCOLOR MngColor; ConvertOleColorToSystemColor(OleColor, pDestObj); } From 1530b3010f92bdee90457b4b7d2bdf489333d33e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 21 Aug 2024 12:13:54 -0700 Subject: [PATCH 19/26] Fix GC mode for getting the custom marshaler object --- src/coreclr/vm/mlinfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 9c4a5bf51ef939..a5a59daf7562bc 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -3981,7 +3981,10 @@ extern "C" void QCALLTYPE StubHelpers_CreateCustomMarshaler(MethodDesc* pMD, mdT pAssembly, hndManagedType); - retObject.Set(pCMInfo->GetCustomMarshaler()); + { + GCX_COOP(); + retObject.Set(pCMInfo->GetCustomMarshaler()); + } END_QCALL; } From 4e4253d35ea98587aad159744dfc66d49c5a58e1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 23 Aug 2024 13:30:22 -0700 Subject: [PATCH 20/26] PR feedback --- src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs | 4 ++-- src/coreclr/vm/interoputil.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 73016ec84988d6..1f3f37833ef039 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1469,8 +1469,8 @@ internal static void SetPendingExceptionObject(Exception? exception) internal static object CreateCustomMarshaler(IntPtr pMD, int paramToken, IntPtr hndManagedType) { #if FEATURE_COMINTEROP - if (hndManagedType == typeof(System.Collections.IEnumerator).TypeHandle.Value - && OperatingSystem.IsWindows()) + if (OperatingSystem.IsWindows() + && hndManagedType == typeof(System.Collections.IEnumerator).TypeHandle.Value) { return GetIEnumeratorToEnumVariantMarshaler(); } diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 63ffc4cc410f2b..98901e45b46d70 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -2242,7 +2242,7 @@ OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj) CONTRACTL_END; OLE_COLOR result; - OBJECTREF sysColor = nullptr; + OBJECTREF sysColor = NULL; GCPROTECT_BEGIN(sysColor); From 1e238ba4fd44d35292e881ec6cbf0e1929d7ebfc Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 23 Aug 2024 13:46:19 -0700 Subject: [PATCH 21/26] Remove unmanaged definition of System.Drawing.Color from the runtime and remove a box->unbox->box operation sequence --- .../classlibnative/bcltype/variant.cpp | 9 +++++--- src/coreclr/vm/interoputil.cpp | 22 +------------------ src/coreclr/vm/interoputil.h | 19 +--------------- 3 files changed, 8 insertions(+), 42 deletions(-) diff --git a/src/coreclr/classlibnative/bcltype/variant.cpp b/src/coreclr/classlibnative/bcltype/variant.cpp index 1a3cf7e75bb441..df9cbec0b38307 100644 --- a/src/coreclr/classlibnative/bcltype/variant.cpp +++ b/src/coreclr/classlibnative/bcltype/variant.cpp @@ -310,11 +310,14 @@ extern "C" void QCALLTYPE Variant_ConvertOleColorToSystemColor(QCall::ObjectHand BEGIN_QCALL; + OBJECTREF obj = NULL; GCX_COOP(); - SYSTEMCOLOR systemColor{}; - ConvertOleColorToSystemColor(oleColor, &systemColor); - objRet.Set(pMT->Box(&systemColor)); + GCPROTECT_BEGIN(obj); + ConvertOleColorToSystemColor(oleColor, &obj); + objRet.Set(obj); + + GCPROTECT_END(); END_QCALL; } diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index 98901e45b46d70..15f9e5b1ececb2 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -2188,27 +2188,7 @@ void GetComSourceInterfacesForClass(MethodTable *pMT, CQuickArray } //-------------------------------------------------------------------------------- -// This method converts an OLE_COLOR to a System.Color. -void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysColor) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - OBJECTREF boxedSysColor = NULL; - - GCPROTECT_BEGIN(boxedSysColor); - - ConvertOleColorToSystemColor(SrcOleColor, &boxedSysColor); - - CopyValueClass(pDestSysColor, boxedSysColor->UnBox(), boxedSysColor->GetMethodTable()); - GCPROTECT_END(); -} - +// This method converts an OLE_COLOR to a boxed Color object. void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, OBJECTREF *pDestSysColor) { CONTRACTL diff --git a/src/coreclr/vm/interoputil.h b/src/coreclr/vm/interoputil.h index 608663e0c0281f..5062e527100421 100644 --- a/src/coreclr/vm/interoputil.h +++ b/src/coreclr/vm/interoputil.h @@ -35,21 +35,6 @@ enum DefaultInterfaceType DefaultInterfaceType_BaseComClass = 4 }; -// System.Drawing.Color struct definition. - -struct SYSTEMCOLOR -{ -#ifdef HOST_64BIT - STRINGREF name; - INT64 value; -#else - INT64 value; - STRINGREF name; -#endif - short knownColor; - short state; -}; - struct ComMethodTable; struct IUnkEntry; interface IStream; @@ -276,10 +261,8 @@ MethodTable *GetDefaultInterfaceMTForClass(MethodTable *pMT, BOOL *pbDispatch); void GetComSourceInterfacesForClass(MethodTable *pClassMT, CQuickArray &rItfList); //-------------------------------------------------------------------------------- -// These methods convert an OLE_COLOR to a System.Color and vice versa. -void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysColor); +// These methods convert an OLE_COLOR to a boxed Color object and vice versa. void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, OBJECTREF *pDestSysColor); -OLE_COLOR ConvertSystemColorToOleColor(SYSTEMCOLOR *pSrcSysColor); OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj); //-------------------------------------------------------------------------------- From fceb168012f1754fd30886e7e426fcc109c31882 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 23 Aug 2024 16:57:28 -0700 Subject: [PATCH 22/26] Remove the QCall and just call ColorMarshaler directly. --- .../src/Microsoft/Win32/OAVariantLib.cs | 4 +-- .../src/System/Variant.cs | 7 ---- .../classlibnative/bcltype/variant.cpp | 35 ------------------- src/coreclr/classlibnative/bcltype/variant.h | 3 -- src/coreclr/vm/qcallentrypoints.cpp | 2 -- 5 files changed, 2 insertions(+), 49 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs b/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs index a51ec6f0132e47..2b3cbab5fabb35 100644 --- a/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs +++ b/src/coreclr/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs @@ -20,6 +20,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using System.StubHelpers; namespace Microsoft.Win32 { @@ -73,8 +74,7 @@ internal static unsafe partial class OAVariantLib if (source is int || source is uint) { uint sourceData = source is int ? (uint)(int)source : (uint)source; - // Int32/UInt32 can be converted to System.Drawing.Color - Variant.ConvertOleColorToSystemColor(ObjectHandleOnStack.Create(ref result), sourceData, targetClass.TypeHandle.Value); + result = ColorMarshaler.ConvertToManaged((int)sourceData); Debug.Assert(result != null); return result; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs index 1ee6acc5be1c47..cba514d4b11efd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs @@ -71,13 +71,6 @@ internal partial struct Variant internal static Variant DBNull => new Variant(CV_NULL, System.DBNull.Value, 0); internal static bool IsSystemDrawingColor(Type type) => type.FullName == "System.Drawing.Color"; // Matches the behavior of IsTypeRefOrDef - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertSystemColorToOleColor")] - internal static partial uint ConvertSystemColorToOleColor(ObjectHandleOnStack obj); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertOleColorToSystemColor")] - internal static partial void ConvertOleColorToSystemColor(ObjectHandleOnStack objret, uint value, IntPtr pMT); - // // Native Methods // diff --git a/src/coreclr/classlibnative/bcltype/variant.cpp b/src/coreclr/classlibnative/bcltype/variant.cpp index df9cbec0b38307..7064170e18457c 100644 --- a/src/coreclr/classlibnative/bcltype/variant.cpp +++ b/src/coreclr/classlibnative/bcltype/variant.cpp @@ -286,39 +286,4 @@ int COMVariant::GetEnumFlags(TypeHandle th) return 0; } } - -extern "C" uint32_t QCALLTYPE Variant_ConvertSystemColorToOleColor(QCall::ObjectHandleOnStack obj) -{ - QCALL_CONTRACT; - - uint32_t ret = 0; - - BEGIN_QCALL; - - GCX_COOP(); - OBJECTREF srcObj = obj.Get(); - ret = ConvertSystemColorToOleColor(&srcObj); - - END_QCALL; - - return ret; -} - -extern "C" void QCALLTYPE Variant_ConvertOleColorToSystemColor(QCall::ObjectHandleOnStack objRet, uint32_t oleColor, MethodTable* pMT) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - OBJECTREF obj = NULL; - GCX_COOP(); - GCPROTECT_BEGIN(obj); - - ConvertOleColorToSystemColor(oleColor, &obj); - objRet.Set(obj); - - GCPROTECT_END(); - END_QCALL; -} - #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/classlibnative/bcltype/variant.h b/src/coreclr/classlibnative/bcltype/variant.h index 12c5a3d36d53dd..aae0a5f9741ac6 100644 --- a/src/coreclr/classlibnative/bcltype/variant.h +++ b/src/coreclr/classlibnative/bcltype/variant.h @@ -40,8 +40,5 @@ class COMVariant static int GetEnumFlags(TypeHandle th); }; -extern "C" uint32_t QCALLTYPE Variant_ConvertSystemColorToOleColor(QCall::ObjectHandleOnStack obj); -extern "C" void QCALLTYPE Variant_ConvertOleColorToSystemColor(QCall::ObjectHandleOnStack objRet, uint32_t oleColor, MethodTable* pMT); - #endif // _VARIANT_H_ diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 7a7e6d0f977989..725bea79c29b55 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -324,8 +324,6 @@ static const Entry s_QCall[] = DllImportEntry(MngdSafeArrayMarshaler_ConvertSpaceToManaged) DllImportEntry(MngdSafeArrayMarshaler_ConvertContentsToManaged) DllImportEntry(MngdSafeArrayMarshaler_ClearNative) - DllImportEntry(Variant_ConvertSystemColorToOleColor) - DllImportEntry(Variant_ConvertOleColorToSystemColor) #endif // FEATURE_COMINTEROP DllImportEntry(NativeLibrary_LoadFromPath) DllImportEntry(NativeLibrary_LoadByName) From cb71d7eb4d8693944686f5f0848885518e21f99f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 28 Aug 2024 15:14:26 -0700 Subject: [PATCH 23/26] PR feedback --- src/coreclr/pal/inc/rt/palrt.h | 2 -- src/coreclr/vm/custommarshalerinfo.cpp | 2 +- src/coreclr/vm/ilmarshalers.h | 2 +- src/coreclr/vm/mlinfo.cpp | 12 +++--------- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/coreclr/pal/inc/rt/palrt.h b/src/coreclr/pal/inc/rt/palrt.h index 18e25222c5db8e..13bbc7d250c321 100644 --- a/src/coreclr/pal/inc/rt/palrt.h +++ b/src/coreclr/pal/inc/rt/palrt.h @@ -716,8 +716,6 @@ typename std::remove_reference::type&& move( T&& t ); #define __RPC__inout #define __RPC__deref_out_ecount_full_opt(x) -typedef DWORD OLE_COLOR; - typedef HANDLE HWND; typedef struct _LIST_ENTRY { diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 784fb0168a6f21..5dd62cc9f583db 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -47,7 +47,7 @@ namespace { pMD = MethodDesc::FindOrCreateAssociatedMethodDesc( pMD, - hndCustomMarshalerType.GetMethodTable(), + pMT, FALSE, // forceBoxedEntryPoint Instantiation(), // methodInst FALSE, // allowInstParam diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index ca84692561b038..7f5dad6bb2276d 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -2533,7 +2533,7 @@ class ILOleColorMarshaler : public ILMarshaler enum { c_fInOnly = TRUE, - c_nativeSize = sizeof(OLE_COLOR), + c_nativeSize = sizeof(uint32_t), }; protected: diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 1efa55eb01bfc1..6785ad0999a4fd 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -59,9 +59,7 @@ namespace { CONTRACT (CustomMarshalerInfo*) { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pAssembly)); POSTCONDITION(CheckPointer(RETVAL)); } @@ -493,9 +491,7 @@ CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(Assembly *pAssembl { CONTRACT (CustomMarshalerInfo*) { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; INJECT_FAULT(COMPlusThrowOM()); PRECONDITION(CheckPointer(pAssembly)); POSTCONDITION(CheckPointer(RETVAL)); @@ -562,9 +558,7 @@ CustomMarshalerInfo *EEMarshalingData::GetIEnumeratorMarshalerInfo() { CONTRACT (CustomMarshalerInfo*) { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; INJECT_FAULT(COMPlusThrowOM()); POSTCONDITION(CheckPointer(RETVAL)); } From 75eecc20f35e4f08c97f863c86d5e84bd417368f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 28 Aug 2024 15:19:53 -0700 Subject: [PATCH 24/26] Fix naming --- .../src/System/StubHelpers.cs | 16 ++++++++-------- src/coreclr/vm/corelib.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index f3d40038f0163a..33d9c6ef28765b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1594,10 +1594,10 @@ internal static void ValidateObject(object obj, IntPtr pMD) #if FEATURE_COMINTEROP internal static class ColorMarshaler { - private static readonly MethodInvoker OleColorToDrawingColorMethod; - private static readonly MethodInvoker DrawingColorToOleColorMethod; + private static readonly MethodInvoker s_oleColorToDrawingColorMethod; + private static readonly MethodInvoker s_drawingColorToOleColorMethod; - internal static readonly IntPtr ColorType; + internal static readonly IntPtr s_colorType; #pragma warning disable CA1810 // explicit static cctor static ColorMarshaler() @@ -1605,21 +1605,21 @@ static ColorMarshaler() Type colorTranslatorType = Type.GetType("System.Drawing.ColorTranslator, System.Drawing.Primitives", throwOnError: true)!; Type colorType = Type.GetType("System.Drawing.Color, System.Drawing.Primitives", throwOnError: true)!; - ColorType = colorType.TypeHandle.Value; + s_colorType = colorType.TypeHandle.Value; - OleColorToDrawingColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("FromOle", [typeof(int)])!); - DrawingColorToOleColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("ToOle", [colorType])!); + s_oleColorToDrawingColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("FromOle", [typeof(int)])!); + s_drawingColorToOleColorMethod = MethodInvoker.Create(colorTranslatorType.GetMethod("ToOle", [colorType])!); } #pragma warning restore CA1810 // explicit static cctor internal static object ConvertToManaged(int managedColor) { - return OleColorToDrawingColorMethod.Invoke(null, managedColor)!; + return s_oleColorToDrawingColorMethod.Invoke(null, managedColor)!; } internal static int ConvertToNative(object? managedColor) { - return (int)DrawingColorToOleColorMethod.Invoke(null, managedColor)!; + return (int)s_drawingColorToOleColorMethod.Invoke(null, managedColor)!; } } #endif diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 6428f8a0c0386e..e50b50cd14d470 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1003,7 +1003,7 @@ DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNativ DEFINE_CLASS(COLORMARSHALER, StubHelpers, ColorMarshaler) DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Obj_RetInt) DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Int_RetObj) -DEFINE_FIELD(COLORMARSHALER, COLOR_TYPE, ColorType) +DEFINE_FIELD(COLORMARSHALER, COLOR_TYPE, s_colorType) #endif // FEATURE_COMINTEROP END_ILLINK_FEATURE_SWITCH() From 740ccb2560dcdd8d872b0195dc1f96d658acb124 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 28 Aug 2024 15:24:13 -0700 Subject: [PATCH 25/26] Update contract --- src/coreclr/vm/custommarshalerinfo.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/vm/custommarshalerinfo.cpp b/src/coreclr/vm/custommarshalerinfo.cpp index 5dd62cc9f583db..c505be13232019 100644 --- a/src/coreclr/vm/custommarshalerinfo.cpp +++ b/src/coreclr/vm/custommarshalerinfo.cpp @@ -174,9 +174,7 @@ CustomMarshalerInfo* CustomMarshalerInfo::CreateIEnumeratorMarshalerInfo(LoaderH { CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; + STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pHeap)); PRECONDITION(CheckPointer(pLoaderAllocator)); } From 8a2bcd4a95788e56dcf22634f523466c39016071 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 28 Aug 2024 15:31:27 -0700 Subject: [PATCH 26/26] Fix type for ComVariant.Create call and remove unused qcall --- src/coreclr/System.Private.CoreLib/src/System/Variant.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs index e6c325c327a71d..3e8d4f662046cd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Variant.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Variant.cs @@ -18,9 +18,6 @@ internal static partial class Variant { internal static bool IsSystemDrawingColor(Type type) => type.FullName == "System.Drawing.Color"; // Matches the behavior of IsTypeRefOrDef - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertSystemColorToOleColor")] - internal static partial uint ConvertSystemColorToOleColor(ObjectHandleOnStack obj); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Variant_ConvertValueTypeToRecord")] private static partial void ConvertValueTypeToRecord(ObjectHandleOnStack obj, out ComVariant pOle); @@ -161,7 +158,7 @@ internal static void MarshalHelperConvertObjectToVariant(object? o, out ComVaria case { } when IsSystemDrawingColor(o.GetType()): // System.Drawing.Color is converted to UInt32 - pOle = ComVariant.Create(ColorMarshaler.ConvertToNative(o)); + pOle = ComVariant.Create((uint)ColorMarshaler.ConvertToNative(o)); break; // DateTime, decimal handled by IConvertible case