diff options
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.patch | 158 |
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 + |