Skip to content

Commit

Permalink
implement fast-path for MonoAOTCompiler when nothing has changed
Browse files Browse the repository at this point in the history
  • Loading branch information
radical committed Sep 17, 2021
1 parent bbc570b commit eecb51f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 26 deletions.
70 changes: 48 additions & 22 deletions src/tasks/AotCompilerTask/MonoAOTCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,47 +361,73 @@ private bool ExecuteInternal()
foreach (var assemblyItem in _assembliesToCompile)
argsList.Add(GetPrecompileArgumentsFor(assemblyItem, monoPaths));

//FIXME: check the nothing changed at all case

_totalNumAssemblies = _assembliesToCompile.Count;
int allowedParallelism = Math.Min(_assembliesToCompile.Count, Environment.ProcessorCount);
if (BuildEngine is IBuildEngine9 be9)
allowedParallelism = be9.RequestCores(allowedParallelism);

if (DisableParallelAot || allowedParallelism == 1)
if (CheckAllUpToDate(argsList))
{
Log.LogMessage(MessageImportance.High, "Everything is up-to-date, nothing to precompile");

_fileWrites.AddRange(argsList.SelectMany(args => args.ProxyFiles).Select(pf => pf.TargetFile));
foreach (var args in argsList)
{
if (!PrecompileLibrarySerial(args))
return !Log.HasLoggedErrors;
}
compiledAssemblies.GetOrAdd(args.AOTAssembly.ItemSpec, args.AOTAssembly);
}
else
{
ParallelLoopResult result = Parallel.ForEach(
argsList,
new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism },
(args, state) => PrecompileLibraryParallel(args, state));
int allowedParallelism = Math.Min(_assembliesToCompile.Count, Environment.ProcessorCount);
if (BuildEngine is IBuildEngine9 be9)
allowedParallelism = be9.RequestCores(allowedParallelism);

if (!result.IsCompleted)
if (DisableParallelAot || allowedParallelism == 1)
{
return false;
foreach (var args in argsList)
{
if (!PrecompileLibrarySerial(args))
return !Log.HasLoggedErrors;
}
}
else
{
ParallelLoopResult result = Parallel.ForEach(
argsList,
new ParallelOptions { MaxDegreeOfParallelism = allowedParallelism },
(args, state) => PrecompileLibraryParallel(args, state));

if (!result.IsCompleted)
{
return false;
}
}

int numUnchanged = _totalNumAssemblies - _numCompiled;
if (numUnchanged > 0 && numUnchanged != _totalNumAssemblies)
Log.LogMessage(MessageImportance.High, $"[{numUnchanged}/{_totalNumAssemblies}] skipped unchanged assemblies.");
}

int numUnchanged = _totalNumAssemblies - _numCompiled;
if (numUnchanged > 0 && numUnchanged != _totalNumAssemblies)
Log.LogMessage(MessageImportance.High, $"[{numUnchanged}/{_totalNumAssemblies}] skipped unchanged assemblies.");
CompiledAssemblies = ConvertAssembliesDictToOrderedList(compiledAssemblies, _assembliesToCompile).ToArray();

if (_cache.Save(CacheFilePath!))
_fileWrites.Add(CacheFilePath!);

CompiledAssemblies = ConvertAssembliesDictToOrderedList(compiledAssemblies, _assembliesToCompile).ToArray();
FileWrites = _fileWrites.ToArray();

return !Log.HasLoggedErrors;
}

private bool CheckAllUpToDate(IList<PrecompileArguments> argsList)
{
foreach (var args in argsList)
{
// compare original assembly vs it's outputs.. all it's outputs!
string assemblyPath = args.AOTAssembly.GetMetadata("FullPath");
if (args.ProxyFiles.Any(pf => IsNewerThanOutput(assemblyPath, pf.TargetFile)))
return false;
}

return true;

static bool IsNewerThanOutput(string inFile, string outFile)
=> !File.Exists(inFile) || !File.Exists(outFile) ||
(File.GetLastWriteTimeUtc(inFile) > File.GetLastWriteTimeUtc(outFile));
}

private IList<ITaskItem> EnsureAndGetAssembliesInTheSameDir(ITaskItem[] originalAssemblies)
{
List<ITaskItem> filteredAssemblies = new();
Expand Down
4 changes: 2 additions & 2 deletions src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public MainWithArgsTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur
).WithRunHosts(host).UnwrapItemsAsArrays();

[Theory]
[MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })]
[MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.All })]
// [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })]
[MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.V8 })]
public void AsyncMainWithArgs(BuildArgs buildArgs, string[] args, RunHost host, string id)
=> TestMainWithArgs("async_main_with_args", @"
public class TestClass {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public NativeRebuildTestsBase(ITestOutputHelper output, SharedBuildPerTestClassF
{
List<object?[]> data = new();
// relinking
data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: false));
data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: true));
// data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: false));
// data.AddRange(GetData(aot: false, nativeRelinking: true, invariant: true));

// aot
data.AddRange(GetData(aot: true, nativeRelinking: false, invariant: false));
Expand Down Expand Up @@ -76,6 +76,7 @@ protected string Rebuild(bool nativeRelink, bool invariant, BuildArgs buildArgs,
File.WriteAllText(Path.Combine(_projectDir!, $"{buildArgs.ProjectName}.csproj"), buildArgs.ProjectFileContents);
buildArgs = newBuildArgs;

Console.WriteLine($"{Environment.NewLine}Rebuilding with no changes ..{Environment.NewLine}");
_testOutput.WriteLine($"{Environment.NewLine}Rebuilding with no changes ..{Environment.NewLine}");
(_, string output) = BuildProject(buildArgs,
id: id,
Expand Down

0 comments on commit eecb51f

Please sign in to comment.