From a7dc093918e358fbef74c58a0279475a8909d9fe Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 19 Dec 2018 15:02:23 -0800 Subject: [PATCH 01/17] Create repro for dotnet/coreclr#19654 --- tests/src/Interop/CMakeLists.txt | 1 + .../MultipleALCs/CMakeLists.txt | 11 +++++ .../MultipleALCs/CustomLoadContext.cs | 48 +++++++++++++++++++ .../MultipleALCs/CustomMarshaler.cs | 44 +++++++++++++++++ .../MultipleALCs/CustomMarshalerInALC.csproj | 28 +++++++++++ .../CustomMarshalersALCNative.cpp | 12 +++++ .../MultipleALCs/MultipleALCs.csproj | 36 ++++++++++++++ .../ICustomMarshaler/MultipleALCs/RunInALC.cs | 31 ++++++++++++ .../{ => Primitives}/ICustomMarshaler.cs | 0 .../{ => Primitives}/ICustomMarshaler.csproj | 4 +- 10 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj create mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs rename tests/src/Interop/ICustomMarshaler/{ => Primitives}/ICustomMarshaler.cs (100%) rename tests/src/Interop/ICustomMarshaler/{ => Primitives}/ICustomMarshaler.csproj (94%) diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index 5685e79762c6..7a833a442924 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -61,6 +61,7 @@ add_subdirectory(DllImportAttribute/ExeFile) add_subdirectory(DllImportAttribute/FileNameContainDot) add_subdirectory(DllImportAttribute/Simple) add_subdirectory(ExecInDefAppDom) +add_subdirectory(ICustomMarshaler/MultipleALCs) if(WIN32) add_subdirectory(PInvoke/Attributes/LCID) diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt new file mode 100644 index 000000000000..f1ddedb6f6f6 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required (VERSION 2.6) +project (CustomMarshalersALCNative) +include_directories(${INC_PLATFORM_DIR}) +set(SOURCES CustomMarshalersALCNative.cpp ) + +# add the executable +add_library (CustomMarshalersALCNative SHARED ${SOURCES}) +target_link_libraries(CustomMarshalersALCNative ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS CustomMarshalersALCNative DESTINATION bin) diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs new file mode 100644 index 000000000000..3a4948f50342 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; + +class CustomLoadContext : AssemblyLoadContext +{ + private string unmanagedDirectory; + + internal CustomLoadContext(string unmanagedDirectory) + { + this.unmanagedDirectory = unmanagedDirectory; + } + + protected override Assembly Load(AssemblyName assemblyName) + { + string assemblyPath = Path.Combine(".", assemblyName.Name) + ".dll"; + if (File.Exists(assemblyPath)) + { + return LoadFromAssemblyPath(assemblyPath); + } + + return Default.LoadFromAssemblyName(assemblyName); + } + + protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) + { + string unmanagedDllPath = Directory.EnumerateFiles( + unmanagedDirectory, + $"{unmanagedDllName}.*").Concat( + Directory.EnumerateFiles( + unmanagedDirectory, + $"lib{unmanagedDllName}.*")) + .FirstOrDefault(); + + if (unmanagedDllPath != null) + { + return this.LoadUnmanagedDllFromPath(unmanagedDllPath); + } + + return base.LoadUnmanagedDll(unmanagedDllName); + } +} diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs new file mode 100644 index 000000000000..4a3fab3faff3 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; + +public class WrappedString +{ + public WrappedString(string str) + { + _str = str; + } + + internal string _str; +} + +public class WrappedStringCustomMarshaler : ICustomMarshaler +{ + private static readonly WrappedStringCustomMarshaler instance = new WrappedStringCustomMarshaler(); + + public void CleanUpManagedData(object ManagedObj) { } + public void CleanUpNativeData(IntPtr pNativeData) { Marshal.ZeroFreeCoTaskMemAnsi(pNativeData); } + + public int GetNativeDataSize() => IntPtr.Size; + + public IntPtr MarshalManagedToNative(object ManagedObj) => Marshal.StringToCoTaskMemAnsi(((WrappedString)ManagedObj)._str); + public object MarshalNativeToManaged(IntPtr pNativeData) => new WrappedString(Marshal.PtrToStringAnsi(pNativeData)); + + public static ICustomMarshaler GetInstance(string cookie) => instance; +} + +public class CustomMarshalerTest +{ + [DllImport("CustomMarshalersALCNative", CharSet = CharSet.Ansi)] + public static extern int NativeParseInt([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WrappedStringCustomMarshaler))] WrappedString str); + + public int ParseInt(string str) + { + return NativeParseInt(new WrappedString(str)); + } +} diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj new file mode 100644 index 000000000000..e04f27f049e4 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj @@ -0,0 +1,28 @@ + + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + library + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + False + + + + + + + + + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp new file mode 100644 index 000000000000..11aee8008abc --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include +#include + + +extern "C" int DLL_EXPORT STDMETHODCALLTYPE NativeParseInt(LPCSTR str) +{ + return atoi(str); +} diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj b/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj new file mode 100644 index 000000000000..02f96d79d74b --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj @@ -0,0 +1,36 @@ + + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs new file mode 100644 index 000000000000..587d10fdb60c --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using TestLibrary; + +public class RunInALC +{ + public static int Main(string[] args) + { + Run(); + Run(); + return 100; + } + + static void Run() + { + string currentAssemblyDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); + var context = new CustomLoadContext(currentAssemblyDirectory); + Assembly inContextAssembly = context.LoadFromAssemblyPath(Path.Combine(currentAssemblyDirectory, "CustomMarshalerInALC.dll")); + Type inContextType = inContextAssembly.GetType("CustomMarshalerTest"); + object instance = Activator.CreateInstance(inContextType); + MethodInfo parseIntMethod = inContextType.GetMethod("ParseInt", BindingFlags.Instance | BindingFlags.Public); + Assert.AreEqual(1234, (int)parseIntMethod.Invoke(instance, new object[]{"1234"})); + } +} diff --git a/tests/src/Interop/ICustomMarshaler/ICustomMarshaler.cs b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs similarity index 100% rename from tests/src/Interop/ICustomMarshaler/ICustomMarshaler.cs rename to tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.cs diff --git a/tests/src/Interop/ICustomMarshaler/ICustomMarshaler.csproj b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj similarity index 94% rename from tests/src/Interop/ICustomMarshaler/ICustomMarshaler.csproj rename to tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj index ae3ef0e4cff0..497213fc4731 100644 --- a/tests/src/Interop/ICustomMarshaler/ICustomMarshaler.csproj +++ b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj @@ -24,10 +24,10 @@ - - + + From d17832f988f85bd25207e71c5ca9bbacf04b3c44 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 19 Dec 2018 20:04:21 -0800 Subject: [PATCH 02/17] Update ICustomMarshaler.csproj --- .../ICustomMarshaler/Primitives/ICustomMarshaler.csproj | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj index 497213fc4731..654be1c04444 100644 --- a/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj +++ b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj @@ -21,13 +21,10 @@ - + + - - - - From d1a3044c0e27c44a9132bb78f5a91ba76501af28 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 19 Dec 2018 20:04:52 -0800 Subject: [PATCH 03/17] Update ICustomMarshaler.csproj --- .../Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj index 654be1c04444..0e68e23a9c93 100644 --- a/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj +++ b/tests/src/Interop/ICustomMarshaler/Primitives/ICustomMarshaler.csproj @@ -22,7 +22,7 @@ - + From 130f9be0811c4e8150f78ed143ff255b6ace5a98 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 20 Dec 2018 11:28:49 -0800 Subject: [PATCH 04/17] Clean up repro per feedback. --- .../MultipleALCs/CustomLoadContext.cs | 48 ------------------- .../MultipleALCs/CustomMarshaler.cs | 4 +- .../MultipleALCs/MultipleALCs.csproj | 1 - .../ICustomMarshaler/MultipleALCs/RunInALC.cs | 10 +++- 4 files changed, 10 insertions(+), 53 deletions(-) delete mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs deleted file mode 100644 index 3a4948f50342..000000000000 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomLoadContext.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Loader; - -class CustomLoadContext : AssemblyLoadContext -{ - private string unmanagedDirectory; - - internal CustomLoadContext(string unmanagedDirectory) - { - this.unmanagedDirectory = unmanagedDirectory; - } - - protected override Assembly Load(AssemblyName assemblyName) - { - string assemblyPath = Path.Combine(".", assemblyName.Name) + ".dll"; - if (File.Exists(assemblyPath)) - { - return LoadFromAssemblyPath(assemblyPath); - } - - return Default.LoadFromAssemblyName(assemblyName); - } - - protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) - { - string unmanagedDllPath = Directory.EnumerateFiles( - unmanagedDirectory, - $"{unmanagedDllName}.*").Concat( - Directory.EnumerateFiles( - unmanagedDirectory, - $"lib{unmanagedDllName}.*")) - .FirstOrDefault(); - - if (unmanagedDllPath != null) - { - return this.LoadUnmanagedDllFromPath(unmanagedDllPath); - } - - return base.LoadUnmanagedDll(unmanagedDllName); - } -} diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs index 4a3fab3faff3..8ec8ff980539 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs @@ -19,8 +19,6 @@ public WrappedString(string str) public class WrappedStringCustomMarshaler : ICustomMarshaler { - private static readonly WrappedStringCustomMarshaler instance = new WrappedStringCustomMarshaler(); - public void CleanUpManagedData(object ManagedObj) { } public void CleanUpNativeData(IntPtr pNativeData) { Marshal.ZeroFreeCoTaskMemAnsi(pNativeData); } @@ -29,7 +27,7 @@ public void CleanUpManagedData(object ManagedObj) { } public IntPtr MarshalManagedToNative(object ManagedObj) => Marshal.StringToCoTaskMemAnsi(((WrappedString)ManagedObj)._str); public object MarshalNativeToManaged(IntPtr pNativeData) => new WrappedString(Marshal.PtrToStringAnsi(pNativeData)); - public static ICustomMarshaler GetInstance(string cookie) => instance; + public static ICustomMarshaler GetInstance(string cookie) => new WrappedStringCustomMarshaler(); } public class CustomMarshalerTest diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj b/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj index 02f96d79d74b..abc186f67c85 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj @@ -25,7 +25,6 @@ - diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs b/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs index 587d10fdb60c..0d156d33e3c3 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs +++ b/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs @@ -21,7 +21,7 @@ public static int Main(string[] args) static void Run() { string currentAssemblyDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); - var context = new CustomLoadContext(currentAssemblyDirectory); + var context = new CustomLoadContext(); Assembly inContextAssembly = context.LoadFromAssemblyPath(Path.Combine(currentAssemblyDirectory, "CustomMarshalerInALC.dll")); Type inContextType = inContextAssembly.GetType("CustomMarshalerTest"); object instance = Activator.CreateInstance(inContextType); @@ -29,3 +29,11 @@ static void Run() Assert.AreEqual(1234, (int)parseIntMethod.Invoke(instance, new object[]{"1234"})); } } + +class CustomLoadContext : AssemblyLoadContext +{ + protected override Assembly Load(AssemblyName assemblyName) + { + return null; + } +} From 8207f1d41786f17cae385ff14fbb85d330af148d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 20 Dec 2018 14:57:23 -0800 Subject: [PATCH 05/17] Add test case for different assemblies with the same CustomMarshaler name. --- tests/src/Interop/CMakeLists.txt | 2 +- .../ConflictingNames/CMakeLists.txt | 11 ++++++ .../CustomMarshaler.cs | 24 ++++++++----- .../CustomMarshaler.csproj} | 0 .../ConflictingNames/CustomMarshaler2.csproj | 29 +++++++++++++++ .../CustomMarshalerNative.cpp} | 0 .../MultipleALCs.csproj | 2 +- .../RunInALC.cs | 2 +- .../SameNameDifferentAssembly.cs | 20 +++++++++++ .../SameNameDifferentAssembly.csproj | 35 +++++++++++++++++++ .../MultipleALCs/CMakeLists.txt | 11 ------ 11 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 tests/src/Interop/ICustomMarshaler/ConflictingNames/CMakeLists.txt rename tests/src/Interop/ICustomMarshaler/{MultipleALCs => ConflictingNames}/CustomMarshaler.cs (64%) rename tests/src/Interop/ICustomMarshaler/{MultipleALCs/CustomMarshalerInALC.csproj => ConflictingNames/CustomMarshaler.csproj} (100%) create mode 100644 tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler2.csproj rename tests/src/Interop/ICustomMarshaler/{MultipleALCs/CustomMarshalersALCNative.cpp => ConflictingNames/CustomMarshalerNative.cpp} (100%) rename tests/src/Interop/ICustomMarshaler/{MultipleALCs => ConflictingNames}/MultipleALCs.csproj (96%) rename tests/src/Interop/ICustomMarshaler/{MultipleALCs => ConflictingNames}/RunInALC.cs (97%) create mode 100644 tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs create mode 100644 tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.csproj delete mode 100644 tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index 7a833a442924..c2dad47becff 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -61,7 +61,7 @@ add_subdirectory(DllImportAttribute/ExeFile) add_subdirectory(DllImportAttribute/FileNameContainDot) add_subdirectory(DllImportAttribute/Simple) add_subdirectory(ExecInDefAppDom) -add_subdirectory(ICustomMarshaler/MultipleALCs) +add_subdirectory(ICustomMarshaler/ConflictingNames) if(WIN32) add_subdirectory(PInvoke/Attributes/LCID) diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/CMakeLists.txt b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CMakeLists.txt new file mode 100644 index 000000000000..b1743b761ba0 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required (VERSION 2.6) +project (CustomMarshalersConflictingNames) +include_directories(${INC_PLATFORM_DIR}) +set(SOURCES CustomMarshalerNative.cpp ) + +# add the executable +add_library (CustomMarshalerNative SHARED ${SOURCES}) +target_link_libraries(CustomMarshalerNative ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS CustomMarshalerNative DESTINATION bin) diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs similarity index 64% rename from tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs rename to tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs index 8ec8ff980539..8122a0378bf4 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshaler.cs +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Runtime.InteropServices; -public class WrappedString +class WrappedString { public WrappedString(string str) { @@ -17,7 +17,7 @@ public WrappedString(string str) internal string _str; } -public class WrappedStringCustomMarshaler : ICustomMarshaler +class WrappedStringCustomMarshaler : ICustomMarshaler { public void CleanUpManagedData(object ManagedObj) { } public void CleanUpNativeData(IntPtr pNativeData) { Marshal.ZeroFreeCoTaskMemAnsi(pNativeData); } @@ -30,13 +30,21 @@ public void CleanUpManagedData(object ManagedObj) { } public static ICustomMarshaler GetInstance(string cookie) => new WrappedStringCustomMarshaler(); } -public class CustomMarshalerTest +#if CUSTOMMARSHALERS2 +namespace CustomMarshalers2 +#else +namespace CustomMarshalers +#endif { - [DllImport("CustomMarshalersALCNative", CharSet = CharSet.Ansi)] - public static extern int NativeParseInt([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WrappedStringCustomMarshaler))] WrappedString str); - - public int ParseInt(string str) + public class CustomMarshalerTest { - return NativeParseInt(new WrappedString(str)); + [DllImport("CustomMarshalerNative", CharSet = CharSet.Ansi)] + private static extern int NativeParseInt([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(WrappedStringCustomMarshaler))] WrappedString str); + + public int ParseInt(string str) + { + return NativeParseInt(new WrappedString(str)); + } } } + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.csproj similarity index 100% rename from tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalerInALC.csproj rename to tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.csproj diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler2.csproj b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler2.csproj new file mode 100644 index 000000000000..38c0cbacd276 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler2.csproj @@ -0,0 +1,29 @@ + + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + library + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + $(DefineConstants);CUSTOMMARSHALERS2 + + + + + + + False + + + + + + + + + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshalerNative.cpp similarity index 100% rename from tests/src/Interop/ICustomMarshaler/MultipleALCs/CustomMarshalersALCNative.cpp rename to tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshalerNative.cpp diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj b/tests/src/Interop/ICustomMarshaler/ConflictingNames/MultipleALCs.csproj similarity index 96% rename from tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj rename to tests/src/Interop/ICustomMarshaler/ConflictingNames/MultipleALCs.csproj index abc186f67c85..045a2b69dc85 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/MultipleALCs.csproj +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/MultipleALCs.csproj @@ -28,7 +28,7 @@ - + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs similarity index 97% rename from tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs rename to tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs index 0d156d33e3c3..355842e50469 100644 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/RunInALC.cs +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs @@ -23,7 +23,7 @@ static void Run() string currentAssemblyDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); var context = new CustomLoadContext(); Assembly inContextAssembly = context.LoadFromAssemblyPath(Path.Combine(currentAssemblyDirectory, "CustomMarshalerInALC.dll")); - Type inContextType = inContextAssembly.GetType("CustomMarshalerTest"); + Type inContextType = inContextAssembly.GetType("CustomMarshalers.CustomMarshalerTest"); object instance = Activator.CreateInstance(inContextType); MethodInfo parseIntMethod = inContextType.GetMethod("ParseInt", BindingFlags.Instance | BindingFlags.Public); Assert.AreEqual(1234, (int)parseIntMethod.Invoke(instance, new object[]{"1234"})); diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs new file mode 100644 index 000000000000..836e23e683e2 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; +using TestLibrary; + +public class RunInALC +{ + public static int Main(string[] args) + { + Assert.AreEqual(123, new CustomMarshalers.CustomMarshalerTest().ParseInt("123")); + Assert.AreEqual(123, new CustomMarshalers2.CustomMarshalerTest().ParseInt("123")); + return 100; + } +} diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.csproj b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.csproj new file mode 100644 index 000000000000..6b1f7df357d2 --- /dev/null +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.csproj @@ -0,0 +1,35 @@ + + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt b/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt deleted file mode 100644 index f1ddedb6f6f6..000000000000 --- a/tests/src/Interop/ICustomMarshaler/MultipleALCs/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project (CustomMarshalersALCNative) -include_directories(${INC_PLATFORM_DIR}) -set(SOURCES CustomMarshalersALCNative.cpp ) - -# add the executable -add_library (CustomMarshalersALCNative SHARED ${SOURCES}) -target_link_libraries(CustomMarshalersALCNative ${LINK_LIBRARIES_ADDITIONAL}) - -# add the install targets -install (TARGETS CustomMarshalersALCNative DESTINATION bin) From f7f49ba902a32fca824712e519e70cade1a236cd Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 11:05:47 -0800 Subject: [PATCH 06/17] Move EEMarshalingData cache from AppDomain to LoaderAllocator. This fixes the custom-marshaler conflict when using unloadable assembly contexts. --- src/vm/appdomain.cpp | 50 ------------------ src/vm/appdomain.hpp | 10 ---- src/vm/ceemain.cpp | 5 -- src/vm/cominterfacemarshaler.cpp | 4 +- src/vm/custommarshalerinfo.cpp | 8 +-- src/vm/custommarshalerinfo.h | 2 +- src/vm/dispparammarshaler.cpp | 2 +- src/vm/ilmarshalers.cpp | 24 ++++----- src/vm/interopconverter.cpp | 4 +- src/vm/interoputil.cpp | 6 +-- src/vm/loaderallocator.cpp | 52 +++++++++++++++++++ src/vm/loaderallocator.hpp | 12 +++++ src/vm/mlinfo.cpp | 17 +++--- src/vm/mlinfo.h | 5 +- .../ConflictingNames/RunInALC.cs | 43 +++++++++++++-- 15 files changed, 138 insertions(+), 106 deletions(-) diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 3e850f10d230..3b41eb6b7940 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -711,8 +711,6 @@ BaseDomain::BaseDomain() m_handleStore = NULL; #endif - m_pMarshalingData = NULL; - #ifdef FEATURE_COMINTEROP m_pMngStdInterfacesInfo = NULL; m_pWinRtBinder = NULL; @@ -785,9 +783,6 @@ void BaseDomain::Init() m_crstAssemblyList.Init(CrstAssemblyList, CrstFlags( CRST_GC_NOTRIGGER_WHEN_TAKEN | CRST_DEBUGGER_THREAD | CRST_TAKEN_DURING_SHUTDOWN)); - // Initialize the EE marshaling data to NULL. - m_pMarshalingData = NULL; - #ifdef FEATURE_COMINTEROP // Allocate the managed standard interfaces information. m_pMngStdInterfacesInfo = new MngStdInterfacesInfo(); @@ -1805,51 +1800,6 @@ OBJECTREF AppDomain::GetMissingObject() #ifndef DACCESS_COMPILE -EEMarshalingData *BaseDomain::GetMarshalingData() -{ - CONTRACT (EEMarshalingData*) - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(m_pMarshalingData)); - } - CONTRACT_END; - - if (!m_pMarshalingData) - { - // Take the lock - CrstHolder holder(&m_InteropDataCrst); - - if (!m_pMarshalingData) - { - LoaderHeap* pHeap = GetLoaderAllocator()->GetLowFrequencyHeap(); - m_pMarshalingData = new (pHeap) EEMarshalingData(this, pHeap, &m_DomainCrst); - } - } - - RETURN m_pMarshalingData; -} - -void BaseDomain::DeleteMarshalingData() -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - // We are in shutdown - no need to take any lock - if (m_pMarshalingData) - { - delete m_pMarshalingData; - m_pMarshalingData = NULL; - } -} - #ifndef CROSSGEN_COMPILE STRINGREF *BaseDomain::IsStringInterned(STRINGREF *pString) diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index 0aeab8f1e4bb..c6327a5f29ce 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -1124,14 +1124,6 @@ class BaseDomain return m_pWinRtBinder; } #endif // FEATURE_COMINTEROP - - //**************************************************************************************** - // This method returns marshaling data that the EE uses that is stored on a per app domain - // basis. - EEMarshalingData *GetMarshalingData(); - - // Deletes marshaling data at shutdown (which contains cached factories that needs to be released) - void DeleteMarshalingData(); #ifdef _DEBUG BOOL OwnDomainLocalBlockLock() @@ -1332,8 +1324,6 @@ class BaseDomain // The large heap handle table critical section. CrstExplicitInit m_LargeHeapHandleTableCrst; - EEMarshalingData *m_pMarshalingData; - #ifdef FEATURE_COMINTEROP // Information regarding the managed standard interfaces. MngStdInterfacesInfo *m_pMngStdInterfacesInfo; diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index 468a1da7f268..16a0ce49cb2c 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -1190,11 +1190,6 @@ void InnerCoEEShutDownCOM() // Release all of the RCWs in all contexts in all caches. ReleaseRCWsInCaches(NULL); - // Release all marshaling data in all AppDomains - AppDomainIterator i(TRUE); - while (i.Next()) - i.GetDomain()->DeleteMarshalingData(); - #ifdef FEATURE_APPX // Cleanup cached factory pointer in SynchronizationContextNative SynchronizationContextNative::Cleanup(); diff --git a/src/vm/cominterfacemarshaler.cpp b/src/vm/cominterfacemarshaler.cpp index a206222d851e..5ee831cb91b7 100644 --- a/src/vm/cominterfacemarshaler.cpp +++ b/src/vm/cominterfacemarshaler.cpp @@ -745,7 +745,7 @@ void COMInterfaceMarshaler::MarshalToNonRCWType(OBJECTREF *poref) LPCWSTR pwszRawUri = hsRawUri.GetRawBuffer(&cchRawUri); gc.refRawURI = StringObject::NewString(pwszRawUri, cchRawUri); - UriMarshalingInfo *pUriMarshalingInfo = GetAppDomain()->GetMarshalingData()->GetUriMarshalingInfo(); + UriMarshalingInfo *pUriMarshalingInfo = GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo(); MethodDesc* pSystemUriCtorMD = pUriMarshalingInfo->GetSystemUriCtorMD(); MethodTable *pMTSystemUri = pUriMarshalingInfo->GetSystemUriType().AsMethodTable(); @@ -787,7 +787,7 @@ void COMInterfaceMarshaler::MarshalToNonRCWType(OBJECTREF *poref) case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs: { MethodDesc *pMD; - EventArgsMarshalingInfo *pInfo = GetAppDomain()->GetMarshalingData()->GetEventArgsMarshalingInfo(); + EventArgsMarshalingInfo *pInfo = GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo(); if (index == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs) pMD = pInfo->GetWinRTNCCEventArgsToSystemNCCEventArgsMD(); diff --git a/src/vm/custommarshalerinfo.cpp b/src/vm/custommarshalerinfo.cpp index 98484876cc18..5889c33d440f 100644 --- a/src/vm/custommarshalerinfo.cpp +++ b/src/vm/custommarshalerinfo.cpp @@ -23,7 +23,7 @@ // Implementation of the custom marshaler info class. //========================================================================== -CustomMarshalerInfo::CustomMarshalerInfo(BaseDomain *pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) +CustomMarshalerInfo::CustomMarshalerInfo(LoaderAllocator *pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes) : m_NativeSize(0) , m_hndManagedType(hndManagedType) , m_hndCustomMarshaler(NULL) @@ -38,7 +38,7 @@ CustomMarshalerInfo::CustomMarshalerInfo(BaseDomain *pDomain, TypeHandle hndCust THROWS; GC_TRIGGERS; MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pDomain)); + PRECONDITION(CheckPointer(pLoaderAllocator)); } CONTRACTL_END; @@ -112,7 +112,7 @@ CustomMarshalerInfo::CustomMarshalerInfo(BaseDomain *pDomain, TypeHandle hndCust IDS_EE_NOCUSTOMMARSHALER, GetFullyQualifiedNameForClassW(hndCustomMarshalerType.GetMethodTable())); } - m_hndCustomMarshaler = pDomain->CreateHandle(CustomMarshalerObj); + m_hndCustomMarshaler = pLoaderAllocator->GetDomain()->CreateHandle(CustomMarshalerObj); // Retrieve the size of the native data. if (m_bDataIsByValue) @@ -628,7 +628,7 @@ CustomMarshalerInfo *SharedCustomMarshalerHelper::GetCustomMarshalerInfo() CONTRACTL_END; // Retrieve the marshalling data for the current app domain. - EEMarshalingData *pMarshalingData = GetThread()->GetDomain()->GetMarshalingData(); + EEMarshalingData *pMarshalingData = GetThread()->GetDomain()->GetLoaderAllocator()->GetMarshalingData(); // Retrieve the custom marshaling information for the current shared custom // marshaling helper. diff --git a/src/vm/custommarshalerinfo.h b/src/vm/custommarshalerinfo.h index aecedf4201b5..951679d135f0 100644 --- a/src/vm/custommarshalerinfo.h +++ b/src/vm/custommarshalerinfo.h @@ -36,7 +36,7 @@ class CustomMarshalerInfo { public: // Constructor and destructor. - CustomMarshalerInfo(BaseDomain* pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes); + CustomMarshalerInfo(LoaderAllocator* pLoaderAllocator, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes); ~CustomMarshalerInfo(); // CustomMarshalerInfo's are always allocated on the loader heap so we need to redefine diff --git a/src/vm/dispparammarshaler.cpp b/src/vm/dispparammarshaler.cpp index 04d156613e75..06ae5bbbf861 100644 --- a/src/vm/dispparammarshaler.cpp +++ b/src/vm/dispparammarshaler.cpp @@ -102,7 +102,7 @@ void DispParamOleColorMarshaler::MarshalNativeToManaged(VARIANT *pSrcVar, OBJECT // Box the System.Drawing.Color value class and give back the boxed object. TypeHandle hndColorType = - GetThread()->GetDomain()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); + GetThread()->GetDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); *pDestObj = hndColorType.GetMethodTable()->Box(&MngColor); } diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp index 58319d85e452..24e8cc4cacd1 100644 --- a/src/vm/ilmarshalers.cpp +++ b/src/vm/ilmarshalers.cpp @@ -1521,7 +1521,7 @@ LocalDesc ILOleColorMarshaler::GetManagedType() STANDARD_VM_CONTRACT; BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndColorType = pDomain->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); + TypeHandle hndColorType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); // // value class @@ -1534,7 +1534,7 @@ void ILOleColorMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit STANDARD_VM_CONTRACT; BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - MethodDesc* pConvertMD = pDomain->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); + MethodDesc* pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); EmitLoadManagedValue(pslILEmit); // int System.Drawing.ColorTranslator.ToOle(System.Drawing.Color c) @@ -1547,7 +1547,7 @@ void ILOleColorMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit STANDARD_VM_CONTRACT; BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - MethodDesc* pConvertMD = pDomain->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); + MethodDesc* pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); EmitLoadNativeValue(pslILEmit); // System.Drawing.Color System.Drawing.ColorTranslator.FromOle(int oleColor) @@ -5676,7 +5676,7 @@ LocalDesc ILUriMarshaler::GetManagedType() { STANDARD_VM_CONTRACT;; BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndUriType = pDomain->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriType(); + TypeHandle hndUriType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriType(); return LocalDesc(hndUriType); // System.Uri } @@ -5693,7 +5693,7 @@ void ILUriMarshaler::EmitConvertCLRUriToWinRTUri(ILCodeStream* pslILEmit, BaseDo { STANDARD_VM_CONTRACT; - UriMarshalingInfo* marshalingInfo = pDomain->GetMarshalingData()->GetUriMarshalingInfo(); + UriMarshalingInfo* marshalingInfo = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo(); ILCodeLabel *pNotNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel *pDoneLabel = pslILEmit->NewCodeLabel(); @@ -5731,7 +5731,7 @@ void ILUriMarshaler::EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, BaseDo { STANDARD_VM_CONTRACT; - MethodDesc* pSystemUriCtorMD = pDomain->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriCtorMD(); + MethodDesc* pSystemUriCtorMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriCtorMD(); ILCodeLabel *pNotNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel *pDoneLabel = pslILEmit->NewCodeLabel(); @@ -5784,7 +5784,7 @@ LocalDesc ILNCCEventArgsMarshaler::GetManagedType() STANDARD_VM_CONTRACT;; BaseDomain *pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndNCCEventArgType = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsType(); + TypeHandle hndNCCEventArgType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsType(); return LocalDesc(hndNCCEventArgType); // System.Collections.Specialized.NotifyCollectionChangedEventArgs } @@ -5802,7 +5802,7 @@ void ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStre { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsToWinRTNCCEventArgsMD(); + MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsToWinRTNCCEventArgsMD(); // IntPtr System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventArgsMarshaler.ConvertToNative(NotifyCollectionChangedEventArgs) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5824,7 +5824,7 @@ void ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStre { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTNCCEventArgsToSystemNCCEventArgsMD(); + MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTNCCEventArgsToSystemNCCEventArgsMD(); // NotifyCollectionChangedEventArgs System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventArgsMarshaler.ConvertToManaged(IntPtr) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5860,7 +5860,7 @@ LocalDesc ILPCEventArgsMarshaler::GetManagedType() STANDARD_VM_CONTRACT;; BaseDomain *pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndPCEventArgType = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsType(); + TypeHandle hndPCEventArgType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsType(); return LocalDesc(hndPCEventArgType); // System.ComponentModel.PropertyChangedEventArgs } @@ -5878,7 +5878,7 @@ void ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStrea { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsToWinRTPCEventArgsMD(); + MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsToWinRTPCEventArgsMD(); // IntPtr System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventArgsMarshaler.ConvertToNative(PropertyChangedEventArgs) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5900,7 +5900,7 @@ void ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStrea { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTPCEventArgsToSystemPCEventArgsMD(); + MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTPCEventArgsToSystemPCEventArgsMD(); // PropertyChangedEventArgs System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventArgsMarshaler.ConvertToManaged(IntPtr) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); diff --git a/src/vm/interopconverter.cpp b/src/vm/interopconverter.cpp index c681023bc911..26254e1aed28 100644 --- a/src/vm/interopconverter.cpp +++ b/src/vm/interopconverter.cpp @@ -207,7 +207,7 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType // This is a redirected type - see if we need to manually marshal it if (redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Uri) { - UriMarshalingInfo *pUriMarshalInfo = GetAppDomain()->GetMarshalingData()->GetUriMarshalingInfo(); + UriMarshalingInfo *pUriMarshalInfo = GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo(); struct { OBJECTREF ref; @@ -241,7 +241,7 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs) { MethodDesc *pMD; - EventArgsMarshalingInfo *pInfo = GetAppDomain()->GetMarshalingData()->GetEventArgsMarshalingInfo(); + EventArgsMarshalingInfo *pInfo = GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo(); if (redirectedTypeIndex == WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs) pMD = pInfo->GetSystemNCCEventArgsToWinRTNCCEventArgsMD(); diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp index a21e68b27095..b84670ba3a19 100644 --- a/src/vm/interoputil.cpp +++ b/src/vm/interoputil.cpp @@ -3261,7 +3261,7 @@ void ConvertOleColorToSystemColor(OLE_COLOR SrcOleColor, SYSTEMCOLOR *pDestSysCo // Retrieve the method desc to use for the current AD. MethodDesc *pOleColorToSystemColorMD = - GetAppDomain()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); + GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); MethodDescCallSite oleColorToSystemColor(pOleColorToSystemColorMD); @@ -3290,7 +3290,7 @@ OLE_COLOR ConvertSystemColorToOleColor(OBJECTREF *pSrcObj) // Retrieve the method desc to use for the current AD. MethodDesc *pSystemColorToOleColorMD = - GetAppDomain()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); + GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); MethodDescCallSite systemColorToOleColor(pSystemColorToOleColorMD); // Set up the args and call the method. @@ -6732,7 +6732,7 @@ ABI::Windows::Foundation::IUriRuntimeClass *CreateWinRTUri(LPCWSTR wszUri, INT32 { STANDARD_VM_CONTRACT; - UriMarshalingInfo* marshalingInfo = GetAppDomain()->GetMarshalingData()->GetUriMarshalingInfo(); + UriMarshalingInfo* marshalingInfo = GetAppDomain()->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo(); // Get the cached factory from the UriMarshalingInfo object of the current appdomain ABI::Windows::Foundation::IUriRuntimeClassFactory* pFactory = marshalingInfo->GetUriFactory(); diff --git a/src/vm/loaderallocator.cpp b/src/vm/loaderallocator.cpp index e3092ff9f387..b2bb2b627279 100644 --- a/src/vm/loaderallocator.cpp +++ b/src/vm/loaderallocator.cpp @@ -73,6 +73,8 @@ LoaderAllocator::LoaderAllocator() m_pJumpStubCache = NULL; m_IsCollectible = false; + m_pMarshalingData = NULL; + #ifdef FEATURE_COMINTEROP m_pComCallWrapperCache = NULL; #endif @@ -1217,6 +1219,9 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory) m_pPrecodeHeap = new (&m_PrecodeHeapInstance) CodeFragmentHeap(this, STUB_CODE_BLOCK_PRECODE); #endif + // Initialize the EE marshaling data to NULL. + m_pMarshalingData = NULL; + // Set up the IL stub cache m_ILStubCache.Init(m_pHighFrequencyHeap); @@ -1322,6 +1327,8 @@ void LoaderAllocator::Terminate() LOG((LF_CLASSLOADER, LL_INFO100, "Begin LoaderAllocator::Terminate for loader allocator %p\n", reinterpret_cast(static_cast(this)))); + DeleteMarshalingData(); + if (m_fGCPressure) { GCX_PREEMP(); @@ -1621,6 +1628,51 @@ void LoaderAllocator::UninitVirtualCallStubManager() } #endif // !CROSSGEN_COMPILE +EEMarshalingData *LoaderAllocator::GetMarshalingData() +{ + CONTRACT (EEMarshalingData*) + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + INJECT_FAULT(COMPlusThrowOM()); + POSTCONDITION(CheckPointer(m_pMarshalingData)); + } + CONTRACT_END; + + if (!m_pMarshalingData) + { + // Take the lock + CrstHolder holder(&m_InteropDataCrst); + + if (!m_pMarshalingData) + { + LoaderHeap* pHeap = GetLowFrequencyHeap(); + m_pMarshalingData = new (pHeap) EEMarshalingData(this, pHeap, &m_crstLoaderAllocator); + } + } + + RETURN m_pMarshalingData; +} + +void LoaderAllocator::DeleteMarshalingData() +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + // We are in shutdown - no need to take any lock + if (m_pMarshalingData) + { + delete m_pMarshalingData; + m_pMarshalingData = NULL; + } +} + #endif // !DACCESS_COMPILE BOOL GlobalLoaderAllocator::CanUnload() diff --git a/src/vm/loaderallocator.hpp b/src/vm/loaderallocator.hpp index 723735966629..d1f29aebebe0 100644 --- a/src/vm/loaderallocator.hpp +++ b/src/vm/loaderallocator.hpp @@ -132,6 +132,7 @@ class UMEntryThunkCache; #ifdef FEATURE_COMINTEROP class ComCallWrapperCache; #endif // FEATURE_COMINTEROP +class EEMarshalingData; class LoaderAllocator { @@ -263,6 +264,9 @@ class LoaderAllocator PtrHashMap m_interopDataHash; // Used for synchronizing access to the m_interopDataHash CrstExplicitInit m_InteropDataCrst; + + + EEMarshalingData* m_pMarshalingData; #endif #ifndef DACCESS_COMPILE @@ -547,6 +551,14 @@ class LoaderAllocator return &m_ILStubCache; } + //**************************************************************************************** + // This method returns marshaling data that the EE uses that is stored on a per LoaderAllocator + // basis. + EEMarshalingData *GetMarshalingData(); + + // Deletes marshaling data at shutdown (which contains cached factories that needs to be released) + void DeleteMarshalingData(); + #ifdef FEATURE_COMINTEROP ComCallWrapperCache * GetComCallWrapperCache(); diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp index 24af47c70822..f91a2e8958e0 100644 --- a/src/vm/mlinfo.cpp +++ b/src/vm/mlinfo.cpp @@ -429,7 +429,7 @@ CustomMarshalerHelper *SetupCustomMarshalerHelper(LPCUTF8 strMarshalerTypeName, EEMarshalingData *pMarshalingData = NULL; // The assembly is not shared so we use the current app domain's marshaling data. - pMarshalingData = GetThread()->GetDomain()->GetMarshalingData(); + pMarshalingData = pAssembly->GetLoaderAllocator()->GetMarshalingData(); // Retrieve the custom marshaler helper from the EE marshaling data. RETURN pMarshalingData->GetCustomMarshalerHelper(pAssembly, hndManagedType, strMarshalerTypeName, cMarshalerTypeNameBytes, strCookie, cCookieStrBytes); @@ -1072,9 +1072,10 @@ void OleColorMarshalingInfo::operator delete(void *pMem) #endif // FEATURE_COMINTEROP -EEMarshalingData::EEMarshalingData(BaseDomain *pDomain, LoaderHeap *pHeap, CrstBase *pCrst) : +EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, LoaderHeap *pHeap, CrstBase *pCrst) : + m_pAllocator(pAllocator), m_pHeap(pHeap), - m_pDomain(pDomain) + m_lock(pCrst) { CONTRACTL { @@ -1209,15 +1210,14 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss // Create the custom marshaler info in the specified heap. - pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pDomain, hndCustomMarshalerType, hndManagedType, strCookie, cCookieStrBytes); + pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, hndCustomMarshalerType, hndManagedType, strCookie, cCookieStrBytes); // Create the custom marshaler helper in the specified heap. pNewCMHelper = new (m_pHeap) NonSharedCustomMarshalerHelper(pNewCMInfo); } - // Take the app domain lock before we insert the custom marshaler info into the hashtable. { - BaseDomain::LockHolder lh(m_pDomain); + CrstHolder lock(m_lock); // Verify that the custom marshaler helper has not already been added by another thread. if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) @@ -1277,15 +1277,14 @@ CustomMarshalerInfo *EEMarshalingData::GetCustomMarshalerInfo(SharedCustomMarsha } // Create the custom marshaler info in the specified heap. - pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pDomain, + pNewCMInfo = new (m_pHeap) CustomMarshalerInfo(m_pAllocator, hndCustomMarshalerType, pSharedCMHelper->GetManagedType(), pSharedCMHelper->GetCookieString(), pSharedCMHelper->GetCookieStringByteCount()); { - // Take the app domain lock before we insert the custom marshaler info into the hashtable. - BaseDomain::LockHolder lh(m_pDomain); + CrstHolder lock(m_lock); // Verify that the custom marshaler info has not already been added by another thread. if (m_SharedCMHelperToCMInfoMap.GetValue(pSharedCMHelper, (HashDatum*)&pCMInfo)) diff --git a/src/vm/mlinfo.h b/src/vm/mlinfo.h index b31e34f1386d..a6dd7674ca0d 100644 --- a/src/vm/mlinfo.h +++ b/src/vm/mlinfo.h @@ -373,7 +373,7 @@ class OleColorMarshalingInfo class EEMarshalingData { public: - EEMarshalingData(BaseDomain *pDomain, LoaderHeap *pHeap, CrstBase *pCrst); + EEMarshalingData(LoaderAllocator *pAllocator, LoaderHeap *pHeap, CrstBase *pCrst); ~EEMarshalingData(); // EEMarshalingData's are always allocated on the loader heap so we need to redefine @@ -402,14 +402,15 @@ class EEMarshalingData EECMHelperHashTable m_CMHelperHashtable; EEPtrHashTable m_SharedCMHelperToCMInfoMap; #endif // CROSSGEN_COMPILE + LoaderAllocator* m_pAllocator; LoaderHeap* m_pHeap; - BaseDomain* m_pDomain; CMINFOLIST m_pCMInfoList; #ifdef FEATURE_COMINTEROP OleColorMarshalingInfo* m_pOleColorInfo; UriMarshalingInfo* m_pUriInfo; EventArgsMarshalingInfo* m_pEventArgsInfo; #endif // FEATURE_COMINTEROP + CrstBase* m_lock; }; struct ItfMarshalInfo; diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs index 355842e50469..1d61f2deafa9 100644 --- a/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/RunInALC.cs @@ -13,16 +13,35 @@ public class RunInALC { public static int Main(string[] args) { - Run(); - Run(); + try + { + ConflictingCustomMarshalerNamesInCollectibleLoadContexts_Succeeds(); + ConflictingCustomMarshalerNamesInNoncollectibleLoadContexts_Succeeds(); + } + catch (System.Exception e) + { + Console.WriteLine(e.ToString()); + return 101; + } return 100; } - static void Run() + static void ConflictingCustomMarshalerNamesInCollectibleLoadContexts_Succeeds() + { + Run(new UnloadableLoadContext()); + Run(new UnloadableLoadContext()); + } + + static void ConflictingCustomMarshalerNamesInNoncollectibleLoadContexts_Succeeds() + { + Run(new CustomLoadContext()); + Run(new CustomLoadContext()); + } + + static void Run(AssemblyLoadContext context) { string currentAssemblyDirectory = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); - var context = new CustomLoadContext(); - Assembly inContextAssembly = context.LoadFromAssemblyPath(Path.Combine(currentAssemblyDirectory, "CustomMarshalerInALC.dll")); + Assembly inContextAssembly = context.LoadFromAssemblyPath(Path.Combine(currentAssemblyDirectory, "CustomMarshaler.dll")); Type inContextType = inContextAssembly.GetType("CustomMarshalers.CustomMarshalerTest"); object instance = Activator.CreateInstance(inContextType); MethodInfo parseIntMethod = inContextType.GetMethod("ParseInt", BindingFlags.Instance | BindingFlags.Public); @@ -30,6 +49,20 @@ static void Run() } } +class UnloadableLoadContext : AssemblyLoadContext +{ + public UnloadableLoadContext() + :base(true) + { + + } + + protected override Assembly Load(AssemblyName assemblyName) + { + return null; + } +} + class CustomLoadContext : AssemblyLoadContext { protected override Assembly Load(AssemblyName assemblyName) From c938b8a5ff55448b43f6020870337d902f9b8e86 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 14:36:47 -0800 Subject: [PATCH 07/17] Internalize the LoaderHeap* parameter. --- src/vm/loaderallocator.cpp | 3 +-- src/vm/mlinfo.cpp | 4 ++-- src/vm/mlinfo.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vm/loaderallocator.cpp b/src/vm/loaderallocator.cpp index b2bb2b627279..8154afda2478 100644 --- a/src/vm/loaderallocator.cpp +++ b/src/vm/loaderallocator.cpp @@ -1647,8 +1647,7 @@ EEMarshalingData *LoaderAllocator::GetMarshalingData() if (!m_pMarshalingData) { - LoaderHeap* pHeap = GetLowFrequencyHeap(); - m_pMarshalingData = new (pHeap) EEMarshalingData(this, pHeap, &m_crstLoaderAllocator); + m_pMarshalingData = new (GetLowFrequencyHeap()) EEMarshalingData(this, &m_crstLoaderAllocator); } } diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp index f91a2e8958e0..b2378a1f9146 100644 --- a/src/vm/mlinfo.cpp +++ b/src/vm/mlinfo.cpp @@ -1072,9 +1072,9 @@ void OleColorMarshalingInfo::operator delete(void *pMem) #endif // FEATURE_COMINTEROP -EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, LoaderHeap *pHeap, CrstBase *pCrst) : +EEMarshalingData::EEMarshalingData(LoaderAllocator* pAllocator, CrstBase *pCrst) : m_pAllocator(pAllocator), - m_pHeap(pHeap), + m_pHeap(pAllocator->GetLowFrequencyHeap()), m_lock(pCrst) { CONTRACTL diff --git a/src/vm/mlinfo.h b/src/vm/mlinfo.h index a6dd7674ca0d..3cba57465611 100644 --- a/src/vm/mlinfo.h +++ b/src/vm/mlinfo.h @@ -373,7 +373,7 @@ class OleColorMarshalingInfo class EEMarshalingData { public: - EEMarshalingData(LoaderAllocator *pAllocator, LoaderHeap *pHeap, CrstBase *pCrst); + EEMarshalingData(LoaderAllocator *pAllocator, CrstBase *pCrst); ~EEMarshalingData(); // EEMarshalingData's are always allocated on the loader heap so we need to redefine From 7ab2a81e7a68a2f5da6cbd3fce822542a6cef0bd Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 15:31:30 -0800 Subject: [PATCH 08/17] Add the pointer to the requesting assembly to the hashtable key. --- src/vm/custommarshalerinfo.cpp | 3 +++ src/vm/custommarshalerinfo.h | 10 +++++++++- src/vm/mlinfo.cpp | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vm/custommarshalerinfo.cpp b/src/vm/custommarshalerinfo.cpp index 5889c33d440f..044d71e8a52f 100644 --- a/src/vm/custommarshalerinfo.cpp +++ b/src/vm/custommarshalerinfo.cpp @@ -458,6 +458,9 @@ BOOL EECMHelperHashtableHelper::CompareKeys(EEHashEntry_t *pEntry, EECMHelperHas return FALSE; } + if (pEntryKey->GetInvokingAssembly() != pKey->GetInvokingAssembly()) + return FALSE; + return TRUE; } diff --git a/src/vm/custommarshalerinfo.h b/src/vm/custommarshalerinfo.h index 951679d135f0..fe67da3cc70b 100644 --- a/src/vm/custommarshalerinfo.h +++ b/src/vm/custommarshalerinfo.h @@ -114,16 +114,18 @@ class CustomMarshalerInfo typedef SList CMINFOLIST; +class Assembly; class EECMHelperHashtableKey { public: - EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation) + EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation, Assembly* invokingAssembly) : m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) , m_strMarshalerTypeName(strMarshalerTypeName) , m_cCookieStrBytes(cCookieStrBytes) , m_strCookie(strCookie) , m_Instantiation(instantiation) + , m_invokingAssembly(invokingAssembly) { LIMITED_METHOD_CONTRACT; } @@ -153,12 +155,18 @@ class EECMHelperHashtableKey LIMITED_METHOD_CONTRACT; return m_Instantiation; } + inline Assembly* GetInvokingAssembly() const + { + LIMITED_METHOD_CONTRACT; + return m_invokingAssembly; + } DWORD m_cMarshalerTypeNameBytes; LPCSTR m_strMarshalerTypeName; DWORD m_cCookieStrBytes; LPCSTR m_strCookie; Instantiation m_Instantiation; + Assembly* m_invokingAssembly; }; diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp index b2378a1f9146..d5934c62bf77 100644 --- a/src/vm/mlinfo.cpp +++ b/src/vm/mlinfo.cpp @@ -1178,7 +1178,7 @@ CustomMarshalerHelper *EEMarshalingData::GetCustomMarshalerHelper(Assembly *pAss TypeHandle hndCustomMarshalerType; // Create the key that will be used to lookup in the hashtable. - EECMHelperHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation()); + EECMHelperHashtableKey Key(cMarshalerTypeNameBytes, strMarshalerTypeName, cCookieStrBytes, strCookie, hndManagedType.GetInstantiation(), pAssembly); // Lookup the custom marshaler helper in the hashtable. if (m_CMHelperHashtable.GetValue(&Key, (HashDatum*)&pCMHelper)) From a60d1d71835e59c99d3413f3ea53586a2cbf1f96 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 15:32:40 -0800 Subject: [PATCH 09/17] Fix linux-musl build break. --- src/vm/loaderallocator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm/loaderallocator.hpp b/src/vm/loaderallocator.hpp index d1f29aebebe0..427087148097 100644 --- a/src/vm/loaderallocator.hpp +++ b/src/vm/loaderallocator.hpp @@ -262,12 +262,12 @@ class LoaderAllocator CrstExplicitInit m_ComCallWrapperCrst; // Hash table that maps a MethodTable to COM Interop compatibility data. PtrHashMap m_interopDataHash; + // Used for synchronizing access to the m_interopDataHash CrstExplicitInit m_InteropDataCrst; +#endif - EEMarshalingData* m_pMarshalingData; -#endif #ifndef DACCESS_COMPILE From 62cf89fe4020c6942e1e806dc84f26e0f3c5b22c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 15:50:05 -0800 Subject: [PATCH 10/17] Move Crst out of FEATURE_COMINTEROP block. --- src/vm/loaderallocator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm/loaderallocator.hpp b/src/vm/loaderallocator.hpp index 427087148097..0a70dc681490 100644 --- a/src/vm/loaderallocator.hpp +++ b/src/vm/loaderallocator.hpp @@ -263,10 +263,10 @@ class LoaderAllocator // Hash table that maps a MethodTable to COM Interop compatibility data. PtrHashMap m_interopDataHash; - // Used for synchronizing access to the m_interopDataHash - CrstExplicitInit m_InteropDataCrst; #endif + // Used for synchronizing access to the m_interopDataHash and m_pMarshalingData + CrstExplicitInit m_InteropDataCrst; EEMarshalingData* m_pMarshalingData; #ifndef DACCESS_COMPILE From 0c006a89766f465d97719a685701715386a7e4d6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 21 Dec 2018 17:09:24 -0800 Subject: [PATCH 11/17] Make sure to copy over the assembly pointer to the key that's actually stored in the hash table. --- src/vm/custommarshalerinfo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vm/custommarshalerinfo.cpp b/src/vm/custommarshalerinfo.cpp index 044d71e8a52f..c7716dfe5dd1 100644 --- a/src/vm/custommarshalerinfo.cpp +++ b/src/vm/custommarshalerinfo.cpp @@ -367,6 +367,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey cbEntry += S_SIZE_T(pKey->GetMarshalerTypeNameByteCount()); cbEntry += S_SIZE_T(pKey->GetCookieStringByteCount()); cbEntry += S_SIZE_T(pKey->GetMarshalerInstantiation().GetNumArgs()) * S_SIZE_T(sizeof(LPVOID)); + cbEntry += S_SIZE_T(sizeof(LPVOID)); if (cbEntry.IsOverflow()) return NULL; @@ -387,6 +388,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey memcpy((void*)pEntryKey->m_strCookie, pKey->GetCookieString(), pKey->GetCookieStringByteCount()); memcpy((void*)pEntryKey->m_Instantiation.GetRawArgs(), pKey->GetMarshalerInstantiation().GetRawArgs(), pEntryKey->m_Instantiation.GetNumArgs() * sizeof(LPVOID)); + pEntryKey->m_invokingAssembly = pKey->GetInvokingAssembly(); } else { @@ -401,6 +403,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey pEntryKey->m_cCookieStrBytes = pKey->GetCookieStringByteCount(); pEntryKey->m_strCookie = pKey->GetCookieString(); pEntryKey->m_Instantiation = Instantiation(pKey->GetMarshalerInstantiation()); + pEntryKey->m_invokingAssembly = pKey->GetInvokingAssembly(); } return pEntry; From 2b0c96fed2b9fae02fa8641f37a51dbf3b0105d0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 2 Jan 2019 09:43:38 -0800 Subject: [PATCH 12/17] Add comment for m_invokingAssembly. --- src/vm/custommarshalerinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/custommarshalerinfo.cpp b/src/vm/custommarshalerinfo.cpp index c7716dfe5dd1..d2d9ef2a40a9 100644 --- a/src/vm/custommarshalerinfo.cpp +++ b/src/vm/custommarshalerinfo.cpp @@ -367,7 +367,7 @@ EEHashEntry_t * EECMHelperHashtableHelper::AllocateEntry(EECMHelperHashtableKey cbEntry += S_SIZE_T(pKey->GetMarshalerTypeNameByteCount()); cbEntry += S_SIZE_T(pKey->GetCookieStringByteCount()); cbEntry += S_SIZE_T(pKey->GetMarshalerInstantiation().GetNumArgs()) * S_SIZE_T(sizeof(LPVOID)); - cbEntry += S_SIZE_T(sizeof(LPVOID)); + cbEntry += S_SIZE_T(sizeof(LPVOID)); // For EECMHelperHashtableKey::m_invokingAssembly if (cbEntry.IsOverflow()) return NULL; From 2da4af171385a827a39b6db60c145f1ca3683d78 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 2 Jan 2019 09:55:00 -0800 Subject: [PATCH 13/17] Move all usages of EEMarshallingData to hang off the correct loader allocator instead of always the global one. --- src/vm/ilmarshalers.cpp | 72 ++++++++++++++++++++--------------------- src/vm/ilmarshalers.h | 12 +++---- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp index 24e8cc4cacd1..dedd9e8c18b4 100644 --- a/src/vm/ilmarshalers.cpp +++ b/src/vm/ilmarshalers.cpp @@ -1520,8 +1520,8 @@ LocalDesc ILOleColorMarshaler::GetManagedType() { STANDARD_VM_CONTRACT; - BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndColorType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); + LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + TypeHandle hndColorType = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetColorType(); // // value class @@ -1533,8 +1533,8 @@ void ILOleColorMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit { STANDARD_VM_CONTRACT; - BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - MethodDesc* pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); + LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetSystemColorToOleColorMD(); EmitLoadManagedValue(pslILEmit); // int System.Drawing.ColorTranslator.ToOle(System.Drawing.Color c) @@ -1546,8 +1546,8 @@ void ILOleColorMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit { STANDARD_VM_CONTRACT; - BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - MethodDesc* pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); + LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + MethodDesc* pConvertMD = pLoader->GetMarshalingData()->GetOleColorMarshalingInfo()->GetOleColorToSystemColorMD(); EmitLoadNativeValue(pslILEmit); // System.Drawing.Color System.Drawing.ColorTranslator.FromOle(int oleColor) @@ -4798,15 +4798,15 @@ void ILHiddenLengthArrayMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* switch (m_pargs->na.m_redirectedTypeIndex) { case WinMDAdapter::RedirectedTypeIndex_System_Uri: - ILUriMarshaler::EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILUriMarshaler::EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs: - ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs: - ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; default: UNREACHABLE(); @@ -4871,15 +4871,15 @@ void ILHiddenLengthArrayMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* switch (m_pargs->na.m_redirectedTypeIndex) { case WinMDAdapter::RedirectedTypeIndex_System_Uri: - ILUriMarshaler::EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILUriMarshaler::EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventArgs: - ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventArgs: - ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); break; default: UNREACHABLE(); @@ -5675,8 +5675,8 @@ LocalDesc ILUriMarshaler::GetNativeType() LocalDesc ILUriMarshaler::GetManagedType() { STANDARD_VM_CONTRACT;; - BaseDomain* pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndUriType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriType(); + LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + TypeHandle hndUriType = pLoader->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriType(); return LocalDesc(hndUriType); // System.Uri } @@ -5689,11 +5689,11 @@ bool ILUriMarshaler::NeedsClearNative() // Note that this method expects the CLR Uri on top of the evaluation stack and leaves the WinRT Uri there. //static -void ILUriMarshaler::EmitConvertCLRUriToWinRTUri(ILCodeStream* pslILEmit, BaseDomain* pDomain) +void ILUriMarshaler::EmitConvertCLRUriToWinRTUri(ILCodeStream* pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - UriMarshalingInfo* marshalingInfo = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo(); + UriMarshalingInfo* marshalingInfo = pLoader->GetMarshalingData()->GetUriMarshalingInfo(); ILCodeLabel *pNotNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel *pDoneLabel = pslILEmit->NewCodeLabel(); @@ -5721,17 +5721,17 @@ void ILUriMarshaler::EmitConvertContentsCLRToNative(ILCodeStream* pslILEmit) STANDARD_VM_CONTRACT; EmitLoadManagedValue(pslILEmit); - EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertCLRUriToWinRTUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreNativeValue(pslILEmit); } // Note that this method expects the WinRT Uri on top of the evaluation stack and leaves the CLR Uri there. //static -void ILUriMarshaler::EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, BaseDomain* pDomain) +void ILUriMarshaler::EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - MethodDesc* pSystemUriCtorMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriCtorMD(); + MethodDesc* pSystemUriCtorMD = pLoader->GetMarshalingData()->GetUriMarshalingInfo()->GetSystemUriCtorMD(); ILCodeLabel *pNotNullLabel = pslILEmit->NewCodeLabel(); ILCodeLabel *pDoneLabel = pslILEmit->NewCodeLabel(); @@ -5759,7 +5759,7 @@ void ILUriMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit) STANDARD_VM_CONTRACT; EmitLoadNativeValue(pslILEmit); - EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertWinRTUriToCLRUri(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreManagedValue(pslILEmit); } @@ -5783,8 +5783,8 @@ LocalDesc ILNCCEventArgsMarshaler::GetManagedType() { STANDARD_VM_CONTRACT;; - BaseDomain *pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndNCCEventArgType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsType(); + LoaderAllocator *pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + TypeHandle hndNCCEventArgType = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsType(); return LocalDesc(hndNCCEventArgType); // System.Collections.Specialized.NotifyCollectionChangedEventArgs } @@ -5798,11 +5798,11 @@ bool ILNCCEventArgsMarshaler::NeedsClearNative() // Note that this method expects the CLR NotifyCollectionChangedEventArgs on top of the evaluation stack and // leaves the WinRT NotifyCollectionChangedEventArgs IP there. //static -void ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream *pslILEmit, BaseDomain *pDomain) +void ILNCCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream *pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsToWinRTNCCEventArgsMD(); + MethodDesc *pConvertMD = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemNCCEventArgsToWinRTNCCEventArgsMD(); // IntPtr System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventArgsMarshaler.ConvertToNative(NotifyCollectionChangedEventArgs) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5813,18 +5813,18 @@ void ILNCCEventArgsMarshaler::EmitConvertContentsCLRToNative(ILCodeStream *pslIL STANDARD_VM_CONTRACT; EmitLoadManagedValue(pslILEmit); - EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreNativeValue(pslILEmit); } // Note that this method expects the WinRT NotifyCollectionChangedEventArgs on top of the evaluation stack and // leaves the CLR NotifyCollectionChangedEventArgs there. //static -void ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain) +void ILNCCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTNCCEventArgsToSystemNCCEventArgsMD(); + MethodDesc *pConvertMD = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTNCCEventArgsToSystemNCCEventArgsMD(); // NotifyCollectionChangedEventArgs System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventArgsMarshaler.ConvertToManaged(IntPtr) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5835,7 +5835,7 @@ void ILNCCEventArgsMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslIL STANDARD_VM_CONTRACT; EmitLoadNativeValue(pslILEmit); - EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreManagedValue(pslILEmit); } @@ -5859,8 +5859,8 @@ LocalDesc ILPCEventArgsMarshaler::GetManagedType() { STANDARD_VM_CONTRACT;; - BaseDomain *pDomain = m_pargs->m_pMarshalInfo->GetModule()->GetDomain(); - TypeHandle hndPCEventArgType = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsType(); + LoaderAllocator* pLoader = m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator(); + TypeHandle hndPCEventArgType = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsType(); return LocalDesc(hndPCEventArgType); // System.ComponentModel.PropertyChangedEventArgs } @@ -5874,11 +5874,11 @@ bool ILPCEventArgsMarshaler::NeedsClearNative() // Note that this method expects the CLR PropertyChangedEventArgs on top of the evaluation stack and // leaves the WinRT PropertyChangedEventArgs IP there. //static -void ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream *pslILEmit, BaseDomain *pDomain) +void ILPCEventArgsMarshaler::EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream *pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsToWinRTPCEventArgsMD(); + MethodDesc *pConvertMD = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetSystemPCEventArgsToWinRTPCEventArgsMD(); // IntPtr System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventArgsMarshaler.ConvertToNative(PropertyChangedEventArgs) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5889,18 +5889,18 @@ void ILPCEventArgsMarshaler::EmitConvertContentsCLRToNative(ILCodeStream *pslILE STANDARD_VM_CONTRACT; EmitLoadManagedValue(pslILEmit); - EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertCLREventArgsToWinRTEventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreNativeValue(pslILEmit); } // Note that this method expects the WinRT PropertyChangedEventArgs on top of the evaluation stack and // leaves the CLR PropertyChangedEventArgs there. //static -void ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain) +void ILPCEventArgsMarshaler::EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader) { STANDARD_VM_CONTRACT; - MethodDesc *pConvertMD = pDomain->GetLoaderAllocator()->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTPCEventArgsToSystemPCEventArgsMD(); + MethodDesc *pConvertMD = pLoader->GetMarshalingData()->GetEventArgsMarshalingInfo()->GetWinRTPCEventArgsToSystemPCEventArgsMD(); // PropertyChangedEventArgs System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventArgsMarshaler.ConvertToManaged(IntPtr) pslILEmit->EmitCALL(pslILEmit->GetToken(pConvertMD), 1, 1); @@ -5911,7 +5911,7 @@ void ILPCEventArgsMarshaler::EmitConvertContentsNativeToCLR(ILCodeStream* pslILE STANDARD_VM_CONTRACT; EmitLoadNativeValue(pslILEmit); - EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetDomain()); + EmitConvertWinRTEventArgsToCLREventArgs(pslILEmit, m_pargs->m_pMarshalInfo->GetModule()->GetLoaderAllocator()); EmitStoreManagedValue(pslILEmit); } diff --git a/src/vm/ilmarshalers.h b/src/vm/ilmarshalers.h index 6a67bf686e47..67318c0af91c 100644 --- a/src/vm/ilmarshalers.h +++ b/src/vm/ilmarshalers.h @@ -3235,8 +3235,8 @@ class ILUriMarshaler : public ILMarshaler c_CLRSize = sizeof(OBJECTREF), }; - static void EmitConvertCLRUriToWinRTUri(ILCodeStream* pslILEmit, BaseDomain* pDomain); - static void EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, BaseDomain* pDomain); + static void EmitConvertCLRUriToWinRTUri(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); + static void EmitConvertWinRTUriToCLRUri(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); protected: virtual LocalDesc GetNativeType(); @@ -3259,8 +3259,8 @@ class ILNCCEventArgsMarshaler : public ILMarshaler c_CLRSize = sizeof(OBJECTREF), }; - static void EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain); - static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain); + static void EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); + static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); protected: virtual LocalDesc GetNativeType(); @@ -3283,8 +3283,8 @@ class ILPCEventArgsMarshaler : public ILMarshaler c_CLRSize = sizeof(OBJECTREF), }; - static void EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain); - static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, BaseDomain* pDomain); + static void EmitConvertCLREventArgsToWinRTEventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); + static void EmitConvertWinRTEventArgsToCLREventArgs(ILCodeStream* pslILEmit, LoaderAllocator* pLoader); protected: virtual LocalDesc GetNativeType(); From b37e42ca16a97958647186680fadbe8a6fdc8946 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 3 Jan 2019 10:06:54 -0800 Subject: [PATCH 14/17] Change to m_InteropDataCrst since this EEMarshallingData can be used in preemptive GC mode. --- src/vm/loaderallocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/loaderallocator.cpp b/src/vm/loaderallocator.cpp index 8154afda2478..1f76992145e7 100644 --- a/src/vm/loaderallocator.cpp +++ b/src/vm/loaderallocator.cpp @@ -1647,7 +1647,7 @@ EEMarshalingData *LoaderAllocator::GetMarshalingData() if (!m_pMarshalingData) { - m_pMarshalingData = new (GetLowFrequencyHeap()) EEMarshalingData(this, &m_crstLoaderAllocator); + m_pMarshalingData = new (GetLowFrequencyHeap()) EEMarshalingData(this, &m_InteropDataCrst); } } From fc192a47f70d6442fe480a8ff56afa214ca973d4 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 3 Jan 2019 12:15:00 -0800 Subject: [PATCH 15/17] Always init m_InteropDataCrst (since it's used by EEMarshallingData as well as COM). --- src/vm/loaderallocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/loaderallocator.cpp b/src/vm/loaderallocator.cpp index 1f76992145e7..c092cd297e8d 100644 --- a/src/vm/loaderallocator.cpp +++ b/src/vm/loaderallocator.cpp @@ -1071,8 +1071,8 @@ void LoaderAllocator::Init(BaseDomain *pDomain, BYTE *pExecutableHeapMemory) m_pDomain = pDomain; m_crstLoaderAllocator.Init(CrstLoaderAllocator, (CrstFlags)CRST_UNSAFE_COOPGC); -#ifdef FEATURE_COMINTEROP m_InteropDataCrst.Init(CrstInteropData, CRST_REENTRANCY); +#ifdef FEATURE_COMINTEROP m_ComCallWrapperCrst.Init(CrstCOMCallWrapper); #endif From 95439739a02f6efbffc5cc4f51500ccf0b3f3681 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Jan 2019 10:26:29 -0800 Subject: [PATCH 16/17] PR Feedback. --- src/vm/loaderallocator.hpp | 3 +++ .../ConflictingNames/CustomMarshaler.cs | 4 ++++ .../ConflictingNames/SameNameDifferentAssembly.cs | 14 +++++++++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/vm/loaderallocator.hpp b/src/vm/loaderallocator.hpp index 0a70dc681490..369fe97023c5 100644 --- a/src/vm/loaderallocator.hpp +++ b/src/vm/loaderallocator.hpp @@ -556,9 +556,12 @@ class LoaderAllocator // basis. EEMarshalingData *GetMarshalingData(); +private: // Deletes marshaling data at shutdown (which contains cached factories that needs to be released) void DeleteMarshalingData(); +public: + #ifdef FEATURE_COMINTEROP ComCallWrapperCache * GetComCallWrapperCache(); diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs index 8122a0378bf4..506f8b21810f 100644 --- a/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/CustomMarshaler.cs @@ -30,6 +30,10 @@ public void CleanUpManagedData(object ManagedObj) { } public static ICustomMarshaler GetInstance(string cookie) => new WrappedStringCustomMarshaler(); } +// Use an ifdef here to give us two separate public API surfaces to call while allowing us to have the same implementation code +// as well as allowing us to share the custom marshaler implementations above. +// If we wanted to add more tests here, we would want to put the public API surface in the namespace and the private +// details and marshalers in the global scope as done above. #if CUSTOMMARSHALERS2 namespace CustomMarshalers2 #else diff --git a/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs index 836e23e683e2..ce9113438cdb 100644 --- a/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs +++ b/tests/src/Interop/ICustomMarshaler/ConflictingNames/SameNameDifferentAssembly.cs @@ -13,8 +13,16 @@ public class RunInALC { public static int Main(string[] args) { - Assert.AreEqual(123, new CustomMarshalers.CustomMarshalerTest().ParseInt("123")); - Assert.AreEqual(123, new CustomMarshalers2.CustomMarshalerTest().ParseInt("123")); - return 100; + try + { + Assert.AreEqual(123, new CustomMarshalers.CustomMarshalerTest().ParseInt("123")); + Assert.AreEqual(123, new CustomMarshalers2.CustomMarshalerTest().ParseInt("123")); + return 100; + } + catch (Exception e) + { + Console.WriteLine(e); + return 101; + } } } From 24d32a0fe7096462f0793ad61389b1edd8036fd0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Jan 2019 11:06:47 -0800 Subject: [PATCH 17/17] Remove extraneous inlines. --- src/vm/custommarshalerinfo.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vm/custommarshalerinfo.h b/src/vm/custommarshalerinfo.h index fe67da3cc70b..95390f292757 100644 --- a/src/vm/custommarshalerinfo.h +++ b/src/vm/custommarshalerinfo.h @@ -130,32 +130,32 @@ class EECMHelperHashtableKey LIMITED_METHOD_CONTRACT; } - inline DWORD GetMarshalerTypeNameByteCount() const + DWORD GetMarshalerTypeNameByteCount() const { LIMITED_METHOD_CONTRACT; return m_cMarshalerTypeNameBytes; } - inline LPCSTR GetMarshalerTypeName() const + LPCSTR GetMarshalerTypeName() const { LIMITED_METHOD_CONTRACT; return m_strMarshalerTypeName; } - inline LPCSTR GetCookieString() const + LPCSTR GetCookieString() const { LIMITED_METHOD_CONTRACT; return m_strCookie; } - inline ULONG GetCookieStringByteCount() const + ULONG GetCookieStringByteCount() const { LIMITED_METHOD_CONTRACT; return m_cCookieStrBytes; } - inline Instantiation GetMarshalerInstantiation() const + Instantiation GetMarshalerInstantiation() const { LIMITED_METHOD_CONTRACT; return m_Instantiation; } - inline Assembly* GetInvokingAssembly() const + Assembly* GetInvokingAssembly() const { LIMITED_METHOD_CONTRACT; return m_invokingAssembly;