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.Interop | |
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.Interop')
-rw-r--r-- | src/System.Private.Interop/src/Shared/ComCallableObject.cs | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/src/System.Private.Interop/src/Shared/ComCallableObject.cs b/src/System.Private.Interop/src/Shared/ComCallableObject.cs index 7f5ef41d8..e6b7bcda8 100644 --- a/src/System.Private.Interop/src/Shared/ComCallableObject.cs +++ b/src/System.Private.Interop/src/Shared/ComCallableObject.cs @@ -91,6 +91,11 @@ namespace System.Runtime.InteropServices RuntimeTypeHandle m_interfaceType; // Refer to interface RuntimeTypeHandle // TODO: Define unqiue vtable for shared CCW instances, store McgInterfaceData pointer at negative offset +#if !CORECLR && ENABLE_WINRT + // for dynamic created stub, remove/delete stub during __interface_ccw destroy + int m_dynamicMethodStart; + int m_dynamicMethodEnd; // [m_dynamicMethodStart, m_dynamicMethodEnd) +#endif /// <summary> /// Cache for single memory block, perfect for calls like IDependencyProperty.SetValue (System.Object converts to CCW, passed to native code, then released). /// Last block not freed at shut-down. Consider more complicated caching when there are evidence for it @@ -107,11 +112,19 @@ namespace System.Runtime.InteropServices IntPtr vt = typeHandle.GetCcwVtable(); #if !CORECLR && ENABLE_WINRT + int dynamicMethodStart = 0; + int dynamicMethodEnd = 0; + if (vt == default(IntPtr) && McgModuleManager.UseDynamicInterop) { // TODO Design an interface, such as IMcgCCWData and each McgModule implements this interface // Dynamic has its own mcg module - vt = DynamicInteropHelpers.GetCCWVTable_NoThrow(managedCCW.TargetObject, typeHandle); + + vt = DynamicInteropHelpers.GetCCWVTable_NoThrow( + managedCCW.TargetObject, + typeHandle, + out dynamicMethodStart, + out dynamicMethodEnd); } #endif if (vt == default(IntPtr)) @@ -130,7 +143,10 @@ namespace System.Runtime.InteropServices pCcw->m_pVtable = vt.ToPointer(); pCcw->m_pNativeCCW = managedCCW.NativeCCW; pCcw->m_interfaceType = typeHandle; - +#if !CORECLR && ENABLE_WINRT + pCcw->m_dynamicMethodStart = dynamicMethodStart; + pCcw->m_dynamicMethodEnd = dynamicMethodEnd; +#endif managedCCW.NativeCCW->Link(pCcw); return pCcw; @@ -138,6 +154,14 @@ namespace System.Runtime.InteropServices internal static void Destroy(__interface_ccw* pInterfaceCCW) { +#if !CORECLR && ENABLE_WINRT + // Remove these dynamic thunk [m_dynamicMethodStart, m_dynamicMethodEnd) + for (int i = pInterfaceCCW->m_dynamicMethodStart; i < pInterfaceCCW->m_dynamicMethodEnd; i++) + { + System.IntPtr thunkAddress = ((System.IntPtr*)pInterfaceCCW->m_pVtable)[i]; + InteropCallInterceptor.FreeThunk(thunkAddress); + } +#endif McgComHelpers.CachedFree(pInterfaceCCW, ref s_cached_interface_ccw); } |