diff options
author | Luqun Lou <luqunl@microsoft.com> | 2017-10-06 19:53:00 +0300 |
---|---|---|
committer | Luqun Lou <luqunl@microsoft.com> | 2017-10-06 19:53:00 +0300 |
commit | ad066ef1adabbffffb7af5af2d86b8c5174cf1d9 (patch) | |
tree | de0eaf01c7e08cde9345d02c74683b13bebedc99 /src/System.Private.TypeLoader | |
parent | 9c9f3f7990e21055ad07b4790ea1476383430032 (diff) |
Remove Thunk created during DynamicCCW
The change is to free these thunks created by DynamicCCW through CallInterceptor.
Changes:
1. ComCallableObject.cs:
a. Use m_dynamicMethodStart and m_dynamicMethodEnd to record methods [dynamicMethodStart , dynamicMethodEnd) are dynamically created.
b. Free these thunks during interface CCW destroy
2. CallInterceptor.cs
a. Add a static FreeThunk method to free thunks created by CCW.
The use pattern for CCW dynamic thunk is that it only save thunk address instead of CallInterceptor instance. it is hard to call CallInterceptor instance's FreeThunk()
3. InteropCallInterceptors:
Remove TODO, since it isn't okay to clear these two field after native call this delegate once.
In native side, it may call this WinRT delegate couple times. if we clear these two fields after one call, the next call will fail.
[tfs-changeset: 1677503]
Diffstat (limited to 'src/System.Private.TypeLoader')
-rw-r--r-- | src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallInterceptor.cs | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallInterceptor.cs b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallInterceptor.cs index 2b9e1cbae..b999f53d3 100644 --- a/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallInterceptor.cs +++ b/src/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallInterceptor.cs @@ -1279,28 +1279,41 @@ namespace Internal.Runtime.CallInterceptor /// </summary> public void FreeThunk() { - if (_thunkAddress != IntPtr.Zero) + FreeThunk(_thunkAddress); + _thunkAddress = IntPtr.Zero; + _id = 0; + } + + /// <summary> + /// Free the specified thunk. Once this is called, the old thunk address is invalid. + /// </summary> + /// <param name="thunkAddress"></param> + public static void FreeThunk(IntPtr thunkAddress) + { + if (thunkAddress != IntPtr.Zero) { lock (s_callInterceptors) { - if (_thunkAddress != IntPtr.Zero) + if (thunkAddress != IntPtr.Zero) { - RuntimeAugments.FreeThunk(s_thunkPoolHeap, _thunkAddress); + IntPtr context; + if (RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, thunkAddress, out context, out _)) + { + int id = context.ToInt32(); + s_callInterceptors[id] = null; + if (s_countFreeCallInterceptorId == s_freeCallInterceptorIds.Count) + { + s_freeCallInterceptorIds.Add(id); + } + else + { + s_freeCallInterceptorIds[s_countFreeCallInterceptorId] = id; + } - _thunkAddress = IntPtr.Zero; + s_countFreeCallInterceptorId++; - s_callInterceptors[_id] = null; - if (s_countFreeCallInterceptorId == s_freeCallInterceptorIds.Count) - { - s_freeCallInterceptorIds.Add(_id); + RuntimeAugments.FreeThunk(s_thunkPoolHeap, thunkAddress); } - else - { - s_freeCallInterceptorIds[s_countFreeCallInterceptorId] = _id; - } - - s_countFreeCallInterceptorId++; - _id = 0; } } } |