Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5282,6 +5282,14 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT)
}
CONTRACT_END;

LoaderAllocator* pLoaderAllocator = pMT->GetLoaderAllocator();

EEMarshalingData* pMarshallingData = pLoaderAllocator->GetMarshalingData();

MethodDesc* pCachedStubMD = pMarshallingData->LookupStructILStub(pMT);
if (pCachedStubMD != NULL)
RETURN pCachedStubMD;

DWORD dwStubFlags = NDIRECTSTUB_FL_STRUCT_MARSHAL;

BOOL bestFit, throwOnUnmappableChar;
Expand Down Expand Up @@ -5340,7 +5348,7 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT)
sigBuilder.NewArg(&cleanupWorkList);

DWORD cbMetaSigSize = sigBuilder.GetSigSize();
AllocMemHolder<BYTE> szMetaSig(pMT->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(cbMetaSigSize)));
AllocMemHolder<BYTE> szMetaSig(pLoaderAllocator->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(cbMetaSigSize)));
sigBuilder.GetSig(szMetaSig, cbMetaSigSize);

StubSigDesc sigDesc(pMT, Signature(szMetaSig, cbMetaSigSize), pMT->GetModule());
Expand Down Expand Up @@ -5373,6 +5381,11 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT)
szMetaSig.SuppressRelease();
}

// The CreateInteropILStub() handles only creating a single stub.
// The stub returned will be okay to return even if the call below loses
// the race to insert into the cache.
pMarshallingData->CacheStructILStub(pMT, pStubMD);

RETURN pStubMD;
}

Expand Down Expand Up @@ -5784,17 +5797,7 @@ void MarshalStructViaILStub(MethodDesc* pStubMD, void* pManagedData, void* pNati
}
CONTRACTL_END;

ARG_SLOT args[] =
{
PtrToArgSlot(pManagedData),
PtrToArgSlot(pNativeData),
(ARG_SLOT)operation,
PtrToArgSlot(ppCleanupWorkList)
};

MethodDescCallSite callSite(pStubMD);

callSite.Call(args);
MarshalStructViaILStubCode(pStubMD->GetSingleCallableAddrOfCode(), pManagedData, pNativeData, operation, ppCleanupWorkList);
}

void MarshalStructViaILStubCode(PCODE pStubCode, void* pManagedData, void* pNativeData, StructMarshalStubs::MarshalOperation operation, void** ppCleanupWorkList /* = nullptr */)
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/loaderallocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,12 @@ class LoaderAllocator
// basis.
EEMarshalingData *GetMarshalingData();

EEMarshalingData* GetMarshalingDataIfAvailable()
{
LIMITED_METHOD_CONTRACT;
return m_pMarshalingData;
}

private:
// Deletes marshaling data at shutdown (which contains cached factories that needs to be released)
void DeleteMarshalingData();
Expand Down
15 changes: 11 additions & 4 deletions src/coreclr/vm/marshalnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,10 @@ FCIMPL3(VOID, MarshalNative::StructureToPtr, Object* pObjUNSAFE, LPVOID ptr, CLR
}
else if (pMT->HasLayout())
{
MethodDesc* structMarshalStub;
EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;

if (structMarshalStub == NULL)
{
GCX_PREEMP();
structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
Expand Down Expand Up @@ -178,8 +180,10 @@ FCIMPL3(VOID, MarshalNative::PtrToStructureHelper, LPVOID ptr, Object* pObjIn, C
}
else if (pMT->HasLayout())
{
MethodDesc* structMarshalStub;
EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;

if (structMarshalStub == NULL)
{
GCX_PREEMP();
structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
Expand Down Expand Up @@ -227,11 +231,14 @@ FCIMPL2(VOID, MarshalNative::DestroyStructure, LPVOID ptr, ReflectClassBaseObjec
}
else if (th.HasLayout())
{
MethodDesc* structMarshalStub;
MethodTable* pMT = th.GetMethodTable();
EEMarshalingData* pEEMarshalingData = pMT->GetLoaderAllocator()->GetMarshalingDataIfAvailable();
MethodDesc* structMarshalStub = (pEEMarshalingData != NULL) ? pEEMarshalingData->LookupStructILStubSpeculative(pMT) : NULL;

if (structMarshalStub == NULL)
{
GCX_PREEMP();
structMarshalStub = NDirect::CreateStructMarshalILStub(th.GetMethodTable());
structMarshalStub = NDirect::CreateStructMarshalILStub(pMT);
}

MarshalStructViaILStub(structMarshalStub, nullptr, ptr, StructMarshalStubs::MarshalOperation::Cleanup);
Expand Down
19 changes: 19 additions & 0 deletions src/coreclr/vm/mlinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@



#define INITIAL_NUM_STRUCT_ILSTUB_HASHTABLE_BUCKETS 32
#define INITIAL_NUM_CMHELPER_HASHTABLE_BUCKETS 32
#define INITIAL_NUM_CMINFO_HASHTABLE_BUCKETS 32
#define DEBUG_CONTEXT_STR_LEN 2000
Expand Down Expand Up @@ -822,6 +823,7 @@ EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst)
CONTRACTL_END;

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);
}
Expand Down Expand Up @@ -879,6 +881,23 @@ void EEMarshalingData::operator delete(void *pMem)
}


void EEMarshalingData::CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD)
{
STANDARD_VM_CONTRACT;

CrstHolder lock(m_lock);

// Verify that the stub has not already been added by another thread.
HashDatum res = 0;
if (m_structILStubCache.GetValue(pMT, &res))
{
return;
}

m_structILStubCache.InsertValue(pMT, pStubMD);
}


CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes)
{
CONTRACT (CustomMarshalerHelper*)
Expand Down
23 changes: 21 additions & 2 deletions src/coreclr/vm/mlinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,26 @@ class EEMarshalingData
void *operator new(size_t size, LoaderHeap *pHeap);
void operator delete(void *pMem);

#ifndef DACCESS_COMPILE
MethodDesc* LookupStructILStubSpeculative(MethodTable* pMT)
{
WRAPPER_NO_CONTRACT;
HashDatum res = 0;
m_structILStubCache.GetValueSpeculative(pMT, &res);
return (MethodDesc*)res;
}

MethodDesc* LookupStructILStub(MethodTable* pMT)
{
WRAPPER_NO_CONTRACT;
HashDatum res = 0;
m_structILStubCache.GetValue(pMT, &res);
return (MethodDesc*)res;
}

void CacheStructILStub(MethodTable* pMT, MethodDesc* pStubMD);
#endif

// This method returns the custom marshaling helper 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);
Expand All @@ -250,11 +270,10 @@ class EEMarshalingData
#ifdef FEATURE_COMINTEROP
// This method retrieves OLE_COLOR marshaling info.
OleColorMarshalingInfo *GetOleColorMarshalingInfo();


#endif // FEATURE_COMINTEROP

private:
EEPtrHashTable m_structILStubCache;
EECMHelperHashTable m_CMHelperHashtable;
EEPtrHashTable m_SharedCMHelperToCMInfoMap;
LoaderAllocator* m_pAllocator;
Expand Down