summaryrefslogtreecommitdiff
path: root/packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch')
-rw-r--r--packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch158
1 files changed, 158 insertions, 0 deletions
diff --git a/packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch b/packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch
new file mode 100644
index 0000000000..8ee6d76e31
--- /dev/null
+++ b/packaging/0002-UMEntryThunk-store-freed-thunks-into-FIFO-free-list.patch
@@ -0,0 +1,158 @@
+From 51ffa6ba338dded7be2a0147a8e477d28b35b159 Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+Date: Fri, 12 Jan 2018 18:55:10 +0300
+Subject: [PATCH 02/47] UMEntryThunk: store freed thunks into FIFO free list
+
+Use free list to delay reusing deleted thunks. It improves
+collected delegate calls diagnostic.
+---
+ src/vm/dllimportcallback.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++--
+ src/vm/dllimportcallback.h | 10 ++++-
+ 2 files changed, 91 insertions(+), 6 deletions(-)
+
+diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp
+index c3e6a4e..fe03f47 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)
+diff --git a/src/vm/dllimportcallback.h b/src/vm/dllimportcallback.h
+index 5838e49..d820a76 100644
+--- a/src/vm/dllimportcallback.h
++++ b/src/vm/dllimportcallback.h
+@@ -250,6 +250,7 @@ class UMEntryThunk
+ {
+ friend class CheckAsmOffsets;
+ friend class NDirectStubLinker;
++ friend class UMEntryThunkFreeList;
+
+ private:
+ #ifdef _DEBUG
+@@ -526,8 +527,13 @@ private:
+ // Field is NULL for a static method.
+ OBJECTHANDLE m_pObjectHandle;
+
+- // Pointer to the shared structure containing everything else
+- PTR_UMThunkMarshInfo m_pUMThunkMarshInfo;
++ union
++ {
++ // Pointer to the shared structure containing everything else
++ PTR_UMThunkMarshInfo m_pUMThunkMarshInfo;
++ // Pointer to the next UMEntryThunk in the free list. Used when it is freed.
++ UMEntryThunk *m_pNextFreeThunk;
++ };
+
+ ADID m_dwDomainId; // appdomain of module (cached for fast access)
+ #ifdef _DEBUG
+--
+2.7.4
+