diff --git a/NuGet.Config b/NuGet.Config
index 01c661c5..c187b39a 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -3,9 +3,7 @@
-
-
-
+
diff --git a/doc/diffs.md b/doc/diffs.md
index 65985405..d14d3c2b 100644
--- a/doc/diffs.md
+++ b/doc/diffs.md
@@ -47,8 +47,8 @@ To build jitutils not using the bootstrap script:
* Run `build.{cmd,sh}`.
By default the script just builds the tools and does not publish them in a separate directory.
-To publish the utilities add the '-p' flag which publishes each utility to the ./bin directory
-in the root of the repo. Additionally, to download the default set of framework assemblies
+To publish the utilities add the '-p' flag which publishes each utility to the ./bin directory
+in the root of the repo. Additionally, to download the default set of framework assemblies
that can be used for generating asm diffs, add '-f'.
```
@@ -66,23 +66,23 @@ build.sh [-b ] [-f] [-h] [-p] [-t ]
By default, assembly code output (aka, "dasm") is generated by running crossgen
with a specified JIT to compile a specified set of assemblies, by setting the
following JIT environment variables to generate the output:
-* `COMPlus_NgenDisasm`
-* `COMPlus_NgenUnwindDump`
-* `COMPlus_NgenEHDump`
-* `COMPlus_JitDiffableDasm`
-* optionally, `COMPlus_NgenGCDump`
+* `DOTNET_NgenDisasm`
+* `DOTNET_NgenUnwindDump`
+* `DOTNET_NgenEHDump`
+* `DOTNET_JitDiffableDasm`
+* optionally, `DOTNET_NgenGCDump`
Generating "diffs" involves generating assembly code output for both a baseline
and a "diff" JIT, and comparing the results.
Passing the `--pmi` option to `jit-diffs` will instead use reflection to jit each
method in the assembly, setting these options:
-* `COMPlus_JitDisasm`
-* `COMPlus_JitUnwindDump`
-* `COMPlus_JitEHDump`
-* `COMPlus_JitDiffableDasm`
-* `COMPlus_JitDisasmAssemblies`
-* optionally, `COMPlus_JitGCDump`
+* `DOTNET_JitDisasm`
+* `DOTNET_JitUnwindDump`
+* `DOTNET_JitEHDump`
+* `DOTNET_JitDiffableDasm`
+* `DOTNET_JitDisasmAssemblies`
+* optionally, `DOTNET_JitGCDump`
## What can jit-diff produce asm diffs for?
@@ -168,7 +168,7 @@ The "jit-diff diff" command has this help message:
[-t ] [-c] [-f] [--benchmarks] [--tests] [--gcinfo] [-v] [--core_root ]
[--test_root ] [--base_root ] [--diff_root ] [--arch ]
[--build ] [--altjit ]
-
+
-b, --base [arg] The base compiler directory or tag. Will use crossgen or clrjit from this
directory.
-d, --diff [arg] The diff compiler directory or tag. Will use crossgen or clrjit from this
@@ -195,35 +195,35 @@ The "jit-diff diff" command has this help message:
--altjit If set, the name of the altjit to use (e.g., clrjit_win_arm64_x64.dll).
--pmi Generate diffs via jitting instead of running crossgen
--assembly Look at diffs for methods in the specified assembly
-
+
Examples:
-
+
jit-diff diff --output c:\diffs --corelib --core_root c:\coreclr\bin\tests\windows.x64.Release\Tests\Core_Root --base c:\coreclr_base\bin\Product
\windows.x64.Checked --diff c:\coreclr\bin\Product\windows.x86.Checked
Generate diffs of System.Private.CoreLib.dll by specifying baseline and
diff compiler directories explicitly.
-
+
jit-diff diff --output c:\diffs --base c:\coreclr_base\bin\Product\windows.x64.Checked --diff
If run within the c:\coreclr git clone of dotnet/coreclr, does the same
as the prevous example, using defaults.
-
+
jit-diff diff --output c:\diffs --base --base_root c:\coreclr_base --diff
Does the same as the prevous example, using -base_root to find the base
directory (if run from c:\coreclr tree).
-
+
jit-diff diff --base --diff
Does the same as the prevous example (if run from c:\coreclr tree), but uses
default c:\coreclr\bin\diffs output directory, and `base_root` must be specified
in the config.json file in the directory pointed to by the JIT_UTILS_ROOT
environment variable.
-
+
jit-diff diff --diff
Only generates asm using the diff JIT -- does not generate asm from a baseline compiler --
using all computed defaults.
-
+
jit-diff diff --diff --arch x86
Generate diffs, but for x86, even if there is an x64 compiler available.
-
+
jit-diff diff --diff --build Debug
Generate diffs, but using a Debug build, even if there is a Checked build available.
```
@@ -380,7 +380,7 @@ Or, disassemble the jitted code for all the methods in `mytest.exe`:
```
Note this latter run should produce similar disassembly as running `mytest.exe` via
-corerun (with appropriate COMPlus flags set) for the methods that are executed
+corerun (with appropriate DOTNET_ flags set) for the methods that are executed
during the run. But `jit-diff diff -pmi` will attempt to show code generated for
all methods, executed or not. And it also works on libraries which are not
directly executable on their own. So PMI offers a potentially faster and more
diff --git a/src/AnalyzeAsm/AnalyzeAsm.csproj b/src/AnalyzeAsm/AnalyzeAsm.csproj
index f730ef52..74954604 100644
--- a/src/AnalyzeAsm/AnalyzeAsm.csproj
+++ b/src/AnalyzeAsm/AnalyzeAsm.csproj
@@ -2,11 +2,7 @@
Exe
- netcoreapp3.1
+ net6.0
-
-
-
-
diff --git a/src/AnalyzeAsm/OccurenceInfo.cs b/src/AnalyzeAsm/OccurenceInfo.cs
index 4106b03f..a41e0424 100644
--- a/src/AnalyzeAsm/OccurenceInfo.cs
+++ b/src/AnalyzeAsm/OccurenceInfo.cs
@@ -2,12 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
+using System.Text.Json;
using MethodDB = System.Collections.Generic.Dictionary>>;
namespace AnalyzeAsm
@@ -135,7 +135,7 @@ private static MethodIndex CreateIndex(string folderPath)
index.AddFile(dasmFile);
}
- string contents = JsonConvert.SerializeObject(index);
+ string contents = JsonSerializer.Serialize(index);
File.WriteAllText(Path.Combine(folderPath, indexFileName), contents);
stopWatch.Stop();
@@ -158,7 +158,7 @@ private static bool TryGetIndex(string folderPath, out MethodIndex index, bool d
return false;
}
- index = JsonConvert.DeserializeObject(File.ReadAllText(indexFilePath));
+ index = JsonSerializer.Deserialize(File.ReadAllText(indexFilePath));
var expectedExeTimeStamp = index.LastModifiedTimeOfExe;
var actualExeTimeStamp = File.GetLastWriteTimeUtc(Assembly.GetExecutingAssembly().Location);
diff --git a/src/AnalyzeAsm/README.md b/src/AnalyzeAsm/README.md
index faa76417..04dd5b71 100644
--- a/src/AnalyzeAsm/README.md
+++ b/src/AnalyzeAsm/README.md
@@ -1,10 +1,10 @@
Notes:
-* The code in `Program.cs` has **lot of redundant code**. Most of the methods are copied from previous methods with little tweak.
+* The code in `Program.cs` has **lot of redundant code**. Most of the methods are copied from previous methods with little tweak.
* All the methods rely on `ngen_arm64.txt` / `ngen_amd64.txt` file that are produced by doing the following:
- * `set COMPlus_NGenDisasm=1`
- * Running `build-test.cmd crossgen > ngen_arm64.txt`
-* The path locations of these files are hardcoded too.
+ * `set DOTNET_NGenDisasm=1`
+ * Running `build-test.cmd crossgen > ngen_arm64.txt`
+* The path locations of these files are hardcoded too.
`FindLdrGroups_1()` finds patterns:
diff --git a/src/cijobs/cijobs.cs b/src/cijobs/cijobs.cs
index d7362109..81918adf 100755
--- a/src/cijobs/cijobs.cs
+++ b/src/cijobs/cijobs.cs
@@ -23,17 +23,17 @@
using System;
-using System.IO;
using System.Collections.Generic;
+using System.CommandLine;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
+using System.Text.Json;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
-using System.CommandLine;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.IO.Compression;
-using Newtonsoft.Json;
namespace ManagedCodeGen
{
@@ -386,7 +386,7 @@ string productString
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
- var productJobs = JsonConvert.DeserializeObject(json);
+ var productJobs = JsonSerializer.Deserialize(json);
return productJobs.jobs;
}
else
@@ -414,7 +414,7 @@ var messageString
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
- var jobBuilds = JsonConvert.DeserializeObject(json);
+ var jobBuilds = JsonSerializer.Deserialize(json);
if (lastSuccessfulBuild)
{
@@ -492,7 +492,7 @@ public async Task GetJobBuildInfo(string repoName, string branchName,
if (response.IsSuccessStatusCode)
{
var buildInfoJson = await response.Content.ReadAsStringAsync();
- var info = JsonConvert.DeserializeObject(buildInfoJson);
+ var info = JsonSerializer.Deserialize(buildInfoJson);
return info;
}
else
diff --git a/src/jit-analyze/jit-analyze.cs b/src/jit-analyze/jit-analyze.cs
index c50ed591..66f008a7 100644
--- a/src/jit-analyze/jit-analyze.cs
+++ b/src/jit-analyze/jit-analyze.cs
@@ -3,17 +3,20 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Diagnostics;
+using System.Collections.Generic;
using System.CommandLine;
+using System.Diagnostics;
+using System.Globalization;
using System.IO;
-using System.Collections.Generic;
using System.Linq;
-using System.Text.RegularExpressions;
-using Newtonsoft.Json;
-using System.Text;
-using System.Runtime.CompilerServices;
-using System.Globalization;
using System.Reflection;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml;
namespace ManagedCodeGen
{
@@ -397,7 +400,7 @@ static MetricCollection()
}
}
- [JsonProperty()]
+ [JsonInclude]
private Metric[] metrics;
public MetricCollection()
@@ -1185,7 +1188,7 @@ public static StringBuilder GenerateJson(IEnumerable compareList)
{
StringBuilder fileContents = new StringBuilder();
- fileContents.AppendLine(JsonConvert.SerializeObject(compareList.Where(file => !file.deltaMetrics.IsZero()), Formatting.Indented));
+ fileContents.AppendLine(JsonSerializer.Serialize(compareList.Where(file => !file.deltaMetrics.IsZero()), new JsonSerializerOptions { WriteIndented = true }));
return fileContents;
}
diff --git a/src/jit-dasm-pmi/jit-dasm-pmi.cs b/src/jit-dasm-pmi/jit-dasm-pmi.cs
index aa40ad70..00d6e9c5 100644
--- a/src/jit-dasm-pmi/jit-dasm-pmi.cs
+++ b/src/jit-dasm-pmi/jit-dasm-pmi.cs
@@ -24,7 +24,7 @@
namespace ManagedCodeGen
{
- // Define options to be parsed
+ // Define options to be parsed
public class Config
{
private ArgumentSyntax _syntaxResult;
@@ -481,10 +481,10 @@ void AppendEnvironmentVariableToPmiEnv(string varName, string varValue)
}
}
- // Pick up ambient COMPlus settings.
+ // Pick up ambient DOTNET settings.
foreach (string envVar in Environment.GetEnvironmentVariables().Keys)
{
- if (envVar.IndexOf("COMPlus_") == 0)
+ if (envVar.IndexOf("DOTNET_") == 0)
{
string value = Environment.GetEnvironmentVariable(envVar);
AppendEnvironmentVariableToPmiEnv(envVar, value);
@@ -492,45 +492,45 @@ void AppendEnvironmentVariableToPmiEnv(string varName, string varValue)
}
// Set up environment do PMI based disasm.
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitDisasm", "*");
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitDisasmAssemblies", Path.GetFileNameWithoutExtension(assembly.Name));
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitUnwindDump", "*");
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitEHDump", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitDisasm", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitDisasmAssemblies", Path.GetFileNameWithoutExtension(assembly.Name));
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitUnwindDump", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitEHDump", "*");
if (!this._config.NoDiffable)
{
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitDiffableDasm", "1");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitDiffableDasm", "1");
}
- AppendEnvironmentVariableToPmiEnv("COMPlus_ReadyToRun", "0");
- AppendEnvironmentVariableToPmiEnv("COMPlus_ZapDisable", "1");
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitEnableNoWayAssert", "1"); // Force noway_assert to generate assert (not fall back to MinOpts).
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitNoForceFallback", "1"); // Don't stress noway fallback path.
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitRequired", "1"); // Force NO_WAY to generate assert. Also generates assert for BADCODE/BADCODE3.
-
+ AppendEnvironmentVariableToPmiEnv("DOTNET_ReadyToRun", "0");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_ZapDisable", "1");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitEnableNoWayAssert", "1"); // Force noway_assert to generate assert (not fall back to MinOpts).
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitNoForceFallback", "1"); // Don't stress noway fallback path.
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitRequired", "1"); // Force NO_WAY to generate assert. Also generates assert for BADCODE/BADCODE3.
+
// We likely don't want tiering enabled, but allow it, if user wants tier0 codegen
- AppendEnvironmentVariableToPmiEnv("COMPlus_TieredCompilation", _config.Tier0 ? "1" : "0");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_TieredCompilation", _config.Tier0 ? "1" : "0");
if (_config.Tier0)
{
// jit all methods at tier0
- AppendEnvironmentVariableToPmiEnv("COMPlus_TC_QuickJitForLoops", "1");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_TC_QuickJitForLoops", "1");
// don't promote any method to tier1
- AppendEnvironmentVariableToPmiEnv("COMPlus_TC_CallCounting", "0");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_TC_CallCounting", "0");
}
if (this.doGCDump)
{
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitGCDump", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitGCDump", "*");
}
if (this.doDebugDump)
{
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitDebugDump", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitDebugDump", "*");
}
if (this._altjit != null)
{
- AppendEnvironmentVariableToPmiEnv("COMPlus_AltJit", "*");
- AppendEnvironmentVariableToPmiEnv("COMPlus_AltJitName", _altjit);
+ AppendEnvironmentVariableToPmiEnv("DOTNET_AltJit", "*");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_AltJitName", _altjit);
const string arm64AsTarget = "_arm64_";
int targetArm64 = _altjit.IndexOf(arm64AsTarget);
@@ -541,7 +541,7 @@ void AppendEnvironmentVariableToPmiEnv(string varName, string varValue)
{
// If this looks like a cross-targeting altjit with a arm64 target and a different host
// then fix the SIMD size.
- AppendEnvironmentVariableToPmiEnv("COMPlus_SIMD16ByteOnly", "1");
+ AppendEnvironmentVariableToPmiEnv("DOTNET_SIMD16ByteOnly", "1");
}
}
}
@@ -565,7 +565,7 @@ void AppendEnvironmentVariableToPmiEnv(string varName, string varValue)
Utility.EnsureParentDirectoryExists(dasmPath);
- AppendEnvironmentVariableToPmiEnv("COMPlus_JitStdOutFile", dasmPath);
+ AppendEnvironmentVariableToPmiEnv("DOTNET_JitStdOutFile", dasmPath);
AddEnvironmentVariable("PMIENV", pmiEnv.ToString());
@@ -610,7 +610,7 @@ void AppendEnvironmentVariableToPmiEnv(string varName, string varValue)
if (hasOutput && File.Exists(logPath) && !File.Exists(dasmPath))
{
- // Looks like the JIT does not support COMPlus_JitStdOutFile so
+ // Looks like the JIT does not support DOTNET_JitStdOutFile so
// the assembly output must be in the log file.
File.Move(logPath, dasmPath);
}
diff --git a/src/jit-dasm/jit-dasm.cs b/src/jit-dasm/jit-dasm.cs
index 7b865fdc..dd258be5 100644
--- a/src/jit-dasm/jit-dasm.cs
+++ b/src/jit-dasm/jit-dasm.cs
@@ -10,7 +10,7 @@
// tools to validate ongoing development.
//
// Scenario 1: Pass A and B compilers to jitdasm. Using the --base and --diff
-// arguments pass two seperate compilers and a passed set of assemblies. This
+// arguments pass two seperate compilers and a passed set of assemblies. This
// is the most common scenario.
//
// Scenario 2: Iterativly call jitdasm with a series of compilers tagging
@@ -37,7 +37,7 @@ public enum CodeGenerator
Crossgen2
}
- // Define options to be parsed
+ // Define options to be parsed
public class Config
{
private ArgumentSyntax _syntaxResult;
@@ -207,7 +207,7 @@ public static int Main(string[] args)
// Builds assemblyInfoList on jitdasm
List assemblyWorkList = GenerateAssemblyWorklist(config);
-
+
// The disasm engine encapsulates a particular set of diffs. An engine is
// produced with a given code generator and assembly list, which then produces
// a set of disasm outputs.
@@ -224,7 +224,7 @@ public static int Main(string[] args)
crossgenDisasm = new Crossgen2DisasmEngine(config.CrossgenExecutable, config, config.RootPath, assemblyWorkList);
}
crossgenDisasm.GenerateAsm();
-
+
if (crossgenDisasm.ErrorCount > 0)
{
Console.Error.WriteLine("{0} errors compiling set.", crossgenDisasm.ErrorCount);
@@ -466,10 +466,10 @@ public void GenerateAsm()
commandArgs.Add(fullPathAssembly);
- // Pick up ambient COMPlus settings.
+ // Pick up ambient DOTNET_ settings.
foreach (string envVar in Environment.GetEnvironmentVariables().Keys)
{
- if (envVar.IndexOf("COMPlus_") == 0)
+ if (envVar.IndexOf("DOTNET_") == 0)
{
string value = Environment.GetEnvironmentVariable(envVar);
AddEnvironmentVariable(envVar, value);
@@ -477,32 +477,32 @@ public void GenerateAsm()
}
// Set up environment do disasm.
- AddEnvironmentVariable("COMPlus_NgenDisasm", "*");
- AddEnvironmentVariable("COMPlus_NgenUnwindDump", "*");
- AddEnvironmentVariable("COMPlus_NgenEHDump", "*");
+ AddEnvironmentVariable("DOTNET_NgenDisasm", "*");
+ AddEnvironmentVariable("DOTNET_NgenUnwindDump", "*");
+ AddEnvironmentVariable("DOTNET_NgenEHDump", "*");
if (!this._config.NoDiffable)
{
- AddEnvironmentVariable("COMPlus_JitDiffableDasm", "1");
+ AddEnvironmentVariable("DOTNET_JitDiffableDasm", "1");
}
- AddEnvironmentVariable("COMPlus_JitEnableNoWayAssert", "1"); // Force noway_assert to generate assert (not fall back to MinOpts).
- AddEnvironmentVariable("COMPlus_JitNoForceFallback", "1"); // Don't stress noway fallback path.
- AddEnvironmentVariable("COMPlus_JitRequired", "1"); // Force NO_WAY to generate assert. Also generates assert for BADCODE/BADCODE3.
+ AddEnvironmentVariable("DOTNET_JitEnableNoWayAssert", "1"); // Force noway_assert to generate assert (not fall back to MinOpts).
+ AddEnvironmentVariable("DOTNET_JitNoForceFallback", "1"); // Don't stress noway fallback path.
+ AddEnvironmentVariable("DOTNET_JitRequired", "1"); // Force NO_WAY to generate assert. Also generates assert for BADCODE/BADCODE3.
if (this.doGCDump)
{
- AddEnvironmentVariable("COMPlus_NgenGCDump", "*");
+ AddEnvironmentVariable("DOTNET_NgenGCDump", "*");
}
if (this.doDebugDump)
{
- AddEnvironmentVariable("COMPlus_NgenDebugDump", "*");
+ AddEnvironmentVariable("DOTNET_NgenDebugDump", "*");
}
if (this._altjit != null)
{
- AddEnvironmentVariable("COMPlus_AltJit", "*");
- AddEnvironmentVariable("COMPlus_AltJitNgen", "*");
- AddEnvironmentVariable("COMPlus_AltJitName", _altjit);
+ AddEnvironmentVariable("DOTNET_AltJit", "*");
+ AddEnvironmentVariable("DOTNET_AltJitNgen", "*");
+ AddEnvironmentVariable("DOTNET_AltJitName", _altjit);
}
string dasmPath = null;
@@ -514,7 +514,7 @@ public void GenerateAsm()
Utility.EnsureParentDirectoryExists(dasmPath);
- AddEnvironmentVariable("COMPlus_JitStdOutFile", dasmPath);
+ AddEnvironmentVariable("DOTNET_JitStdOutFile", dasmPath);
}
if (this.verbose)
@@ -568,7 +568,7 @@ public void GenerateAsm()
if (hasOutput && File.Exists(logPath) && !File.Exists(dasmPath))
{
- // Looks like the JIT does not support COMPlus_JitStdOutFile so
+ // Looks like the JIT does not support DOTNET_JitStdOutFile so
// the assembly output must be in the log file.
File.Move(logPath, dasmPath);
}
@@ -714,8 +714,8 @@ override protected ProcessResult ExecuteProcess(List commandArgs, bool c
foreach (var envVar in _environmentVariables)
{
commandArgs.Add("--codegenopt");
- string complusPrefix = "COMPlus_";
- commandArgs.Add(String.Format("{0}={1}", envVar.Key.Substring(complusPrefix.Length), envVar.Value));
+ string dotnetPrefix = "DOTNET_";
+ commandArgs.Add(String.Format("{0}={1}", envVar.Key.Substring(dotnetPrefix.Length), envVar.Value));
}
return Utility.ExecuteProcess(_executablePath, commandArgs, capture);
}
diff --git a/src/jit-diff/install.cs b/src/jit-diff/install.cs
index b550f215..fc154ff5 100644
--- a/src/jit-diff/install.cs
+++ b/src/jit-diff/install.cs
@@ -3,13 +3,18 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Collections.Generic;
using System.CommandLine;
+using System.Diagnostics;
using System.IO;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
using System.Linq;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml;
namespace ManagedCodeGen
{
@@ -19,7 +24,7 @@ public static int InstallCommand(Config config)
{
var configFilePath = Path.Combine(config.JitUtilsRoot, s_configFileName);
string configJson = File.ReadAllText(configFilePath);
- var jObj = JObject.Parse(configJson);
+ var jObj = JsonObject.Parse(configJson);
if ((jObj[s_configFileRootKey] == null) || (jObj[s_configFileRootKey]["tools"] == null))
{
@@ -32,7 +37,7 @@ public static int InstallCommand(Config config)
return -1;
}
- var tools = (JArray)jObj[s_configFileRootKey]["tools"];
+ var tools = (JsonArray)jObj[s_configFileRootKey]["tools"];
// Early out if the tool is already installed. We can only do this if we're not doing
// "--last_successful", in which case we don't know what the build number (and hence
@@ -134,8 +139,6 @@ public static int InstallCommand(Config config)
toolPath = Path.Combine(toolPath, tag);
- JObject newTool = new JObject();
- newTool.Add("tag", tag);
string platformPath = Path.Combine(toolPath, "Product");
if (!Directory.Exists(platformPath))
{
@@ -148,27 +151,20 @@ public static int InstallCommand(Config config)
{
if (Path.GetFileName(dir).ToUpper().Contains(buildOS))
{
- newTool.Add("path", Path.GetFullPath(dir));
- if (tools.HasValues)
+ tools.Add(new JsonObject
{
- tools.Last.AddAfterSelf(newTool);
- }
- else
- {
- tools.Add(newTool);
- }
+ ["tag"] = tag,
+ ["path"] = Path.GetFullPath(dir)
+ });
break;
}
}
// Overwrite current config.json with new data.
- using (var file = File.CreateText(configFilePath))
+ using (var sw = File.CreateText(configFilePath))
{
- using (JsonTextWriter writer = new JsonTextWriter(file))
- {
- writer.Formatting = Formatting.Indented;
- jObj.WriteTo(writer);
- }
+ var json = JsonSerializer.Serialize (jObj, new JsonSerializerOptions { WriteIndented = true });
+ sw.Write(json);
}
return 0;
diff --git a/src/jit-diff/jit-diff.cs b/src/jit-diff/jit-diff.cs
index dd6bd10f..eb9a6d20 100755
--- a/src/jit-diff/jit-diff.cs
+++ b/src/jit-diff/jit-diff.cs
@@ -3,12 +3,13 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Collections.Generic;
using System.CommandLine;
using System.IO;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
using System.Linq;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
@@ -152,7 +153,7 @@ public class Config
private bool _cctors;
private int _count = 20;
private string _metric = "CodeSize";
- private JObject _jObj;
+ private JsonObject _jObj;
private bool _configFileLoaded = false;
private bool _noJitUtilsRoot = false;
private bool _validationError = false;
@@ -701,7 +702,7 @@ private void ExpandToolTags()
return;
}
- var tools = _jObj[s_configFileRootKey]["tools"];
+ var tools = (JsonArray)_jObj[s_configFileRootKey]["tools"];
if (tools == null)
{
return;
@@ -948,13 +949,13 @@ public string GetToolPath(string tool, out bool found)
{
found = true;
- string tag = token.Value();
+ string tag = token.ToString();
// Extract set value for tool and see if we can find it
// in the installed tools.
- var path = _jObj[s_configFileRootKey]["tools"].Children()
- .Where(x => (string)x["tag"] == tag)
- .Select(x => (string)x["path"]);
+ var tools = (JsonArray)_jObj[s_configFileRootKey]["tools"];
+ var path = tools.Where(x => (string)x["tag"] == tag)
+ .Select(x => (string)x["path"]);
// If the tag resolves to a tool return it, otherwise just return it
// as a posible path.
return path.Any() ? path.First() : tag;
@@ -981,7 +982,7 @@ public T ExtractDefault(string name, out bool found)
try
{
- return token.Value();
+ return token.GetValue();
}
catch (System.FormatException e)
{
@@ -1013,9 +1014,9 @@ private void LoadFileConfig()
try
{
- _jObj = JObject.Parse(configJson);
+ _jObj = (JsonObject)JsonObject.Parse(configJson);
}
- catch (Newtonsoft.Json.JsonReaderException ex)
+ catch (JsonException ex)
{
Console.Error.WriteLine("Error reading config file: {0}", ex.Message);
Console.Error.WriteLine("Continuing; ignoring config file.");
@@ -1227,12 +1228,12 @@ public int ListCommand()
// Print list of the installed tools.
- var tools = asmdiffNode["tools"];
+ var tools = (JsonArray)asmdiffNode["tools"];
if (tools != null)
{
Console.WriteLine("Installed tools:");
- foreach (var tool in tools.Children())
+ foreach (JsonObject tool in tools)
{
string tag = (string)tool["tag"];
string path = (string)tool["path"];
diff --git a/src/jit-diff/uninstall.cs b/src/jit-diff/uninstall.cs
index d1a59c2b..0ad793c8 100644
--- a/src/jit-diff/uninstall.cs
+++ b/src/jit-diff/uninstall.cs
@@ -6,8 +6,8 @@
using System.CommandLine;
using System.IO;
using System.Linq;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
namespace ManagedCodeGen
{
@@ -17,7 +17,7 @@ public static int UninstallCommand(Config config)
{
var configFilePath = Path.Combine(config.JitUtilsRoot, s_configFileName);
string configJson = File.ReadAllText(configFilePath);
- var jObj = JObject.Parse(configJson);
+ var jObj = JsonObject.Parse(configJson);
if ((jObj[s_configFileRootKey] == null) || (jObj[s_configFileRootKey]["tools"] == null))
{
@@ -25,9 +25,8 @@ public static int UninstallCommand(Config config)
return -1;
}
- var tools = (JArray)jObj[s_configFileRootKey]["tools"];
- var elem = tools.Children()
- .Where(x => (string)x["tag"] == config.Tag);
+ var tools = (JsonArray)jObj[s_configFileRootKey]["tools"];
+ var elem = tools.Where(x => (string)x["tag"] == config.Tag);
if (!elem.Any())
{
Console.WriteLine("{0} is not installed in {1}.", config.Tag, s_configFileName);
@@ -47,16 +46,13 @@ public static int UninstallCommand(Config config)
}
Console.WriteLine("Removing tag {0} from config file.", config.Tag);
- jobj.Remove();
+ tools.Remove(jobj);
// Overwrite current config.json with new data.
- using (var file = File.CreateText(configFilePath))
+ using (var sw = File.CreateText(configFilePath))
{
- using (JsonTextWriter writer = new JsonTextWriter(file))
- {
- writer.Formatting = Formatting.Indented;
- jObj.WriteTo(writer);
- }
+ var json = JsonSerializer.Serialize (jObj, new JsonSerializerOptions { WriteIndented = true });
+ sw.Write(json);
}
return 0;
diff --git a/src/jit-format/jit-format.cs b/src/jit-format/jit-format.cs
index f7e736d5..3dd41e71 100644
--- a/src/jit-format/jit-format.cs
+++ b/src/jit-format/jit-format.cs
@@ -8,17 +8,17 @@
//
using System;
-using System.Diagnostics;
+using System.Collections.Generic;
using System.CommandLine;
+using System.Diagnostics;
using System.IO;
-using System.Xml;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using System.Linq;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using System.Xml;
namespace ManagedCodeGen
{
@@ -46,7 +46,7 @@ public class Config
private string _compileCommands = null;
private bool _rewriteCompileCommands = false;
- private JObject _jObj;
+ private JsonObject _jObj;
private string _jitUtilsRoot = null;
public Config(string[] args)
@@ -332,7 +332,7 @@ private void LoadFileConfig()
{
string configJson = File.ReadAllText(path);
- _jObj = JObject.Parse(configJson);
+ _jObj = (JsonObject)JsonObject.Parse(configJson);
// Check if there is any default config specified.
if (_jObj[s_configFileRootKey]["default"] != null)
@@ -395,7 +395,7 @@ public T ExtractDefault(string name, out bool found)
try
{
- return token.Value();
+ return token.GetValue();
}
catch (System.FormatException e)
{
@@ -580,17 +580,17 @@ public static int Main(string[] args)
public static string rewriteCompileCommands (string compileCommandFile, string project)
{
string allCommands = File.ReadAllText(compileCommandFile);
- JArray commands = (JArray)JArray.Parse(allCommands);
+ JsonArray commands = (JsonArray)JsonArray.Parse(allCommands);
List newCommands = new List();
- foreach (JObject command in commands.Children())
+ foreach (JsonObject command in commands)
{
// Search for directory entries containing jit/
- if (command["directory"].Value().Contains("jit/" + project))
+ if (command["directory"].ToString().Contains("jit/" + project))
{
// Add the command to our list of new commands
- string directory = command["directory"].Value();
- string compileCommand = command["command"].Value().Replace("-I", "-isystem").Replace("\\","/");
+ string directory = command["directory"].ToString();
+ string compileCommand = command["command"].ToString().Replace("-I", "-isystem").Replace("\\","/");
if (compileCommand.Contains("cl.exe"))
{
// First extract cl.exe path: it may contain spaces.
@@ -622,7 +622,7 @@ public static string rewriteCompileCommands (string compileCommandFile, string p
}
}
}
- string file = command["file"].Value();
+ string file = command["file"].ToString();
newCommands.Add(new CompileCommand(directory, compileCommand, file));
}
@@ -630,7 +630,7 @@ public static string rewriteCompileCommands (string compileCommandFile, string p
// write commands back to a file.
string newCompileCommandsFileName = Path.Combine(Path.GetDirectoryName(compileCommandFile), "compile_commands.json");
- string json = JsonConvert.SerializeObject(newCommands.ToArray(), Newtonsoft.Json.Formatting.Indented);
+ string json = JsonSerializer.Serialize(newCommands.ToArray(), new JsonSerializerOptions { WriteIndented = true });
System.IO.File.WriteAllText(newCompileCommandsFileName, json);
return newCompileCommandsFileName;
diff --git a/src/jit-include.props b/src/jit-include.props
index 6be307a9..ed35d9fd 100644
--- a/src/jit-include.props
+++ b/src/jit-include.props
@@ -1,7 +1,6 @@
-
diff --git a/src/mutate-test/MutateTestRootCommand.cs b/src/mutate-test/MutateTestRootCommand.cs
new file mode 100644
index 00000000..48bd1e3c
--- /dev/null
+++ b/src/mutate-test/MutateTestRootCommand.cs
@@ -0,0 +1,83 @@
+// 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.CommandLine;
+
+namespace MutateTest
+{
+ internal sealed class MutateTestRootCommand : RootCommand
+ {
+ public Argument InputFilePath { get; } =
+ new("input-test-case", "Input test case file or directory (for --recursive)") { Arity = ArgumentArity.OneOrMore };
+ public Option EHStress { get; } =
+ new(new[] { "--ehStress" }, "Add EH to methods");
+ public Option StructStress { get; } =
+ new(new[] { "--structStress" }, "Replace locals with structs");
+ public Option ShowResults { get; } =
+ new(new[] { "--showResults" }, "Add EH to methods");
+ public Option Verbose { get; } =
+ new(new[] { "--verbose" }, "Describe each transformation");
+ public Option Quiet { get; } =
+ new(new[] { "--quiet" }, "Produce minimal output");
+ public Option Recursive { get; } =
+ new(new[] { "--recursive" }, "Process each file recursively");
+ public Option Seed { get; } =
+ new(new[] { "--seed" }, () => 42, "Random seed");
+ public Option StopAtFirstFailure { get; } =
+ new(new[] { "--stopAtFirstFailure" }, "Stop each test at first failure");
+ public Option EmptyBlocks { get; } =
+ new(new[] { "--emptyBlocks" }, "Transform empty blocks");
+ public Option SizeLimit { get; } =
+ new(new[] { "--sizeLimit" }, () => 10000, "Don't process programs larger than this size");
+ public Option TimeLimit { get; } =
+ new(new[] { "--timeLimit" }, () => 10000, "Don't stress programs where compile + run takes more than this many milliseconds");
+ public Option Projects { get; } =
+ new(new[] { "--projects" }, "Look for .csproj files instead of .cs files when doing recursive exploration");
+ public Option OnlyFailures { get; } =
+ new(new[] { "--onlyFailures" }, "Only emit output for cases that fail at runtime");
+
+ public ParseResult Result { get; private set; }
+
+ public MutateTestRootCommand(string[] args) : base(".NET JIT mutate test utility")
+ {
+ AddArgument(InputFilePath);
+ AddOption(EHStress);
+ AddOption(StructStress);
+ AddOption(ShowResults);
+ AddOption(Verbose);
+ AddOption(Quiet);
+ AddOption(Recursive);
+ AddOption(Seed);
+ AddOption(StopAtFirstFailure);
+ AddOption(EmptyBlocks);
+ AddOption(SizeLimit);
+ AddOption(TimeLimit);
+ AddOption(Projects);
+ AddOption(OnlyFailures);
+
+ this.SetHandler(context =>
+ {
+ Result = context.ParseResult;
+
+ try
+ {
+ context.ExitCode = new Program(this).Run();
+ }
+ catch (Exception e)
+ {
+ Console.ResetColor();
+ Console.ForegroundColor = ConsoleColor.Red;
+
+ Console.Error.WriteLine("Error: " + e.Message);
+ Console.Error.WriteLine(e.ToString());
+
+ Console.ResetColor();
+
+ context.ExitCode = 1;
+ }
+ });
+ }
+ }
+}
diff --git a/src/mutate-test/Program.cs b/src/mutate-test/Program.cs
index 26e89aba..94197bee 100644
--- a/src/mutate-test/Program.cs
+++ b/src/mutate-test/Program.cs
@@ -2,24 +2,24 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Build.Locator;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Emit;
-using Microsoft.CodeAnalysis.MSBuild;
using System;
-using System.Collections.Generic;
using System.CommandLine;
-using System.CommandLine.Invocation;
-using System.Data;
+using System.CommandLine.Parsing;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
-// TODO:
+using Microsoft.Build.Locator;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Emit;
+using Microsoft.CodeAnalysis.MSBuild;
+
+// TODO:
// * Fix dependent project limitation
// * Find better way of piping in references needed for compilation, and resolving what's needed to run
// * Try random stuff from https://github.com/dotnet/roslyn-sdk/tree/master/samples/CSharp/TreeTransforms
@@ -29,33 +29,10 @@
// Useful if you can express what you want in C# and need to see how to get a transform to create it for you.
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
-using static MutateTest.OptionHolder;
namespace MutateTest
{
- class OptionHolder
- {
- public string InputFile { get; set; }
- public bool EhStress { get; set; }
- public bool StructStress { get; set; }
- public bool ShowResults { get; set; }
- public bool Recursive { get; set; }
- public bool Verbose { get; set; }
- public bool Quiet { get; set; }
- public bool StopAtFirstFailure { get; set; }
- public int Seed { get; set; }
- public int SizeLimit { get; set; }
- public int TimeLimit { get; set; }
- public bool Projects { get; set; }
- public bool OnlyFailures { get; set; }
-
- public static OptionHolder Options { get; set; }
- }
-
- public class MutateTestException : Exception
- {
-
- }
+ public class MutateTestException : Exception { }
enum ExecutionResultKind
{
@@ -83,7 +60,7 @@ struct ExecutionResult
public int value;
public bool Success => kind == ExecutionResultKind.RanNormally;
- public bool OriginalCompileFailed => kind == ExecutionResultKind.CompilationFailed || kind == ExecutionResultKind.CompilationException
+ public bool OriginalCompileFailed => kind == ExecutionResultKind.CompilationFailed || kind == ExecutionResultKind.CompilationException
|| kind == ExecutionResultKind.HasDependentProjects || kind == ExecutionResultKind.SkipSpecialCase;
public bool CompileFailed => kind == ExecutionResultKind.CompilationFailed || kind == ExecutionResultKind.CompilationException
@@ -104,8 +81,8 @@ public override string ToString()
case ExecutionResultKind.CompilationFailed: return "base compilation failed";
case ExecutionResultKind.MutantCompilationException: return "mutant compilation caused exception";
case ExecutionResultKind.MutantCompilationFailed: return "mutant compilation failed";
- case ExecutionResultKind.SizeTooLarge: return $"test case size {value} bytes exceeds current size limit {Options.SizeLimit} bytes";
- case ExecutionResultKind.RanTooLong: return $"base compile or excution time {value} ms exceeds current time limit {Options.TimeLimit} ms";
+ case ExecutionResultKind.SizeTooLarge: return $"test case size {value} bytes exceeds current size limit {Program.SizeLimit} bytes";
+ case ExecutionResultKind.RanTooLong: return $"base compile or excution time {value} ms exceeds current time limit {Program.TimeLimit} ms";
case ExecutionResultKind.LoadFailed: return "base assembly load failed";
case ExecutionResultKind.ThrewException: return "base execution threw an exception";
case ExecutionResultKind.BadExitCode: return $"base execution returned bad exit code {value}";
@@ -121,8 +98,12 @@ public override string ToString()
}
}
- public class Program
+ internal sealed class Program
{
+ public static int SizeLimit;
+ public static int TimeLimit;
+ public static bool Verbose;
+
private static readonly CSharpCompilationOptions DebugOptions =
new CSharpCompilationOptions(OutputKind.ConsoleApplication, concurrentBuild: false, optimizationLevel: OptimizationLevel.Debug).WithAllowUnsafe(true);
@@ -150,21 +131,30 @@ public class Program
MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Threading.Tasks")).Location),
};
- public static Random Random;
+ public readonly Random _random;
+ private readonly List _mutators;
+ private readonly MutateTestRootCommand _command;
+ private readonly bool _quiet;
- static IEnumerable Mutators;
-
- static IEnumerable GetMutators()
+ public Program(MutateTestRootCommand command)
{
- var mutators = new List();
+ _command = command;
+ _random = new Random(Get(command.Seed));
+ _quiet = Get(_command.Quiet);
+
+ SizeLimit = Get(_command.SizeLimit);
+ TimeLimit = Get(_command.TimeLimit);
+ Verbose = Get(_command.Verbose);
+
+ _mutators = new List();
- SplitBlocksInTwo splitBlocks = new SplitBlocksInTwo(Random);
- mutators.Add(splitBlocks);
+ SplitBlocksInTwo splitBlocks = new SplitBlocksInTwo(_random);
+ _mutators.Add(splitBlocks);
AddBlocks addBlocks = new AddBlocks();
- mutators.Add(addBlocks);
+ _mutators.Add(addBlocks);
- if (Options.EhStress)
+ if (Get(_command.EHStress))
{
// Singletons
Mutator tryCatch = new WrapBlocksInTryCatch();
@@ -191,16 +181,16 @@ static IEnumerable GetMutators()
Mutator randomMoveToCatchx2 = new RepeatMutator(randomMoveToCatch, 2);
// Random @ mutation time
- Mutator tryCatchRandom = new RandomMutator(tryCatch, Random, 0.25);
- Mutator tryEmtpyFinallyRandom = new RandomMutator(tryEmptyFinally, Random, 0.25);
- Mutator emptyTryFinallyRandom = new RandomMutator(emptyTryFinally, Random, 0.25);
- Mutator moveToCatchRandom = new RandomMutator(randomMoveToCatch, Random, 0.25);
+ Mutator tryCatchRandom = new RandomMutator(tryCatch, _random, 0.25);
+ Mutator tryEmtpyFinallyRandom = new RandomMutator(tryEmptyFinally, _random, 0.25);
+ Mutator emptyTryFinallyRandom = new RandomMutator(emptyTryFinally, _random, 0.25);
+ Mutator moveToCatchRandom = new RandomMutator(randomMoveToCatch, _random, 0.25);
// Alternative
- Mutator either12 = new RandomChoiceMutator(tryCatch, tryEmptyFinally, Random, 0.5);
- Mutator either34 = new RandomChoiceMutator(randomMoveToCatch, tryEmptyFinally, Random, 0.5);
- Mutator either1s = new RandomChoiceMutator(tryCatch, splitBlocks, Random, 0.5);
- Mutator either2s = new RandomChoiceMutator(randomMoveToCatch, splitBlocks, Random, 0.5);
+ Mutator either12 = new RandomChoiceMutator(tryCatch, tryEmptyFinally, _random, 0.5);
+ Mutator either34 = new RandomChoiceMutator(randomMoveToCatch, tryEmptyFinally, _random, 0.5);
+ Mutator either1s = new RandomChoiceMutator(tryCatch, splitBlocks, _random, 0.5);
+ Mutator either2s = new RandomChoiceMutator(randomMoveToCatch, splitBlocks, _random, 0.5);
// Combination
Mutator addSplit = new ComboMutator(addBlocks, splitBlocks);
@@ -220,94 +210,40 @@ static IEnumerable GetMutators()
Mutator combo1s2 = new ComboMutator(combo1s, combo2);
Mutator combo4s3 = new ComboMutator(combo4s, combo3);
- mutators.AddRange(new Mutator[] {
- addSplit,
- tryCatch, tryCatchx2,
- tryEmptyFinally, tryEmtpyFinallyx2,
- emptyTryFinally, emptyTryFinallyx2,
- randomTryCatch, randomTryEmptyFinally, randomEmptyTryFinally,
- randomMoveToCatch, randomMoveToCatchx2,
- tryCatchRandom, tryEmtpyFinallyRandom,
- emptyTryFinallyRandom, moveToCatchRandom,
- either12, either34, either1s, either2s,
- combo1, combo2, combo3, combo4,
- combo1s, combo2s, combo3s, combo4s,
- combo2s1, combo3s4, combo1s2, combo4s3,
- });
+ _mutators.AddRange(new Mutator[]
+ {
+ addSplit,
+ tryCatch, tryCatchx2,
+ tryEmptyFinally, tryEmtpyFinallyx2,
+ emptyTryFinally, emptyTryFinallyx2,
+ randomTryCatch, randomTryEmptyFinally, randomEmptyTryFinally,
+ randomMoveToCatch, randomMoveToCatchx2,
+ tryCatchRandom, tryEmtpyFinallyRandom,
+ emptyTryFinallyRandom, moveToCatchRandom,
+ either12, either34, either1s, either2s,
+ combo1, combo2, combo3, combo4,
+ combo1s, combo2s, combo3s, combo4s,
+ combo2s1, combo3s4, combo1s2, combo4s3,
+ });
}
-
- return mutators;
}
public static bool EnsureStack() => RuntimeHelpers.TryEnsureSufficientExecutionStack();
private static bool isFirstRun = true;
- static int Main(string[] args)
- {
- RootCommand rootCommand = new RootCommand();
- rootCommand.Description = "Take an existing test case and produce new test cases via mutation";
-
- Argument inputFile = new Argument();
- inputFile.Name = "InputFile";
- inputFile.Description = "Input test case file or directory (for --recursive)";
- rootCommand.AddArgument(inputFile);
-
- Option ehStressOption = new Option("--ehStress", "add EH to methods", new Argument());
- rootCommand.AddOption(ehStressOption);
-
- Option structStressOption = new Option("--structStress", "replace locals with structs", new Argument());
- rootCommand.AddOption(structStressOption);
-
- Option showResultsOption = new Option("--showResults", "print modified programs to stdout", new Argument());
- rootCommand.AddOption(showResultsOption);
-
- Option verboseOption = new Option("--verbose", "describe each transformation", new Argument());
- rootCommand.AddOption(verboseOption);
-
- Option quietOption = new Option("--quiet", "produce minimal output", new Argument());
- rootCommand.AddOption(quietOption);
-
- Option recursiveOption = new Option("--recursive", "process each file recursively", new Argument());
- rootCommand.AddOption(recursiveOption);
-
- Option seedOption = new Option("--seed", "random seed", new Argument(42));
- rootCommand.AddOption(seedOption);
-
- Option stopAtFirstFailureOption = new Option("--stopAtFirstFailure", "stop each test at first failure", new Argument());
- rootCommand.AddOption(stopAtFirstFailureOption);
+ private T Get(Option option) => _command.Result.GetValueForOption(option);
- Option emptyBlocks = new Option("--emptyBlocks", "transform empty blocks", new Argument());
- rootCommand.AddOption(emptyBlocks);
+ private static int Main(string[] args) =>
+ new CommandLineBuilder(new MutateTestRootCommand(args))
+ .UseVersionOption("-v")
+ .UseHelp()
+ .UseParseErrorReporting()
+ .Build()
+ .Invoke(args);
- Option sizeLimit = new Option("--sizeLimit", "don't process programs larger than this size", new Argument(10000));
- rootCommand.AddOption(sizeLimit);
-
- Option timeLimit = new Option("--timeLimit", "don't stress programs where compile + run takes more than this many milliseconds", new Argument(1000));
- rootCommand.AddOption(timeLimit);
-
- Option projectsOption = new Option("--projects", "look for .csproj files instead of .cs files when doing recursive exploration", new Argument());
- rootCommand.AddOption(projectsOption);
-
- Option onlyFailuresOption = new Option("--onlyFailures", "only emit output for cases that fail at runtime", new Argument());
- rootCommand.AddOption(onlyFailuresOption);
-
- rootCommand.Handler = CommandHandler.Create((options) =>
- {
- Options = options;
- return InnerMain();
- });
-
- return rootCommand.InvokeAsync(args).Result;
- }
-
- static int InnerMain()
+ public int Run()
{
- // Setup option-dependent statics
-
- Random = new Random(Options.Seed);
- Mutators = GetMutators();
-
int total = 0;
int skipped = 0;
int failed = 0;
@@ -316,22 +252,23 @@ static int InnerMain()
int variantFailedToCompile = 0;
int variantFailedToRun = 0;
- if (Options.Projects)
+ if (Get(_command.Projects))
{
MSBuildLocator.RegisterDefaults();
}
- if (Options.Recursive)
+ string inputFilePath = _command.Result.GetValueForArgument(_command.InputFilePath);
+ if (Get(_command.Recursive))
{
- if (!Directory.Exists(Options.InputFile))
+ if (!Directory.Exists(inputFilePath))
{
- Console.WriteLine($"Unable to access directory '{Options.InputFile}'");
+ Console.WriteLine($"Unable to access directory '{inputFilePath}'");
return -1;
}
- string suffix = Options.Projects ? ".csproj" : ".cs";
- string kind = Options.Projects ? "projects" : "test files";
- var inputFiles = Directory.EnumerateFiles(Options.InputFile, "*", SearchOption.AllDirectories)
+ string suffix = Get(_command.Projects) ? ".csproj" : ".cs";
+ string kind = Get(_command.Projects) ? "projects" : "test files";
+ var inputFiles = Directory.EnumerateFiles(inputFilePath, "*", SearchOption.AllDirectories)
.Where(s => (s.EndsWith(suffix)));
Console.WriteLine($"Processing {inputFiles.Count()} {kind}\n");
@@ -346,7 +283,7 @@ static int InnerMain()
ExecutionResult result;
- if (Options.Projects)
+ if (Get(_command.Projects))
{
result = MutateOneProject(subInputFile, ref subVariantTotal, ref subVariantFailedToCompile, ref subVariantFailedToRun);
}
@@ -357,7 +294,7 @@ static int InnerMain()
if (result.Success)
{
- if (!Options.OnlyFailures)
+ if (!Get(_command.OnlyFailures))
{
Console.WriteLine($"// {subInputFile}: {subVariantTotal} variants, all passed");
}
@@ -367,7 +304,7 @@ static int InnerMain()
{
if (result.OriginalCompileFailed || result.OriginalRunFailed || result.NoMutationsAttempted)
{
- if (!Options.OnlyFailures)
+ if (!Get(_command.OnlyFailures))
{
Console.WriteLine($"// {subInputFile}: {result}");
}
@@ -380,7 +317,7 @@ static int InnerMain()
failed++;
}
- if ((subVariantFailedToRun > 0) || !Options.OnlyFailures)
+ if ((subVariantFailedToRun > 0) || !Get(_command.OnlyFailures))
{
int successes = subVariantTotal - subVariantFailedToCompile - subVariantFailedToRun;
Console.WriteLine($"// {subInputFile}: {subVariantTotal} variants, {successes} passed" +
@@ -410,18 +347,18 @@ static int InnerMain()
{
ExecutionResult result;
- if (Options.Projects)
+ if (Get(_command.Projects))
{
- result = MutateOneProject(Options.InputFile, ref variantTotal, ref variantFailedToCompile, ref variantFailedToRun);
+ result = MutateOneProject(inputFilePath, ref variantTotal, ref variantFailedToCompile, ref variantFailedToRun);
}
else
{
- result = MutateOneTestFile(Options.InputFile, ref variantTotal, ref variantFailedToCompile, ref variantFailedToRun);
+ result = MutateOneTestFile(inputFilePath, ref variantTotal, ref variantFailedToCompile, ref variantFailedToRun);
}
if (result.Success)
{
- Console.WriteLine($"// {Options.InputFile}: {variantTotal} variants, all passed");
+ Console.WriteLine($"// {inputFilePath}: {variantTotal} variants, all passed");
succeeded++;
return 100;
}
@@ -429,22 +366,22 @@ static int InnerMain()
if (result.OriginalCompileFailed || result.OriginalRunFailed || result.NoMutationsAttempted)
{
// base case did not compile
- Console.WriteLine($"// {Options.InputFile}: {result}");
+ Console.WriteLine($"// {inputFilePath}: {result}");
}
else
{
int successes = variantTotal - variantFailedToCompile - variantFailedToRun;
- Console.WriteLine($"// {Options.InputFile}: {variantTotal} variants, {successes} passed" +
+ Console.WriteLine($"// {inputFilePath}: {variantTotal} variants, {successes} passed" +
$" [{variantFailedToCompile} did not compile, {variantFailedToRun} did not run correctly]");
}
-
+
return -1;
}
}
- static ExecutionResult MutateOneTestFile(string testFile, ref int attempted, ref int failedToCompile, ref int failedToRun)
+ private ExecutionResult MutateOneTestFile(string testFile, ref int attempted, ref int failedToCompile, ref int failedToRun)
{
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine("---------------------------------------");
Console.WriteLine("// Original Program");
@@ -467,9 +404,9 @@ static ExecutionResult MutateOneTestFile(string testFile, ref int attempted, ref
return MutateOneCompilation(compilation, Path.GetFileName(testFile), ref attempted, ref failedToCompile, ref failedToRun);
}
- static ExecutionResult MutateOneProject(string projectFile, ref int attempted, ref int failedToCompile, ref int failedToRun)
+ private ExecutionResult MutateOneProject(string projectFile, ref int attempted, ref int failedToCompile, ref int failedToRun)
{
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine("---------------------------------------");
Console.WriteLine("// Original Program");
@@ -493,11 +430,11 @@ static ExecutionResult MutateOneProject(string projectFile, ref int attempted, r
// Seems like we need to spoon feed in the assembly references here?
// Probably missing some important step.
- var compilation = project.GetCompilationAsync().Result.AddReferences(References);
+ var compilation = project.GetCompilationAsync().Result.AddReferences(References);
- if (!Options.Quiet)
+ if (!_quiet)
{
- if (Options.ShowResults)
+ if (Get(_command.ShowResults))
{
// Would be nice to show breakdown by file....
foreach (SyntaxTree s in compilation.SyntaxTrees)
@@ -511,7 +448,7 @@ static ExecutionResult MutateOneProject(string projectFile, ref int attempted, r
}
}
- static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, string name, ref int attempted, ref int failedToCompile, ref int failedToRun)
+ private ExecutionResult MutateOneCompilation(CSharpCompilation compilation, string name, ref int attempted, ref int failedToCompile, ref int failedToRun)
{
// Bail on some specific tests
// We use substring match as there are often variants
@@ -533,7 +470,7 @@ static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, strin
if (exclusions.Any(x => name.Contains(x)))
{
- return new ExecutionResult() { kind = ExecutionResultKind.SkipSpecialCase };
+ return new ExecutionResult { kind = ExecutionResultKind.SkipSpecialCase };
}
Stopwatch s = new Stopwatch();
@@ -550,13 +487,13 @@ static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, strin
int inputSize = compilation.SyntaxTrees.Sum(x => x.Length);
- if (inputSize > Options.SizeLimit)
+ if (inputSize > Get(_command.SizeLimit))
{
- return new ExecutionResult() { kind = ExecutionResultKind.SizeTooLarge, value = inputSize };
+ return new ExecutionResult { kind = ExecutionResultKind.SizeTooLarge, value = inputSize };
}
// First run will be slower because of jitting (sigh)
- int timeLimit = Options.TimeLimit;
+ int timeLimit = Program.TimeLimit;
if (isFirstRun)
{
timeLimit *= 3;
@@ -565,15 +502,15 @@ static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, strin
if (s.ElapsedMilliseconds > timeLimit)
{
- return new ExecutionResult() { kind = ExecutionResultKind.RanTooLong, value = (int) s.ElapsedMilliseconds };
+ return new ExecutionResult { kind = ExecutionResultKind.RanTooLong, value = (int) s.ElapsedMilliseconds };
}
// Ok, we have a compile and runnable test case. Now, mess with it....
int variantNumber = 0;
- ExecutionResult result = new ExecutionResult() { kind = ExecutionResultKind.RanNormally };
+ ExecutionResult result = new ExecutionResult { kind = ExecutionResultKind.RanNormally };
- foreach (var mutator in Mutators)
+ foreach (var mutator in _mutators)
{
attempted++;
ExecutionResult mutationResult = ApplyMutations(variantNumber++, mutator, compilation);
@@ -581,7 +518,7 @@ static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, strin
if (!mutationResult.Success)
{
// count assembly load failures as compile failures for now.
- if (mutationResult.CompileFailed || mutationResult.AssemblyLoadFailed)
+ if (mutationResult.CompileFailed || mutationResult.AssemblyLoadFailed)
{
failedToCompile++;
}
@@ -601,12 +538,12 @@ static ExecutionResult MutateOneCompilation(CSharpCompilation compilation, strin
return result;
}
- static ExecutionResult ApplyMutations(int variantNumber, Mutator m, CSharpCompilation compilation)
+ private ExecutionResult ApplyMutations(int variantNumber, Mutator m, CSharpCompilation compilation)
{
string shortTitle = $"Mutation [{variantNumber}]";
string title = $"// {shortTitle}: {m.Name}";
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine();
Console.WriteLine("---------------------------------------");
@@ -624,11 +561,11 @@ static ExecutionResult ApplyMutations(int variantNumber, Mutator m, CSharpCompil
transformedTrees.Add(SyntaxTree(transformedRoot));
}
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine($"// {shortTitle}: made {totalTransformCount} mutations");
- if (Options.ShowResults)
+ if (Get(_command.ShowResults))
{
foreach (SyntaxTree s in transformedTrees)
{
@@ -642,7 +579,7 @@ static ExecutionResult ApplyMutations(int variantNumber, Mutator m, CSharpCompil
return CompileAndExecute(newCompilation, shortTitle, isMutant: true);
}
- static ExecutionResult CompileAndExecute(CSharpCompilation compilation, string name, bool isMutant = false)
+ private ExecutionResult CompileAndExecute(CSharpCompilation compilation, string name, bool isMutant = false)
{
using (var ms = new MemoryStream())
{
@@ -653,7 +590,7 @@ static ExecutionResult CompileAndExecute(CSharpCompilation compilation, string n
}
catch (Exception ex)
{
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine($"// Compilation of '{name}' failed: {ex.Message}");
}
@@ -662,7 +599,7 @@ static ExecutionResult CompileAndExecute(CSharpCompilation compilation, string n
if (!emitResult.Success)
{
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine($"// Compilation of '{name}' failed: {emitResult.Diagnostics.Length} errors");
foreach (var d in emitResult.Diagnostics)
@@ -673,7 +610,7 @@ static ExecutionResult CompileAndExecute(CSharpCompilation compilation, string n
return new ExecutionResult() { kind = isMutant ? ExecutionResultKind.MutantCompilationFailed : ExecutionResultKind.CompilationFailed };
}
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine($"// Compiled '{name}' successfully");
}
@@ -742,7 +679,7 @@ static ExecutionResult CompileAndExecute(CSharpCompilation compilation, string n
return new ExecutionResult() { kind = isMutant? ExecutionResultKind.MutantBadExitCode : ExecutionResultKind.BadExitCode, value = (int)inputResult };
}
- if (!Options.Quiet)
+ if (!_quiet)
{
Console.WriteLine($"// Execution of '{name}' succeeded (exitCode {inputResult})");
}
@@ -781,7 +718,7 @@ protected int GetTransformCount()
protected virtual void Announce(SyntaxNode node, string message = "")
{
- if (Options.Verbose)
+ if (Program.Verbose)
{
var lineSpan = node.GetLocation().GetMappedLineSpan();
Console.WriteLine($"// {Name} [{TransformCount}] @ lines {lineSpan.StartLinePosition.Line}-{lineSpan.EndLinePosition.Line} {message}");
@@ -791,7 +728,7 @@ protected virtual void Announce(SyntaxNode node, string message = "")
protected void AnnounceSkip(SyntaxNode node, string message = "")
{
- if (Options.Verbose)
+ if (Program.Verbose)
{
var lineSpan = node.GetLocation().GetMappedLineSpan();
Console.WriteLine($"// SKIP {Name} [{TransformCount}] @ lines {lineSpan.StartLinePosition.Line}-{lineSpan.EndLinePosition.Line} {message}");
@@ -850,12 +787,12 @@ protected static bool InvalidInFinally(SyntaxNode node)
// before we see a block. Bail for now.
return node.DescendantNodes(descendIntoTrivia: false).Any(
x =>
- x.Kind() == SyntaxKind.ReturnStatement
- || x.Kind() == SyntaxKind.ThrowStatement
- || x.Kind() == SyntaxKind.ImplicitStackAllocArrayCreationExpression
- || x.Kind() == SyntaxKind.StackAllocArrayCreationExpression
- || x.Kind() == SyntaxKind.GotoStatement
- || x.Kind() == SyntaxKind.BreakStatement
+ x.IsKind(SyntaxKind.ReturnStatement)
+ || x.IsKind(SyntaxKind.ThrowStatement)
+ || x.IsKind(SyntaxKind.ImplicitStackAllocArrayCreationExpression)
+ || x.IsKind(SyntaxKind.StackAllocArrayCreationExpression)
+ || x.IsKind(SyntaxKind.GotoStatement)
+ || x.IsKind(SyntaxKind.BreakStatement)
); ;
}
@@ -864,32 +801,32 @@ protected static bool IsInvalidInCatchOrFinally(SyntaxNode node)
{
// Throw is legally ok, but we disallow to try and avoid causing stack overflow
return node.DescendantNodes(descendIntoTrivia: false).Any(
- x => x.Kind() == SyntaxKind.ImplicitStackAllocArrayCreationExpression
- || x.Kind() == SyntaxKind.StackAllocArrayCreationExpression
- || x.Kind() == SyntaxKind.ThrowStatement
+ x => x.IsKind(SyntaxKind.ImplicitStackAllocArrayCreationExpression)
+ || x.IsKind(SyntaxKind.StackAllocArrayCreationExpression)
+ || x.IsKind(SyntaxKind.ThrowStatement)
);
}
protected static bool IsEnclosedInLoop(SyntaxNode node)
{
return node.Ancestors().Any(
- x => x.Kind() == SyntaxKind.ForStatement
- || x.Kind() == SyntaxKind.DoStatement
- || x.Kind() == SyntaxKind.WhileStatement
- || x.Kind() == SyntaxKind.ForEachStatement
+ x => x.IsKind(SyntaxKind.ForStatement)
+ || x.IsKind(SyntaxKind.DoStatement)
+ || x.IsKind(SyntaxKind.WhileStatement)
+ || x.IsKind(SyntaxKind.ForEachStatement)
);
}
protected static bool IsEnclosedInCatch(SyntaxNode node)
{
return node.Ancestors().Any(
- x => x.Kind() == SyntaxKind.CatchClause
+ x => x.IsKind(SyntaxKind.CatchClause)
);
}
protected static bool DefinesLabel(SyntaxNode node)
{
- return node.DescendantNodes().Any(x => x.Kind() == SyntaxKind.LabeledStatement);
+ return node.DescendantNodes().Any(x => x.IsKind(SyntaxKind.LabeledStatement));
}
public SyntaxNode Mutate(SyntaxNode node, out int transformCount)
@@ -901,7 +838,7 @@ public SyntaxNode Mutate(SyntaxNode node, out int transformCount)
}
}
- // Rewrite as
+ // Rewrite as
// try { } catch (MutateTest.MutateTestException) { throw; }
public class WrapBlocksInTryCatch : Mutator
{
@@ -1331,7 +1268,7 @@ public override SyntaxNode VisitExpressionStatement(ExpressionStatementSyntax no
{
node = (ExpressionStatementSyntax)base.VisitExpressionStatement(node);
- if (node.Parent.Kind() == SyntaxKind.Block)
+ if (node.Parent.IsKind(SyntaxKind.Block))
{
AnnounceSkip(node);
return node;
@@ -1346,7 +1283,7 @@ public override SyntaxNode VisitReturnStatement(ReturnStatementSyntax node)
{
node = (ReturnStatementSyntax)base.VisitReturnStatement(node);
- if (node.Parent.Kind() == SyntaxKind.Block)
+ if (node.Parent.IsKind(SyntaxKind.Block))
{
AnnounceSkip(node);
return node;
diff --git a/src/mutate-test/mutate-test.csproj b/src/mutate-test/mutate-test.csproj
index eb470254..5533bbaa 100644
--- a/src/mutate-test/mutate-test.csproj
+++ b/src/mutate-test/mutate-test.csproj
@@ -2,17 +2,16 @@
Exe
- netcoreapp3.1
+ net6.0
Mutate
Mutate
- 7.3
-
-
-
-
+
+
+
+
diff --git a/src/superpmi/superpmicollect.cs b/src/superpmi/superpmicollect.cs
index c88a9886..63e8dc39 100644
--- a/src/superpmi/superpmicollect.cs
+++ b/src/superpmi/superpmicollect.cs
@@ -314,18 +314,18 @@ private static void CollectMCFiles(string runProgramPath, string runProgramArgum
Console.WriteLine("Setting environment variables:");
Console.WriteLine(" SuperPMIShimLogPath=" + s_tempDir);
Console.WriteLine(" SuperPMIShimPath=" + Global.JitPath);
- Console.WriteLine(" COMPlus_JitName=" + Global.CollectorShimName);
+ Console.WriteLine(" DOTNET_JitName=" + Global.CollectorShimName);
Environment.SetEnvironmentVariable("SuperPMIShimLogPath", s_tempDir);
Environment.SetEnvironmentVariable("SuperPMIShimPath", Global.JitPath);
- Environment.SetEnvironmentVariable("COMPlus_JitName", Global.CollectorShimName);
+ Environment.SetEnvironmentVariable("DOTNET_JitName", Global.CollectorShimName);
RunProgramsWhileCollecting(runProgramPath, runProgramArguments);
// Un-set environment variables
Environment.SetEnvironmentVariable("SuperPMIShimLogPath", "");
Environment.SetEnvironmentVariable("SuperPMIShimPath", "");
- Environment.SetEnvironmentVariable("COMPlus_JitName", "");
+ Environment.SetEnvironmentVariable("DOTNET_JitName", "");
// Did any .mc files get generated?
string[] mcFiles = Directory.GetFiles(s_tempDir, "*.mc");
@@ -604,7 +604,7 @@ private static void Usage()
Console.WriteLine("If -mch is not given, all generated files are deleted, and the result is simply the exit code");
Console.WriteLine("indicating whether the collection succeeded. This is useful as a test.");
Console.WriteLine("");
- Console.WriteLine("If the COMPlus_JitName variable is already set, it is assumed SuperPMI collection is already happening,");
+ Console.WriteLine("If the DOTNET_JitName variable is already set, it is assumed SuperPMI collection is already happening,");
Console.WriteLine("and the program exits with success.");
Console.WriteLine("");
Console.WriteLine("On success, the return code is 100.");
@@ -701,14 +701,14 @@ private static int Main(string[] args)
// Done with argument parsing.
- string jitnamevar = System.Environment.GetEnvironmentVariable("COMPlus_JitName");
+ string jitnamevar = System.Environment.GetEnvironmentVariable("DOTNET_JitName");
if (!String.IsNullOrEmpty(jitnamevar))
{
- // Someone already has the COMPlus_JitName variable set. We don't want to override
+ // Someone already has the DOTNET_JitName variable set. We don't want to override
// that. Perhaps someone is already doing a SuperPMI collection and invokes this
// program as part of a full test path in which this program exists.
- Console.WriteLine("COMPlus_JitName already exists: skipping SuperPMI collection and returning success");
+ Console.WriteLine("DOTNET_JitName already exists: skipping SuperPMI collection and returning success");
return 100;
}
diff --git a/src/target-framework.props b/src/target-framework.props
index 7e777ca8..f7f9a41f 100644
--- a/src/target-framework.props
+++ b/src/target-framework.props
@@ -3,7 +3,7 @@
- netcoreapp3.1
+ net6.0