Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuqun Lou <luqunl@microsoft.com>2017-10-06 19:53:00 +0300
committerLuqun Lou <luqunl@microsoft.com>2017-10-06 19:53:00 +0300
commitad066ef1adabbffffb7af5af2d86b8c5174cf1d9 (patch)
treede0eaf01c7e08cde9345d02c74683b13bebedc99 /src/System.Private.Interop
parent9c9f3f7990e21055ad07b4790ea1476383430032 (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.cs28
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);
}