Skip to content

Commit

Permalink
Generate hashes for two ref assembly types in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
safesparrow committed Oct 31, 2023
1 parent 1937918 commit fe5041b
Showing 1 changed file with 38 additions and 19 deletions.
57 changes: 38 additions & 19 deletions MSBuild.CompilerCache/RefTrimmer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,10 @@ public static ImmutableArray<string> GetInternalsVisibleToAssemblies(MetadataRea
.ToImmutableArray();
}

public static (ImmutableArray<byte> bytes, ImmutableArray<string> internalsVisibleToAssemblies) MakeRefasm(
ImmutableArray<byte> content, LoggerBase logger, RefAsmType refAsmType)
public static ImmutableArray<byte> MakeRefasm(LoggerBase logger, RefAsmType refAsmType, PEReader peReader)
{
var peReader = new PEReader(content);
var metaReader = peReader.GetMetadataReader();

var internalsVisibleToAssemblies = GetInternalsVisibleToAssemblies(metaReader);

if (!metaReader.IsAssembly)
throw new Exception("File format is not supported");

Expand All @@ -97,34 +93,57 @@ public static (ImmutableArray<byte> bytes, ImmutableArray<string> internalsVisib

var refBytes = MetadataImporter.MakeRefasm(metaReader, peReader, logger, filter, makeMock: false)!;

return (ImmutableArray.Create(refBytes), internalsVisibleToAssemblies);
return ImmutableArray.Create(refBytes);
}

public static (string hash, ImmutableArray<string> internalsVisibleToAssemblies) MakeRefasmAndGetHash(
ImmutableArray<byte> content, LoggerBase logger, RefAsmType refAsmType)
public static string MakeRefasmAndGetHash(LoggerBase logger, RefAsmType refAsmType, PEReader peReader)
{
var (bytes, internalsVisibleToAssemblies) = MakeRefasm(content, logger, refAsmType);
var bytes = MakeRefasm(logger, refAsmType, peReader);
var hash = Utils.BytesToHashHex(bytes.AsSpan());
return (hash, internalsVisibleToAssemblies);
return hash;
}

public RefData GenerateRefData(ImmutableArray<byte> content)
{
var logger = new VerySimpleLogger(Console.Out, LogLevel.Warning);
var loggerBase = new LoggerBase(logger);

var (publicRefHash, internalsVisibleToAssemblies) =
MakeRefasmAndGetHash(content, loggerBase, RefAsmType.Public);
var peReader = new PEReader(content);
var metaReader = peReader.GetMetadataReader();
var internalsVisibleToAssemblies = GetInternalsVisibleToAssemblies(metaReader);
// If no assemblies can see the internals, there is no need to generate public+internal ref assembly
var internalsNeverAccessible = internalsVisibleToAssemblies.IsEmpty;
var publicAndInternalRefHash =
internalsNeverAccessible
? publicRefHash
: MakeRefasmAndGetHash(content, loggerBase, RefAsmType.PublicAndInternal).hash;


string GetPublicHash()
{
var peReader2 = new PEReader(content);
return MakeRefasmAndGetHash(loggerBase, RefAsmType.Public, peReader2);
}

string GetPublicAndInternalHash()
{
var peReader3 = new PEReader(content);
return MakeRefasmAndGetHash(loggerBase, RefAsmType.PublicAndInternal, peReader3);
}

string? publicRefHash = null; string? publicAndInternalRefHash = null;
if (internalsNeverAccessible)
{
publicRefHash = publicAndInternalRefHash = GetPublicHash();
}
else
{
var tasks = new[]
{
Task.Factory.StartNew(() => { publicRefHash = GetPublicHash();}),
Task.Factory.StartNew(() => { publicAndInternalRefHash = GetPublicAndInternalHash();})
};
Task.WaitAll(tasks);
}

return new RefData(
PublicRefHash: publicRefHash,
PublicAndInternalRefHash: publicAndInternalRefHash,
PublicRefHash: publicRefHash!,
PublicAndInternalRefHash: publicAndInternalRefHash!,
InternalsVisibleTo: internalsVisibleToAssemblies
);
}
Expand Down

0 comments on commit fe5041b

Please sign in to comment.