diff options
Diffstat (limited to 'ARMeilleure/Translation/PTC/Ptc.cs')
| -rw-r--r-- | ARMeilleure/Translation/PTC/Ptc.cs | 499 |
1 files changed, 304 insertions, 195 deletions
diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 6dd902bc..163e3efa 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -3,6 +3,7 @@ using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.X86; using ARMeilleure.Memory; using ARMeilleure.Translation.Cache; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using System; @@ -12,17 +13,20 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Runtime; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Threading; +using static ARMeilleure.Translation.PTC.PtcFormatter; + namespace ARMeilleure.Translation.PTC { public static class Ptc { - private const string HeaderMagic = "PTChd"; + private const string HeaderMagicString = "PTChd\0\0\0"; - private const int InternalVersion = 2010; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 1968; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1"; @@ -37,12 +41,14 @@ namespace ARMeilleure.Translation.PTC private const byte FillingByte = 0x00; private const CompressionLevel SaveCompressionLevel = CompressionLevel.Fastest; - private static readonly MemoryStream _infosStream; - private static readonly MemoryStream _codesStream; - private static readonly MemoryStream _relocsStream; - private static readonly MemoryStream _unwindInfosStream; + private static MemoryStream _infosStream; + private static MemoryStream _codesStream; + private static MemoryStream _relocsStream; + private static MemoryStream _unwindInfosStream; + + private static BinaryWriter _infosWriter; - private static readonly BinaryWriter _infosWriter; + private static readonly ulong _headerMagic; private static readonly ManualResetEvent _waitEvent; @@ -66,12 +72,9 @@ namespace ARMeilleure.Translation.PTC static Ptc() { - _infosStream = new MemoryStream(); - _codesStream = new MemoryStream(); - _relocsStream = new MemoryStream(); - _unwindInfosStream = new MemoryStream(); + InitializeMemoryStreams(); - _infosWriter = new BinaryWriter(_infosStream, EncodingCache.UTF8NoBOM, true); + _headerMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(HeaderMagicString).AsSpan()); _waitEvent = new ManualResetEvent(true); @@ -95,13 +98,13 @@ namespace ARMeilleure.Translation.PTC public static void Initialize(string titleIdText, string displayVersion, bool enabled) { Wait(); - ClearMemoryStreams(); - PtcJumpTable.Clear(); PtcProfiler.Wait(); PtcProfiler.ClearEntries(); - if (String.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault) + Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled})."); + + if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault) { TitleIdText = TitleIdTextDefault; DisplayVersion = DisplayVersionDefault; @@ -114,55 +117,72 @@ namespace ARMeilleure.Translation.PTC return; } - Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled})."); - TitleIdText = titleIdText; - DisplayVersion = !String.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault; + DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault; - if (enabled) + string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir); + string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir); + + if (!Directory.Exists(workPathActual)) { - string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir); - string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir); + Directory.CreateDirectory(workPathActual); + } - if (!Directory.Exists(workPathActual)) - { - Directory.CreateDirectory(workPathActual); - } + if (!Directory.Exists(workPathBackup)) + { + Directory.CreateDirectory(workPathBackup); + } - if (!Directory.Exists(workPathBackup)) - { - Directory.CreateDirectory(workPathBackup); - } + CachePathActual = Path.Combine(workPathActual, DisplayVersion); + CachePathBackup = Path.Combine(workPathBackup, DisplayVersion); - CachePathActual = Path.Combine(workPathActual, DisplayVersion); - CachePathBackup = Path.Combine(workPathBackup, DisplayVersion); + PreLoad(); + PtcProfiler.PreLoad(); - Enable(); + Enable(); + } - PreLoad(); - PtcProfiler.PreLoad(); - } - else - { - CachePathActual = string.Empty; - CachePathBackup = string.Empty; + private static void InitializeMemoryStreams() + { + _infosStream = new MemoryStream(); + _codesStream = new MemoryStream(); + _relocsStream = new MemoryStream(); + _unwindInfosStream = new MemoryStream(); - Disable(); - } + _infosWriter = new BinaryWriter(_infosStream, EncodingCache.UTF8NoBOM, true); } - internal static void ClearMemoryStreams() + private static void DisposeMemoryStreams() { - _infosStream.SetLength(0L); - _codesStream.SetLength(0L); - _relocsStream.SetLength(0L); - _unwindInfosStream.SetLength(0L); + _infosWriter.Dispose(); + + _infosStream.Dispose(); + _codesStream.Dispose(); + _relocsStream.Dispose(); + _unwindInfosStream.Dispose(); + } + + private static bool AreMemoryStreamsEmpty() + { + return _infosStream.Length == 0L && _codesStream.Length == 0L && _relocsStream.Length == 0L && _unwindInfosStream.Length == 0L; + } + + private static void ResetMemoryStreamsIfNeeded() + { + if (AreMemoryStreamsEmpty()) + { + return; + } + + DisposeMemoryStreams(); + + InitializeMemoryStreams(); } private static void PreLoad() { - string fileNameActual = String.Concat(CachePathActual, ".cache"); - string fileNameBackup = String.Concat(CachePathBackup, ".cache"); + string fileNameActual = string.Concat(CachePathActual, ".cache"); + string fileNameBackup = string.Concat(CachePathBackup, ".cache"); FileInfo fileInfoActual = new FileInfo(fileNameActual); FileInfo fileInfoBackup = new FileInfo(fileNameBackup); @@ -183,106 +203,144 @@ namespace ARMeilleure.Translation.PTC } } - private static bool Load(string fileName, bool isBackup) + private static unsafe bool Load(string fileName, bool isBackup) { - using (FileStream compressedStream = new FileStream(fileName, FileMode.Open)) - using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress, true)) - using (MemoryStream stream = new MemoryStream()) - using (MD5 md5 = MD5.Create()) + using (FileStream compressedStream = new(fileName, FileMode.Open)) + using (DeflateStream deflateStream = new(compressedStream, CompressionMode.Decompress, true)) { - int hashSize = md5.HashSize / 8; + Hash128 currentSizeHash = DeserializeStructure<Hash128>(compressedStream); - try - { - deflateStream.CopyTo(stream); - } - catch + Span<byte> sizeBytes = new byte[sizeof(int)]; + compressedStream.Read(sizeBytes); + Hash128 expectedSizeHash = XXHash128.ComputeHash(sizeBytes); + + if (currentSizeHash != expectedSizeHash) { InvalidateCompressedStream(compressedStream); return false; } - stream.Seek(0L, SeekOrigin.Begin); + int size = BinaryPrimitives.ReadInt32LittleEndian(sizeBytes); - byte[] currentHash = new byte[hashSize]; - stream.Read(currentHash, 0, hashSize); + IntPtr intPtr = IntPtr.Zero; - byte[] expectedHash = md5.ComputeHash(stream); - - if (!CompareHash(currentHash, expectedHash)) + try { - InvalidateCompressedStream(compressedStream); + intPtr = Marshal.AllocHGlobal(size); - return false; - } + using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite)) + { + try + { + deflateStream.CopyTo(stream); + } + catch + { + InvalidateCompressedStream(compressedStream); - stream.Seek((long)hashSize, SeekOrigin.Begin); + return false; + } - Header header = ReadHeader(stream); + int hashSize = Unsafe.SizeOf<Hash128>(); - if (header.Magic != HeaderMagic) - { - InvalidateCompressedStream(compressedStream); + stream.Seek(0L, SeekOrigin.Begin); + Hash128 currentHash = DeserializeStructure<Hash128>(stream); - return false; - } + ReadOnlySpan<byte> streamBytes = new(stream.PositionPointer, (int)(stream.Length - stream.Position)); + Hash128 expectedHash = XXHash128.ComputeHash(streamBytes); - if (header.CacheFileVersion != InternalVersion) - { - InvalidateCompressedStream(compressedStream); + if (currentHash != expectedHash) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - if (header.FeatureInfo != GetFeatureInfo()) - { - InvalidateCompressedStream(compressedStream); + stream.Seek((long)hashSize, SeekOrigin.Begin); - return false; - } + Header header = ReadHeader(stream); - if (header.OSPlatform != GetOSPlatform()) - { - InvalidateCompressedStream(compressedStream); + if (header.Magic != _headerMagic) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - if (header.InfosLen % InfoEntry.Stride != 0) - { - InvalidateCompressedStream(compressedStream); + if (header.CacheFileVersion != InternalVersion) + { + InvalidateCompressedStream(compressedStream); - return false; - } + return false; + } - byte[] infosBuf = new byte[header.InfosLen]; - byte[] codesBuf = new byte[header.CodesLen]; - byte[] relocsBuf = new byte[header.RelocsLen]; - byte[] unwindInfosBuf = new byte[header.UnwindInfosLen]; + if (header.Endianness != GetEndianness()) + { + InvalidateCompressedStream(compressedStream); - stream.Read(infosBuf, 0, header.InfosLen); - stream.Read(codesBuf, 0, header.CodesLen); - stream.Read(relocsBuf, 0, header.RelocsLen); - stream.Read(unwindInfosBuf, 0, header.UnwindInfosLen); + return false; + } - try - { - PtcJumpTable = PtcJumpTable.Deserialize(stream); - } - catch - { - PtcJumpTable = new PtcJumpTable(); + if (header.FeatureInfo != GetFeatureInfo()) + { + InvalidateCompressedStream(compressedStream); - InvalidateCompressedStream(compressedStream); + return false; + } - return false; - } + if (header.OSPlatform != GetOSPlatform()) + { + InvalidateCompressedStream(compressedStream); + + return false; + } + + if (header.InfosLen % InfoEntry.Stride != 0) + { + InvalidateCompressedStream(compressedStream); + + return false; + } + + ReadOnlySpan<byte> infosBuf = new(stream.PositionPointer, header.InfosLen); + stream.Seek(header.InfosLen, SeekOrigin.Current); + + ReadOnlySpan<byte> codesBuf = new(stream.PositionPointer, header.CodesLen); + stream.Seek(header.CodesLen, SeekOrigin.Current); - _infosStream.Write(infosBuf, 0, header.InfosLen); - _codesStream.Write(codesBuf, 0, header.CodesLen); - _relocsStream.Write(relocsBuf, 0, header.RelocsLen); - _unwindInfosStream.Write(unwindInfosBuf, 0, header.UnwindInfosLen); + ReadOnlySpan<byte> relocsBuf = new(stream.PositionPointer, header.RelocsLen); + stream.Seek(header.RelocsLen, SeekOrigin.Current); + + ReadOnlySpan<byte> unwindInfosBuf = new(stream.PositionPointer, header.UnwindInfosLen); + stream.Seek(header.UnwindInfosLen, SeekOrigin.Current); + + try + { + PtcJumpTable = PtcJumpTable.Deserialize(stream); + } + catch + { + PtcJumpTable = new PtcJumpTable(); + + InvalidateCompressedStream(compressedStream); + + return false; + } + + _infosStream.Write(infosBuf); + _codesStream.Write(codesBuf); + _relocsStream.Write(relocsBuf); + _unwindInfosStream.Write(unwindInfosBuf); + } + } + finally + { + if (intPtr != IntPtr.Zero) + { + Marshal.FreeHGlobal(intPtr); + } + } } long fileSize = new FileInfo(fileName).Length; @@ -292,20 +350,16 @@ namespace ARMeilleure.Translation.PTC return true; } - private static bool CompareHash(ReadOnlySpan<byte> currentHash, ReadOnlySpan<byte> expectedHash) - { - return currentHash.SequenceEqual(expectedHash); - } - - private static Header ReadHeader(MemoryStream stream) + private static Header ReadHeader(Stream stream) { - using (BinaryReader headerReader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true)) + using (BinaryReader headerReader = new(stream, EncodingCache.UTF8NoBOM, true)) { Header header = new Header(); - header.Magic = headerReader.ReadString(); + header.Magic = headerReader.ReadUInt64(); header.CacheFileVersion = headerReader.ReadUInt32(); + header.Endianness = headerReader.ReadBoolean(); header.FeatureInfo = headerReader.ReadUInt64(); header.OSPlatform = headerReader.ReadUInt32(); @@ -323,87 +377,133 @@ namespace ARMeilleure.Translation.PTC compressedStream.SetLength(0L); } - private static void PreSave(object state) + private static void PreSave() { _waitEvent.Reset(); - string fileNameActual = String.Concat(CachePathActual, ".cache"); - string fileNameBackup = String.Concat(CachePathBackup, ".cache"); + try + { + string fileNameActual = string.Concat(CachePathActual, ".cache"); + string fileNameBackup = string.Concat(CachePathBackup, ".cache"); - FileInfo fileInfoActual = new FileInfo(fileNameActual); + FileInfo fileInfoActual = new FileInfo(fileNameActual); - if (fileInfoActual.Exists && fileInfoActual.Length != 0L) - { - File.Copy(fileNameActual, fileNameBackup, true); + if (fileInfoActual.Exists && fileInfoActual.Length != 0L) + { + File.Copy(fileNameActual, fileNameBackup, true); + } + + Save(fileNameActual); } + finally + { + ResetMemoryStreamsIfNeeded(); + PtcJumpTable.ClearIfNeeded(); - Save(fileNameActual); + GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; + } _waitEvent.Set(); } - private static void Save(string fileName) + private static unsafe void Save(string fileName) { int translatedFuncsCount; - using (MemoryStream stream = new MemoryStream()) - using (MD5 md5 = MD5.Create()) + int hashSize = Unsafe.SizeOf<Hash128>(); + + int size = hashSize + Header.Size + GetMemoryStreamsLength() + PtcJumpTable.GetSerializeSize(PtcJumpTable); + + Span<byte> sizeBytes = new byte[sizeof(int)]; + BinaryPrimitives.WriteInt32LittleEndian(sizeBytes, size); + Hash128 sizeHash = XXHash128.ComputeHash(sizeBytes); + + Span<byte> sizeHashBytes = new byte[hashSize]; + MemoryMarshal.Write<Hash128>(sizeHashBytes, ref sizeHash); + + IntPtr intPtr = IntPtr.Zero; + + try { - int hashSize = md5.HashSize / 8; + intPtr = Marshal.AllocHGlobal(size); - stream.Seek((long)hashSize, SeekOrigin.Begin); + using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite)) + { + stream.Seek((long)hashSize, SeekOrigin.Begin); - WriteHeader(stream); + WriteHeader(stream); - _infosStream.WriteTo(stream); - _codesStream.WriteTo(stream); - _relocsStream.WriteTo(stream); - _unwindInfosStream.WriteTo(stream); + _infosStream.WriteTo(stream); + _codesStream.WriteTo(stream); + _relocsStream.WriteTo(stream); + _unwindInfosStream.WriteTo(stream); - PtcJumpTable.Serialize(stream, PtcJumpTable); + PtcJumpTable.Serialize(stream, PtcJumpTable); - translatedFuncsCount = GetInfosEntriesCount(); + stream.Seek((long)hashSize, SeekOrigin.Begin); + ReadOnlySpan<byte> streamBytes = new(stream.PositionPointer, (int)(stream.Length - stream.Position)); + Hash128 hash = XXHash128.ComputeHash(streamBytes); - ClearMemoryStreams(); - PtcJumpTable.Clear(); + stream.Seek(0L, SeekOrigin.Begin); + SerializeStructure(stream, hash); - stream.Seek((long)hashSize, SeekOrigin.Begin); - byte[] hash = md5.ComputeHash(stream); + translatedFuncsCount = GetInfosEntriesCount(); - stream.Seek(0L, SeekOrigin.Begin); - stream.Write(hash, 0, hashSize); + ResetMemoryStreamsIfNeeded(); + PtcJumpTable.ClearIfNeeded(); - using (FileStream compressedStream = new FileStream(fileName, FileMode.OpenOrCreate)) - using (DeflateStream deflateStream = new DeflateStream(compressedStream, SaveCompressionLevel, true)) - { - try + using (FileStream compressedStream = new(fileName, FileMode.OpenOrCreate)) + using (DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true)) { - stream.WriteTo(deflateStream); - } - catch - { - compressedStream.Position = 0L; - } + try + { + compressedStream.Write(sizeHashBytes); + compressedStream.Write(sizeBytes); - if (compressedStream.Position < compressedStream.Length) - { - compressedStream.SetLength(compressedStream.Position); + stream.Seek(0L, SeekOrigin.Begin); + stream.CopyTo(deflateStream); + } + catch + { + compressedStream.Position = 0L; + } + + if (compressedStream.Position < compressedStream.Length) + { + compressedStream.SetLength(compressedStream.Position); + } } } } + finally + { + if (intPtr != IntPtr.Zero) + { + Marshal.FreeHGlobal(intPtr); + } + } long fileSize = new FileInfo(fileName).Length; - Logger.Info?.Print(LogClass.Ptc, $"Saved Translation Cache (size: {fileSize} bytes, translated functions: {translatedFuncsCount})."); + if (fileSize != 0L) + { + Logger.Info?.Print(LogClass.Ptc, $"Saved Translation Cache (size: {fileSize} bytes, translated functions: {translatedFuncsCount})."); + } + } + + private static int GetMemoryStreamsLength() + { + return (int)_infosStream.Length + (int)_codesStream.Length + (int)_relocsStream.Length + (int)_unwindInfosStream.Length; } - private static void WriteHeader(MemoryStream stream) + private static void WriteHeader(Stream stream) { - using (BinaryWriter headerWriter = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true)) + using (BinaryWriter headerWriter = new(stream, EncodingCache.UTF8NoBOM, true)) { - headerWriter.Write((string)HeaderMagic); // Header.Magic + headerWriter.Write((ulong)_headerMagic); // Header.Magic headerWriter.Write((uint)InternalVersion); // Header.CacheFileVersion + headerWriter.Write((bool)GetEndianness()); // Header.Endianness headerWriter.Write((ulong)GetFeatureInfo()); // Header.FeatureInfo headerWriter.Write((uint)GetOSPlatform()); // Header.OSPlatform @@ -416,10 +516,7 @@ namespace ARMeilleure.Translation.PTC internal static void LoadTranslations(ConcurrentDictionary<ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable) { - if ((int)_infosStream.Length == 0 || - (int)_codesStream.Length == 0 || - (int)_relocsStream.Length == 0 || - (int)_unwindInfosStream.Length == 0) + if (AreMemoryStreamsEmpty()) { return; } @@ -431,10 +528,10 @@ namespace ARMeilleure.Translation.PTC _relocsStream.Seek(0L, SeekOrigin.Begin); _unwindInfosStream.Seek(0L, SeekOrigin.Begin); - using (BinaryReader infosReader = new BinaryReader(_infosStream, EncodingCache.UTF8NoBOM, true)) - using (BinaryReader codesReader = new BinaryReader(_codesStream, EncodingCache.UTF8NoBOM, true)) - using (BinaryReader relocsReader = new BinaryReader(_relocsStream, EncodingCache.UTF8NoBOM, true)) - using (BinaryReader unwindInfosReader = new BinaryReader(_unwindInfosStream, EncodingCache.UTF8NoBOM, true)) + using (BinaryReader infosReader = new(_infosStream, EncodingCache.UTF8NoBOM, true)) + using (BinaryReader codesReader = new(_codesStream, EncodingCache.UTF8NoBOM, true)) + using (BinaryReader relocsReader = new(_relocsStream, EncodingCache.UTF8NoBOM, true)) + using (BinaryReader unwindInfosReader = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true)) { for (int i = 0; i < GetInfosEntriesCount(); i++) { @@ -446,9 +543,9 @@ namespace ARMeilleure.Translation.PTC SkipReloc(infoEntry.RelocEntriesCount); SkipUnwindInfo(unwindInfosReader); } - else if (infoEntry.HighCq || !PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) || !value.highCq) + else if (infoEntry.HighCq || !PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) || !value.HighCq) { - byte[] code = ReadCode(codesReader, infoEntry.CodeLen); + Span<byte> code = ReadCode(codesReader, infoEntry.CodeLen); if (infoEntry.RelocEntriesCount != 0) { @@ -529,11 +626,11 @@ namespace ARMeilleure.Translation.PTC _unwindInfosStream.Seek(pushEntriesLength * UnwindPushEntry.Stride + UnwindInfo.Stride, SeekOrigin.Current); } - private static byte[] ReadCode(BinaryReader codesReader, int codeLen) + private static Span<byte> ReadCode(BinaryReader codesReader, int codeLen) { - byte[] codeBuf = new byte[codeLen]; + Span<byte> codeBuf = new byte[codeLen]; - codesReader.Read(codeBuf, 0, codeLen); + codesReader.Read(codeBuf); return codeBuf; } @@ -605,9 +702,9 @@ namespace ARMeilleure.Translation.PTC return new UnwindInfo(pushEntries, prologueSize); } - private static TranslatedFunction FastTranslate(byte[] code, ulong guestSize, UnwindInfo unwindInfo, bool highCq) + private static TranslatedFunction FastTranslate(ReadOnlySpan<byte> code, ulong guestSize, UnwindInfo unwindInfo, bool highCq) { - CompiledFunction cFunc = new CompiledFunction(code, unwindInfo); + CompiledFunction cFunc = new CompiledFunction(code.ToArray(), unwindInfo); IntPtr codePtr = JitCache.Map(cFunc); @@ -663,6 +760,11 @@ namespace ARMeilleure.Translation.PTC if (profiledFuncsToTranslate.Count == 0) { + ResetMemoryStreamsIfNeeded(); + PtcJumpTable.ClearIfNeeded(); + + GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; + return; } @@ -696,6 +798,8 @@ namespace ARMeilleure.Translation.PTC break; } } + + Translator.DisposePools(); } int maxDegreeOfParallelism = (Environment.ProcessorCount * 3) / 4; @@ -715,8 +819,6 @@ namespace ARMeilleure.Translation.PTC threads.Clear(); - Translator.ResetPools(); - _loggerEvent.Set(); PtcJumpTable.Initialize(jumpTable); @@ -724,7 +826,9 @@ namespace ARMeilleure.Translation.PTC PtcJumpTable.ReadJumpTable(jumpTable); PtcJumpTable.ReadDynamicTable(jumpTable); - ThreadPool.QueueUserWorkItem(PreSave); + Thread preSaveThread = new Thread(PreSave); + preSaveThread.IsBackground = true; + preSaveThread.Start(); } private static void TranslationLogger(object state) @@ -751,11 +855,11 @@ namespace ARMeilleure.Translation.PTC _infosWriter.Write((ulong)guestSize); // InfoEntry.GuestSize _infosWriter.Write((bool)highCq); // InfoEntry.HighCq _infosWriter.Write((bool)false); // InfoEntry.Stubbed - _infosWriter.Write((int)ptcInfo.CodeStream.Length); // InfoEntry.CodeLen + _infosWriter.Write((int)ptcInfo.Code.Length); // InfoEntry.CodeLen _infosWriter.Write((int)ptcInfo.RelocEntriesCount); // InfoEntry.RelocEntriesCount // WriteCode. - ptcInfo.CodeStream.WriteTo(_codesStream); + _codesStream.Write(ptcInfo.Code.AsSpan()); // WriteReloc. ptcInfo.RelocStream.WriteTo(_relocsStream); @@ -765,6 +869,11 @@ namespace ARMeilleure.Translation.PTC } } + private static bool GetEndianness() + { + return BitConverter.IsLittleEndian; + } + private static ulong GetFeatureInfo() { return (ulong)HardwareCapabilities.FeatureInfoEdx << 32 | (uint)HardwareCapabilities.FeatureInfoEcx; @@ -784,9 +893,12 @@ namespace ARMeilleure.Translation.PTC private struct Header { - public string Magic; + public const int Size = 41; // Bytes. + + public ulong Magic; public uint CacheFileVersion; + public bool Endianness; public ulong FeatureInfo; public uint OSPlatform; @@ -849,12 +961,9 @@ namespace ARMeilleure.Translation.PTC Wait(); _waitEvent.Dispose(); - _infosWriter.Dispose(); + _loggerEvent.Dispose(); - _infosStream.Dispose(); - _codesStream.Dispose(); - _relocsStream.Dispose(); - _unwindInfosStream.Dispose(); + DisposeMemoryStreams(); } } } |
