Fix setting of DllImportResolver in crossgen2. (#167)
authorEugene Rozenfeld <erozen@microsoft.com>
Tue, 26 Nov 2019 01:17:36 +0000 (17:17 -0800)
committerGitHub <noreply@github.com>
Tue, 26 Nov 2019 01:17:36 +0000 (17:17 -0800)
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.

src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs

index a330169..f9fe717 100644 (file)
@@ -58,8 +58,6 @@ namespace Internal.JitInterface
 
         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 @@ namespace Internal.JitInterface
         [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 @@ namespace Internal.JitInterface
             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 @@ namespace Internal.JitInterface
         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.
index e9cfb44..484ed78 100644 (file)
@@ -223,6 +223,8 @@ namespace ILCompiler
             _jitConfigProvider = configProvider;
 
             _inputFilePath = inputFilePath;
+
+            CorInfoImpl.RegisterJITModule(configProvider);
         }
 
         public override void Compile(string outputFile)
@@ -282,7 +284,7 @@ namespace ILCompiler
                     {
                         using (PerfEventSource.StartStopEvents.JitMethodEvents())
                         {
-                            CorInfoImpl corInfoImpl = cwt.GetValue(Thread.CurrentThread, thread => new CorInfoImpl(this, _jitConfigProvider));
+                            CorInfoImpl corInfoImpl = cwt.GetValue(Thread.CurrentThread, thread => new CorInfoImpl(this));
                             corInfoImpl.CompileMethod(methodCodeNodeNeedingCode);
                         }
                     }
index 6b0aa46..96020e1 100644 (file)
@@ -140,8 +140,8 @@ namespace Internal.JitInterface
         private OffsetMapping[] _debugLocInfos;
         private NativeVarInfo[] _debugVarInfos;
 
-        public CorInfoImpl(ReadyToRunCodegenCompilation compilation, JitConfigProvider jitConfig)
-            : this(jitConfig)
+        public CorInfoImpl(ReadyToRunCodegenCompilation compilation)
+            : this()
         {
             _compilation = compilation;
         }