From 4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Mon, 25 Nov 2019 17:17:36 -0800 Subject: [PATCH] Fix setting of DllImportResolver in crossgen2. (#167) After change https://github.com/dotnet/coreclr/pull/27068 we are creating multiple instances of CorInfoImpl. That broke the scenario when jitpath is set: we are calling NativeLibrary.SetDllImportResolver more than once, which results in `System.InvalidOperationException: A resolver is already set for the assembly.` This fix ensures that we call NativeLibrary.SetDllImportResolver at most once. This change also ensures that we set the resolver before attempting to load the jit. That fixes the --jitpath scenario on Linux. --- .../tools/Common/JitInterface/CorInfoImpl.cs | 47 +++++++------------ .../Compiler/ReadyToRunCodegenCompilation.cs | 4 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 4 +- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index a330169175866..f9fe7172fa8b2 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -58,8 +58,6 @@ private enum ImageFileMachine private ExceptionDispatchInfo _lastException; - private static bool s_jitRegistered = RegisterJITModule(); - [DllImport(JitLibrary)] private extern static IntPtr PAL_RegisterModule([MarshalAs(UnmanagedType.LPUTF8Str)] string moduleName); @@ -113,50 +111,41 @@ private IntPtr AllocException(Exception ex) [DllImport(JitSupportLibrary)] private extern static char* GetExceptionMessage(IntPtr obj); - private JitConfigProvider _jitConfig; + private static JitConfigProvider s_jitConfig; private readonly UnboxingMethodDescFactory _unboxingThunkFactory; - private static bool RegisterJITModule() + public static void RegisterJITModule(JitConfigProvider jitConfig) { - if ((Environment.OSVersion.Platform == PlatformID.Unix) || (Environment.OSVersion.Platform == PlatformID.MacOSX)) + s_jitConfig = jitConfig; + if (jitConfig.JitPath != null) { - return PAL_RegisterModule("libclrjitilc.so") != (IntPtr)1; + NativeLibrary.SetDllImportResolver(typeof(CorInfoImpl).Assembly, JitLibraryResolver); } - else + + if (Environment.OSVersion.Platform == PlatformID.Unix) { - return true; + // TODO: The PAL_RegisterModule export should be removed from the JIT + // and the call to PAL_InitializeDLL should be moved to jitStartup. + // https://github.com/dotnet/coreclr/issues/27941 + PAL_RegisterModule("libclrjitilc.so"); } + + jitStartup(GetJitHost(jitConfig.UnmanagedInstance)); } - private IntPtr JitLibraryResolver(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath) + private static IntPtr JitLibraryResolver(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath) { IntPtr libHandle = IntPtr.Zero; if (libraryName == JitLibrary) { - libHandle = NativeLibrary.Load(_jitConfig.JitPath, assembly, searchPath); + libHandle = NativeLibrary.Load(s_jitConfig.JitPath, assembly, searchPath); } return libHandle; } - public CorInfoImpl(JitConfigProvider jitConfig) + public CorInfoImpl() { - // - // Global initialization - // - _jitConfig = jitConfig; - if (!s_jitRegistered) - { - throw new IOException("Failed to register JIT"); - } - - if (_jitConfig.JitPath != null) - { - NativeLibrary.SetDllImportResolver(typeof(CorInfoImpl).Assembly, JitLibraryResolver); - } - - jitStartup(GetJitHost(_jitConfig.UnmanagedInstance)); - _jit = getJit(); if (_jit == IntPtr.Zero) { @@ -264,7 +253,7 @@ private void PublishCode() var relocs = _relocs.ToArray(); Array.Sort(relocs, (x, y) => (x.Offset - y.Offset)); - int alignment = _jitConfig.HasFlag(CorJitFlag.CORJIT_FLAG_SIZE_OPT) ? + int alignment = s_jitConfig.HasFlag(CorJitFlag.CORJIT_FLAG_SIZE_OPT) ? _compilation.NodeFactory.Target.MinimumFunctionAlignment : _compilation.NodeFactory.Target.OptimumFunctionAlignment; @@ -3032,7 +3021,7 @@ private bool isMethodDefinedInCoreLib() private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes) { // Read the user-defined configuration options. - foreach (var flag in _jitConfig.Flags) + foreach (var flag in s_jitConfig.Flags) flags.Set(flag); // Set the rest of the flags that don't make sense to expose publically. diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index e9cfb44703e4a..484ed7803038e 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -223,6 +223,8 @@ internal ReadyToRunCodegenCompilation( _jitConfigProvider = configProvider; _inputFilePath = inputFilePath; + + CorInfoImpl.RegisterJITModule(configProvider); } public override void Compile(string outputFile) @@ -282,7 +284,7 @@ protected override void ComputeDependencyNodeDependencies(List new CorInfoImpl(this, _jitConfigProvider)); + CorInfoImpl corInfoImpl = cwt.GetValue(Thread.CurrentThread, thread => new CorInfoImpl(this)); corInfoImpl.CompileMethod(methodCodeNodeNeedingCode); } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 6b0aa4658a1a5..96020e1eaf654 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -140,8 +140,8 @@ unsafe partial class CorInfoImpl private OffsetMapping[] _debugLocInfos; private NativeVarInfo[] _debugVarInfos; - public CorInfoImpl(ReadyToRunCodegenCompilation compilation, JitConfigProvider jitConfig) - : this(jitConfig) + public CorInfoImpl(ReadyToRunCodegenCompilation compilation) + : this() { _compilation = compilation; }