summaryrefslogtreecommitdiff
path: root/src/vm/dllimportcallback.cpp
diff options
context:
space:
mode:
authorKonstantin Baladurin <k.baladurin@partner.samsung.com>2018-01-12 18:55:10 +0300
committerJan Kotas <jkotas@microsoft.com>2018-01-12 12:40:37 -0800
commitb0a10f69a85404bcc9c377c80dc2950f927f8731 (patch)
tree524d83fc1f7dd6b6379414764a6b8619e583cb46 /src/vm/dllimportcallback.cpp
parent28839fc0b2dcaf89b7217741291c8c3f578f38a0 (diff)
downloadcoreclr-b0a10f69a85404bcc9c377c80dc2950f927f8731.tar.gz
coreclr-b0a10f69a85404bcc9c377c80dc2950f927f8731.tar.bz2
coreclr-b0a10f69a85404bcc9c377c80dc2950f927f8731.zip
UMEntryThunk: store freed thunks into FIFO free list
Use free list to delay reusing deleted thunks. It improves collected delegate calls diagnostic.
Diffstat (limited to 'src/vm/dllimportcallback.cpp')
-rw-r--r--src/vm/dllimportcallback.cpp87
1 files changed, 83 insertions, 4 deletions
diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp
index c3e6a4e62d..fe03f47388 100644
--- a/src/vm/dllimportcallback.cpp
+++ b/src/vm/dllimportcallback.cpp
@@ -33,6 +33,79 @@ struct UM2MThunk_Args
int argLen;
};
+class UMEntryThunkFreeList
+{
+public:
+ UMEntryThunkFreeList(size_t threshold) :
+ m_threshold(threshold),
+ m_count(0),
+ m_pHead(NULL),
+ m_pTail(NULL)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ m_crst.Init(CrstLeafLock, CRST_UNSAFE_ANYMODE);
+ }
+
+ UMEntryThunk *GetUMEntryThunk()
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (m_count < m_threshold)
+ return NULL;
+
+ CrstHolder ch(&m_crst);
+
+ UMEntryThunk *pThunk = m_pHead;
+
+ if (pThunk == NULL)
+ return NULL;
+
+ m_pHead = m_pHead->m_pNextFreeThunk;
+ --m_count;
+
+ return pThunk;
+ }
+
+ void AddToList(UMEntryThunk *pThunk)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ }
+ CONTRACTL_END;
+
+ CrstHolder ch(&m_crst);
+
+ if (m_pHead == NULL)
+ {
+ m_pHead = pThunk;
+ m_pTail = pThunk;
+ }
+ else
+ {
+ m_pTail->m_pNextFreeThunk = pThunk;
+ m_pTail = pThunk;
+ }
+
+ pThunk->m_pNextFreeThunk = NULL;
+
+ ++m_count;
+ }
+
+private:
+ // Used to delay reusing freed thunks
+ size_t m_threshold;
+ size_t m_count;
+ UMEntryThunk *m_pHead;
+ UMEntryThunk *m_pTail;
+ CrstStatic m_crst;
+};
+
+#define DEFAULT_THUNK_FREE_LIST_THRESHOLD 64
+
+static UMEntryThunkFreeList s_thunkFreeList(DEFAULT_THUNK_FREE_LIST_THRESHOLD);
+
EXTERN_C void STDCALL UM2MThunk_WrapperHelper(void *pThunkArgs,
int argLen,
void *pAddr,
@@ -1111,20 +1184,26 @@ UMEntryThunk* UMEntryThunk::CreateUMEntryThunk()
UMEntryThunk * p;
- // On the phone, use loader heap to save memory commit of regular executable heap
- p = (UMEntryThunk *)(void *)SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->AllocMem(S_SIZE_T(sizeof(UMEntryThunk)));
+ p = s_thunkFreeList.GetUMEntryThunk();
+
+ if (p == NULL)
+ p = (UMEntryThunk *)(void *)SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->AllocMem(S_SIZE_T(sizeof(UMEntryThunk)));
RETURN p;
}
void UMEntryThunk::Terminate()
{
- WRAPPER_NO_CONTRACT;
+ CONTRACTL
+ {
+ NOTHROW;
+ }
+ CONTRACTL_END;
_ASSERTE(!SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->IsZeroInit());
m_code.Poison();
- SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->BackoutMem(this, sizeof(UMEntryThunk));
+ s_thunkFreeList.AddToList(this);
}
VOID UMEntryThunk::FreeUMEntryThunk(UMEntryThunk* p)