Simplify JIT shutdown logic in crossgen2 (#56687)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Tue, 3 Aug 2021 05:34:45 +0000 (14:34 +0900)
committerGitHub <noreply@github.com>
Tue, 3 Aug 2021 05:34:45 +0000 (14:34 +0900)
There was unanswered comment about thread safety in https://github.com/dotnet/runtime/pull/56187/files#r675461236 so I just decided to fix it myself.

While on it, I simplified shutdown to use `AppDomain.ProcessExit`.

I'm not sure `AppDomain.UnhandledException` is needed but the original code had this in a `finally`.

The better fix would be to allow JIT to be initialized right before we start a compilation and shut down after, but that would require no process wide state in the JIT. As it stands now, JIT is once-per-process-global.

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
src/coreclr/tools/aot/crossgen2/Program.cs

index ff268b7..d5dc33b 100644 (file)
@@ -79,32 +79,26 @@ namespace Internal.JitInterface
             [DllImport(JitLibrary)]
             private extern static IntPtr getJit();
 
-            public static IntPtr Get()
-            {
-                if (s_jit != IntPtr.Zero)
-                {
-                    return s_jit;
-                }
-
-                lock(typeof(JitPointerAccessor))
-                {
-                    s_jit = getJit();
-                    return s_jit;
-                }
-            }
-
             [DllImport(JitSupportLibrary)]
             private extern static CorJitResult JitProcessShutdownWork(IntPtr jit);
 
-            public static void ShutdownJit()
+            static JitPointerAccessor()
             {
+                s_jit = getJit();
+
                 if (s_jit != IntPtr.Zero)
                 {
-                    JitProcessShutdownWork(s_jit);
+                    AppDomain.CurrentDomain.ProcessExit += (_, _) => JitProcessShutdownWork(s_jit);
+                    AppDomain.CurrentDomain.UnhandledException += (_, _) => JitProcessShutdownWork(s_jit);
                 }
             }
 
-            private static IntPtr s_jit;
+            public static IntPtr Get()
+            {
+                return s_jit;
+            }
+
+            private static readonly IntPtr s_jit;
         }
 
         [DllImport(JitLibrary)]
@@ -159,11 +153,6 @@ namespace Internal.JitInterface
             jitStartup(GetJitHost(JitConfigProvider.Instance.UnmanagedInstance));
         }
 
-        public static void ShutdownJit()
-        {
-            JitPointerAccessor.ShutdownJit();
-        }
-
         public CorInfoImpl()
         {
             _jit = JitPointerAccessor.Get();
index 4b5d4a7..c1207a4 100644 (file)
@@ -65,12 +65,6 @@ namespace ILCompiler
             ((ReadyToRunCompilerContext)context).SetCompilationGroup(group);
         }
 
-        // Shutdown the Jit if it has been loaded. This must only be called once per process
-        public static void ShutdownJit()
-        {
-            CorInfoImpl.ShutdownJit();
-        }
-
         public override CompilationBuilder UseBackendOptions(IEnumerable<string> options)
         {
             var builder = new ArrayBuilder<KeyValuePair<string, string>>();
index d541851..afae84f 100644 (file)
@@ -989,14 +989,7 @@ namespace ILCompiler
 #if DEBUG
             try
             {
-                try
-                {
-                    return new Program().Run(args);
-                }
-                finally
-                {
-                    ReadyToRunCodegenCompilationBuilder.ShutdownJit();
-                }
+                return new Program().Run(args);
             }
             catch (CodeGenerationFailedException ex) when (DumpReproArguments(ex))
             {
@@ -1005,14 +998,7 @@ namespace ILCompiler
 #else
             try
             {
-                try
-                {
-                    return new Program().Run(args);
-                }
-                finally
-                {
-                    ReadyToRunCodegenCompilationBuilder.ShutdownJit();
-                }
+                return new Program().Run(args);
             }
             catch (Exception e)
             {