Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kekyo committed Jun 4, 2024
1 parent 8ab4697 commit 8bf3a8b
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 83 deletions.
2 changes: 1 addition & 1 deletion chibias/chibias.core/Assembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public bool Assemble(
{
// Convert source code to object file.
using var outputStream = isDryrun ?
null : ObjectStreamUtilities.OpenObjectStream(outputTemporaryFilePath, true);
null : CompressionStreamUtilities.OpenStream(outputTemporaryFilePath, true);
if (outputStream != null)
{
Expand Down
2 changes: 1 addition & 1 deletion chibild/chibild.core/CilLinker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private bool TryLoadInputReferences(
$"Unable to find the object file: {relativePath}");
break;
}
using (var fs = ObjectStreamUtilities.OpenObjectStream(
using (var fs = CompressionStreamUtilities.OpenStream(
Path.Combine(baseInputPath, relativePath), false))
{
var tr = new StreamReader(fs, Encoding.UTF8, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ public override LoadObjectResults LoadObjectIfRequired(
LoadObjectResults.CaughtError :
LoadObjectResults.Loaded;
}
return LoadObjectResults.Ignored;

return this.requiredState == (int)RequiredStates.Loaded ?
LoadObjectResults.Loaded : LoadObjectResults.Ignored;
}

public static ArchivedObjectInputFragment[] Load(
Expand Down
93 changes: 39 additions & 54 deletions chibild/chibild.core/Generating/AssemblyInputFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ public override LoadObjectResults LoadObjectIfRequired(
this.PrepareToLoadAssembly();
return LoadObjectResults.Loaded;
}

return this.requiredState == (int)RequiredStates.Loaded ?
LoadObjectResults.Loaded : LoadObjectResults.Ignored;
}
Expand Down Expand Up @@ -411,35 +412,15 @@ private static string GetAssemblyPathHashedPath(string assemblyPath)
path.Substring(2));
}

private static string GetAssemblyHash(string assemblyPath)
{
using var fileStream = StreamUtilities.OpenStream(
assemblyPath, false);

using var alg = MD5.Create();
return BitConverter.ToString(alg.ComputeHash(fileStream)).
Replace("-", string.Empty).
ToLowerInvariant();
}

private static bool IsValidCache(
TextReader tr,
string assemblyPath,
string assemblyHash)
string assemblyPath)
{
var header1 = tr.ReadLine()?.Split(' ') ?? CommonUtilities.Empty<string>();
if (header1.FirstOrDefault() is ".path" &&
header1.ElementAt(1) is { } path)
{
if (assemblyPath == path)
{
var header2 = tr.ReadLine()?.Split(' ') ?? CommonUtilities.Empty<string>();
if (header2.FirstOrDefault() is ".hash" &&
header2.ElementAt(1) is { } hash)
{
return assemblyHash == hash;
}
}
return assemblyPath == path;
}

return false;
Expand All @@ -456,52 +437,57 @@ public static AssemblyInputFragment Load(
{
var assemblyPath = Path.Combine(baseInputPath, relativePath);
var assemblyHashedPath = GetAssemblyPathHashedPath(assemblyPath) + ".symtab";
var assemblyHash = GetAssemblyHash(assemblyPath);
//var assemblyHash = GetAssemblyHash(assemblyPath);

// Found cached file.
var cachePath = cacheBasePath != null ?
Path.Combine(cacheBasePath, assemblyHashedPath) :
null;
if (cachePath != null)
{
if (File.Exists(cachePath))
try
{
// https://gist.github.com/kekyo/004e6970d9e442c96b672838a9e18a9d
try
if (File.Exists(cachePath))
{
using var cacheStream = ObjectStreamUtilities.OpenObjectStream(
cachePath, false);
var tr = new StreamReader(cacheStream, Encoding.UTF8, true);
var assemblyDate = File.GetLastWriteTime(assemblyPath);
var cacheDate = File.GetLastWriteTime(cachePath);

if (IsValidCache(tr, assemblyPath, assemblyHash))
if (cacheDate >= assemblyDate)
{
var symbolLists = SymbolUtilities.EnumerateSymbolTable(
tr,
cachePath);
using var cacheStream = CompressionStreamUtilities.OpenStream(
cachePath, false);
var tr = new StreamReader(cacheStream, Encoding.UTF8, true);

var aggSymbols = SymbolAggregator.AggregateSymbolsFromSymbolTable(
logger,
symbolLists).
ToArray();

if (aggSymbols.SingleOrDefault() is { } aggSymbol &&
aggSymbol.ObjectName == "symcache")
if (IsValidCache(tr, assemblyPath))
{
logger.Information($"Loading cached symbols: {relativePath}");
logger.Trace($"Cached symbols: {cachePath}");

return new(
baseInputPath,
relativePath,
assemblyPath,
assemblyResolverFactory,
aggSymbol);
var symbolLists = SymbolUtilities.EnumerateSymbolTable(
tr,
cachePath);

var aggSymbols = SymbolAggregator.AggregateSymbolsFromSymbolTable(
logger,
symbolLists).
ToArray();

if (aggSymbols.SingleOrDefault() is { } aggSymbol &&
aggSymbol.ObjectName == "symcache")
{
logger.Information($"Loading cached symbols: {relativePath}");
logger.Trace($"Cached symbols: {cachePath}");

return new(
baseInputPath,
relativePath,
assemblyPath,
assemblyResolverFactory,
aggSymbol);
}
}
}
}
catch
{
}
}
catch
{
}
}

Expand Down Expand Up @@ -546,12 +532,11 @@ public static AssemblyInputFragment Load(

try
{
using (var cacheStream = ObjectStreamUtilities.OpenObjectStream(
using (var cacheStream = CompressionStreamUtilities.OpenStream(
newCachePath, true))
{
var tw = new StreamWriter(cacheStream, Encoding.UTF8);
tw.WriteLine($".path {assemblyPath}");
tw.WriteLine($".hash {assemblyHash}");

SymbolUtilities.WriteSymbolTable(tw, new[] { symbolList });
}
Expand Down
9 changes: 7 additions & 2 deletions chibild/chibild.core/Generating/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,11 @@ private void ConsumeArchivedObject(
isLocationOriginSource))
{
case LoadObjectResults.Loaded:
found = true;
if (currentFragment is ArchivedObjectInputFragment afif)
{
// This consume may cause another `InputFragment` to become `Required` state.
// Therefore, it is a `do-while` loop to check again.
found = true;
this.ConsumeFragment(afif, inputFragments);
}
break;
Expand All @@ -199,9 +201,11 @@ private void ConsumeArchivedObject(
isLocationOriginSource))
{
case LoadObjectResults.Loaded:
found = true;
if (currentFragment is ArchivedObjectInputFragment afif)
{
// This consume may cause another `InputFragment` to become `Required` state.
// Therefore, it is a `do-while` loop to check again.
found = true;
this.ConsumeFragment(afif, inputFragments);
}
break;
Expand All @@ -214,6 +218,7 @@ private void ConsumeArchivedObject(
});
#endif
}
// Repeat if at least one `ArchivedObjectInputFragment` is processed and there are no errors.
while (found && !this.caughtError);
}

Expand Down
2 changes: 1 addition & 1 deletion chibild/chibild.core/Generating/CodeGenerator_Emit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ private bool TryLoadAndConsumeCAbiStartUpObjectIfRequired(
return false;
}

using var fs = ObjectStreamUtilities.OpenObjectStream(
using var fs = CompressionStreamUtilities.OpenStream(
objectPath,
false);

Expand Down
10 changes: 6 additions & 4 deletions chibild/chibild.core/LinkerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,15 @@ public sealed class LinkerOptions
public string[] PrependExecutionSearchPaths =
CommonUtilities.Empty<string>();


public string? CacheBasePath =
GetDefaultCacheBasePath();

public bool IsDryRun = false;

public static string GetDefaultCacheBasePath() =>
Path.Combine(
CommonUtilities.GetHomePath(),
CommonUtilities.GetHomePath() ?? Environment.CurrentDirectory,
".cache",
"chibild-cil",
"symtab");

public bool IsDryRun = false;
}
8 changes: 6 additions & 2 deletions toolchain.common/Generating/SymbolUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,13 @@ public static IEnumerable<SymbolList> EnumerateSymbolTable(
Token? currentObjectName = null;
var symbols = new List<Symbol>();

foreach (var tokens in CilTokenizer.TokenizeAll("", symbolTableName, tr).
Where(tokens => tokens.Length >= 2))
foreach (var tokens in CilTokenizer.TokenizeAll("", symbolTableName, tr))
{
if (tokens.Length < 2)
{
continue;
}

switch (tokens[0])
{
// .object [objectName]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

namespace chibicc.toolchain.IO;

public static class ObjectStreamUtilities
public static class CompressionStreamUtilities
{
public static Stream OpenObjectStream(
public static Stream OpenStream(
string objectFilePath, bool writable)
{
var s = StreamUtilities.OpenStream(objectFilePath, writable);
Expand All @@ -34,7 +34,7 @@ public static Stream OpenObjectStream(
}

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static Stream OpenEmbeddedObjectStream(
public static Stream OpenEmbeddedStream(
string objectResourcePath,
Assembly? assembly = null)
{
Expand Down
26 changes: 12 additions & 14 deletions toolchain.common/Internal/CommonUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal static class CommonUtilities
public static readonly bool IsInWindows =
Environment.OSVersion.Platform == PlatformID.Win32NT;

public static string GetHomePath()
public static string? GetHomePath()
{
if (IsInWindows)
{
Expand All @@ -64,30 +64,28 @@ public static string GetHomePath()
if (!string.IsNullOrWhiteSpace(homeDrive) &&
!string.IsNullOrWhiteSpace(homePath))
{
var path = Path.GetFullPath(
var path1 = Path.GetFullPath(
$"{homeDrive}{homePath}".
TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
if (Directory.Exists(path))
if (Directory.Exists(path1))
{
return path;
return path1;
}
}
}
else

if (Environment.GetEnvironmentVariable("HOME") is { } path2 &&
!string.IsNullOrWhiteSpace(path2))
{
if (Environment.GetEnvironmentVariable("HOME") is { } path &&
!string.IsNullOrWhiteSpace(path))
path2 = Path.GetFullPath(
path2.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
if (Directory.Exists(path2))
{
path = Path.GetFullPath(
path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
if (Directory.Exists(path))
{
return path;
}
return path2;
}
}

return Path.GetFullPath(".");
return null;
}

public static string GetDirectoryPath(string path) =>
Expand Down

0 comments on commit 8bf3a8b

Please sign in to comment.