1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
5 using System.Collections.Generic;
6 using System.Diagnostics;
9 using System.Runtime.InteropServices;
11 internal class Program
13 public static int CompareDLLs(string folder1, string folder2)
17 string superIlcFolder1 = Directory.GetDirectories(folder1, "CPAOT*").First();
18 string superIlcFolder2 = Directory.GetDirectories(folder2, "CPAOT*").First();
20 // Check for files that failed compilation with one of the seeds but not the other
21 HashSet<string> uniqueFilenames = new HashSet<string>(Directory.GetFiles(superIlcFolder1, "*.dll").Select(Path.GetFileName));
22 uniqueFilenames.SymmetricExceptWith(Directory.GetFiles(superIlcFolder2, "*.dll").Select(Path.GetFileName));
23 foreach (string uniqueFilename in uniqueFilenames)
25 Console.WriteLine($"{uniqueFilename} was found in only one of the output folders.");
29 foreach (string filename in Directory.GetFiles(superIlcFolder1, "*.dll").Select(Path.GetFileName))
31 if (uniqueFilenames.Contains(filename))
34 byte[] file1 = File.ReadAllBytes(Path.Combine(superIlcFolder1, Path.GetFileName(filename)));
35 byte[] file2 = File.ReadAllBytes(Path.Combine(superIlcFolder2, Path.GetFileName(filename)));
37 if (file1.Length != file2.Length)
39 Console.WriteLine(filename);
40 Console.WriteLine($"Expected ReadyToRun'd files to be identical but they have different sizes ({file1.Length} and {file2.Length})");
45 int byteDifferentCount = 0;
46 for (int i = 0; i < file1.Length; ++i)
48 if (file1[i] != file2[i])
54 if (byteDifferentCount > 0)
57 Console.WriteLine($"Error: Found {byteDifferentCount} different bytes in {filename}");
61 Console.WriteLine($"Files of length {file1.Length} were identical.");
66 public static string OSExeSuffix(string path) => (OperatingSystem.IsWindows() ? path + ".exe" : path);
68 private static void PrepareCompilationInputFolder(string coreRootFolder, string compilationInputFolder)
70 if (Directory.Exists(compilationInputFolder))
72 Directory.Delete(compilationInputFolder, true);
74 Directory.CreateDirectory(compilationInputFolder);
76 CopyDeterminismTestAssembly(coreRootFolder, compilationInputFolder, "System.Private.CoreLib.dll");
79 private static void CopyDeterminismTestAssembly(string coreRootFolder, string compilationInputFolder, string fileName)
81 File.Copy(Path.Combine(coreRootFolder, fileName), Path.Combine(compilationInputFolder, fileName));
84 public static bool CompileWithSeed(int seed, string coreRootPath, string compilationInputFolder, string outDir)
86 string superIlcPath = Path.Combine(coreRootPath, "R2RTest", "R2RTest.dll");
87 string coreRunPath = Path.Combine(coreRootPath, OSExeSuffix("corerun"));
89 Console.WriteLine($"================================== Compiling with seed {seed} ==================================");
90 Environment.SetEnvironmentVariable("CoreRT_DeterminismSeed", seed.ToString());
91 if (Directory.Exists(outDir))
93 Directory.Delete(outDir, true);
95 Directory.CreateDirectory(outDir);
97 string crossgen2OptsR2RTest = Environment.GetEnvironmentVariable("CrossGen2OptionsR2RTest");
99 ProcessStartInfo processStartInfo = new ProcessStartInfo(coreRunPath, $"{superIlcPath} compile-directory -cr {coreRootPath} -in {compilationInputFolder} {crossgen2OptsR2RTest} --nojit --noexe --large-bubble --release --nocleanup -out {outDir}");
100 var process = Process.Start(processStartInfo);
101 process.WaitForExit();
102 if (process.ExitCode != 0)
104 Console.WriteLine($"Compilation failed. {processStartInfo.FileName} {processStartInfo.Arguments} failed with exit code {process.ExitCode}");
106 return 0 == process.ExitCode;
109 public static int Main()
111 string coreRootPath = Environment.GetEnvironmentVariable("CORE_ROOT");
112 string compilationInputFolder = "TestAssemblies";
113 PrepareCompilationInputFolder(coreRootPath, compilationInputFolder);
114 if (!CompileWithSeed(1, coreRootPath, compilationInputFolder, "seed1"))
116 if (!CompileWithSeed(2, coreRootPath, compilationInputFolder, "seed2"))
118 return CompareDLLs("seed1", "seed2");