@@ -33,6 +33,79 @@ struct UM2MThunk_Args
33
33
int argLen;
34
34
};
35
35
36
+ class UMEntryThunkFreeList
37
+ {
38
+ public:
39
+ UMEntryThunkFreeList (size_t threshold) :
40
+ m_threshold (threshold),
41
+ m_count (0 ),
42
+ m_pHead (NULL ),
43
+ m_pTail (NULL )
44
+ {
45
+ WRAPPER_NO_CONTRACT;
46
+
47
+ m_crst.Init (CrstLeafLock, CRST_UNSAFE_ANYMODE);
48
+ }
49
+
50
+ UMEntryThunk *GetUMEntryThunk ()
51
+ {
52
+ WRAPPER_NO_CONTRACT;
53
+
54
+ if (m_count < m_threshold)
55
+ return NULL ;
56
+
57
+ CrstHolder ch (&m_crst);
58
+
59
+ UMEntryThunk *pThunk = m_pHead;
60
+
61
+ if (pThunk == NULL )
62
+ return NULL ;
63
+
64
+ m_pHead = m_pHead->m_pNextFreeThunk ;
65
+ --m_count;
66
+
67
+ return pThunk;
68
+ }
69
+
70
+ void AddToList (UMEntryThunk *pThunk)
71
+ {
72
+ CONTRACTL
73
+ {
74
+ NOTHROW;
75
+ }
76
+ CONTRACTL_END;
77
+
78
+ CrstHolder ch (&m_crst);
79
+
80
+ if (m_pHead == NULL )
81
+ {
82
+ m_pHead = pThunk;
83
+ m_pTail = pThunk;
84
+ }
85
+ else
86
+ {
87
+ m_pTail->m_pNextFreeThunk = pThunk;
88
+ m_pTail = pThunk;
89
+ }
90
+
91
+ pThunk->m_pNextFreeThunk = NULL ;
92
+
93
+ ++m_count;
94
+ }
95
+
96
+ private:
97
+ // Used to delay reusing freed thunks
98
+ size_t m_threshold;
99
+ size_t m_count;
100
+ UMEntryThunk *m_pHead;
101
+ UMEntryThunk *m_pTail;
102
+ CrstStatic m_crst;
103
+ };
104
+
105
+ #define DEFAULT_THUNK_FREE_LIST_THRESHOLD 64
106
+
107
+ static UMEntryThunkFreeList s_thunkFreeList (DEFAULT_THUNK_FREE_LIST_THRESHOLD);
108
+
36
109
EXTERN_C void STDCALL UM2MThunk_WrapperHelper (void *pThunkArgs,
37
110
int argLen,
38
111
void *pAddr,
@@ -1111,20 +1184,26 @@ UMEntryThunk* UMEntryThunk::CreateUMEntryThunk()
1111
1184
1112
1185
UMEntryThunk * p;
1113
1186
1114
- // On the phone, use loader heap to save memory commit of regular executable heap
1115
- p = (UMEntryThunk *)(void *)SystemDomain::GetGlobalLoaderAllocator ()->GetExecutableHeap ()->AllocMem (S_SIZE_T (sizeof (UMEntryThunk)));
1187
+ p = s_thunkFreeList.GetUMEntryThunk ();
1188
+
1189
+ if (p == NULL )
1190
+ p = (UMEntryThunk *)(void *)SystemDomain::GetGlobalLoaderAllocator ()->GetExecutableHeap ()->AllocMem (S_SIZE_T (sizeof (UMEntryThunk)));
1116
1191
1117
1192
RETURN p;
1118
1193
}
1119
1194
1120
1195
void UMEntryThunk::Terminate ()
1121
1196
{
1122
- WRAPPER_NO_CONTRACT;
1197
+ CONTRACTL
1198
+ {
1199
+ NOTHROW;
1200
+ }
1201
+ CONTRACTL_END;
1123
1202
1124
1203
_ASSERTE (!SystemDomain::GetGlobalLoaderAllocator ()->GetExecutableHeap ()->IsZeroInit ());
1125
1204
m_code.Poison ();
1126
1205
1127
- SystemDomain::GetGlobalLoaderAllocator ()-> GetExecutableHeap ()-> BackoutMem ( this , sizeof (UMEntryThunk) );
1206
+ s_thunkFreeList. AddToList ( this );
1128
1207
}
1129
1208
1130
1209
VOID UMEntryThunk::FreeUMEntryThunk (UMEntryThunk* p)
0 commit comments