From f44271a617cd64efc7da1b482429471f149efdd8 Mon Sep 17 00:00:00 2001 From: LDj3SNuD Date: Sat, 30 Jan 2021 04:32:53 +0100 Subject: [PATCH] Avoid buffer allocations in CodeGenContext.GetCode(). Avoid stream allocations in PTC.PtcInfo. Refactoring/nits. --- .../RegisterAllocators/LinearScanAllocator.cs | 67 +++++++++--------- ARMeilleure/CodeGen/X86/CodeGenContext.cs | 12 +--- ARMeilleure/CodeGen/X86/CodeGenerator.cs | 5 ++ ARMeilleure/Translation/PTC/Ptc.cs | 70 +++++++++---------- ARMeilleure/Translation/PTC/PtcInfo.cs | 10 +-- ARMeilleure/Translation/Translator.cs | 4 +- 6 files changed, 78 insertions(+), 90 deletions(-) diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs index 99400a39c5..cd36bdc028 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs @@ -86,51 +86,50 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { NumberLocals(cfg); - using (AllocationContext context = new AllocationContext(stackAlloc, regMasks, _intervals.Count)) + using AllocationContext context = new AllocationContext(stackAlloc, regMasks, _intervals.Count); + + BuildIntervals(cfg, context); + + for (int index = 0; index < _intervals.Count; index++) { - BuildIntervals(cfg, context); + LiveInterval current = _intervals[index]; - for (int index = 0; index < _intervals.Count; index++) + if (current.IsEmpty) { - LiveInterval current = _intervals[index]; - - if (current.IsEmpty) - { - continue; - } - - if (current.IsFixed) - { - context.Active.Set(index); - - if (current.Register.Type == RegisterType.Integer) - { - context.IntUsedRegisters |= 1 << current.Register.Index; - } - else /* if (interval.Register.Type == RegisterType.Vector) */ - { - context.VecUsedRegisters |= 1 << current.Register.Index; - } - - continue; - } - - AllocateInterval(context, current, index); + continue; } - for (int index = RegistersCount * 2; index < _intervals.Count; index++) + if (current.IsFixed) { - if (!_intervals[index].IsSpilled) + context.Active.Set(index); + + if (current.Register.Type == RegisterType.Integer) { - ReplaceLocalWithRegister(_intervals[index]); + context.IntUsedRegisters |= 1 << current.Register.Index; } + else /* if (interval.Register.Type == RegisterType.Vector) */ + { + context.VecUsedRegisters |= 1 << current.Register.Index; + } + + continue; } - InsertSplitCopies(); - InsertSplitCopiesAtEdges(cfg); - - return new AllocationResult(context.IntUsedRegisters, context.VecUsedRegisters, context.StackAlloc.TotalSize); + AllocateInterval(context, current, index); } + + for (int index = RegistersCount * 2; index < _intervals.Count; index++) + { + if (!_intervals[index].IsSpilled) + { + ReplaceLocalWithRegister(_intervals[index]); + } + } + + InsertSplitCopies(); + InsertSplitCopiesAtEdges(cfg); + + return new AllocationResult(context.IntUsedRegisters, context.VecUsedRegisters, context.StackAlloc.TotalSize); } private void AllocateInterval(AllocationContext context, LiveInterval current, int cIndex) diff --git a/ARMeilleure/CodeGen/X86/CodeGenContext.cs b/ARMeilleure/CodeGen/X86/CodeGenContext.cs index 67ee0afea7..fa726f2f86 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenContext.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenContext.cs @@ -302,13 +302,11 @@ namespace ARMeilleure.CodeGen.X86 { Assembler assembler = new Assembler(codeStream, _ptcInfo); - Span buffer; - for (int index = 0; index < _jumps.Count; index++) { Jump jump = _jumps[index]; - buffer = new byte[jump.JumpPosition - _stream.Position]; + Span buffer = new byte[jump.JumpPosition - _stream.Position]; _stream.Read(buffer); _stream.Seek(_ptcDisabled ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current); @@ -325,13 +323,7 @@ namespace ARMeilleure.CodeGen.X86 } } - buffer = new byte[_stream.Length - _stream.Position]; - - _stream.Read(buffer); - - codeStream.Write(buffer); - - _ptcInfo?.WriteCode(codeStream); + _stream.CopyTo(codeStream); return codeStream.ToArray(); } diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 5f41ff7901..7fbb6f05d4 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -190,6 +190,11 @@ namespace ARMeilleure.CodeGen.X86 byte[] code = context.GetCode(); + if (ptcInfo != null) + { + ptcInfo.Code = code; + } + Logger.EndPass(PassName.CodeGeneration); return new CompiledFunction(code, unwindInfo); diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 9fda3e90a1..6100124458 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -198,31 +198,31 @@ namespace ARMeilleure.Translation.PTC using (FileStream compressedStream = new FileStream(fileName, FileMode.Open)) using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress, true)) { + using MD5 md5 = MD5.Create(); + + int hashSize = md5.HashSize / 8; + + byte[] currentSizeHash = new byte[hashSize]; + compressedStream.Read(currentSizeHash, 0, hashSize); + + byte[] sizeBytes = new byte[sizeof(int)]; + compressedStream.Read(sizeBytes, 0, sizeBytes.Length); + + byte[] expectedSizeHash = md5.ComputeHash(sizeBytes); + + if (!CompareHash(currentSizeHash, expectedSizeHash)) + { + InvalidateCompressedStream(compressedStream); + + return false; + } + + int size = BitConverter.ToInt32(sizeBytes, 0); + IntPtr intPtr = IntPtr.Zero; try { - MD5 md5 = MD5.Create(); - - int hashSize = md5.HashSize / 8; - - byte[] currentSizeHash = new byte[hashSize]; - compressedStream.Read(currentSizeHash, 0, hashSize); - - byte[] sizeBytes = new byte[sizeof(int)]; - compressedStream.Read(sizeBytes, 0, sizeBytes.Length); - - byte[] expectedSizeHash = md5.ComputeHash(sizeBytes); - - if (!CompareHash(currentSizeHash, expectedSizeHash)) - { - InvalidateCompressedStream(compressedStream); - - return false; - } - - int size = BitConverter.ToInt32(sizeBytes, 0); - intPtr = Marshal.AllocHGlobal(size); using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite)) @@ -245,8 +245,6 @@ namespace ARMeilleure.Translation.PTC byte[] expectedHash = md5.ComputeHash(stream); - md5.Dispose(); - if (!CompareHash(currentHash, expectedHash)) { InvalidateCompressedStream(compressedStream); @@ -413,20 +411,20 @@ namespace ARMeilleure.Translation.PTC { int translatedFuncsCount; + using MD5 md5 = MD5.Create(); + + int hashSize = md5.HashSize / 8; + + int size = hashSize + Header.Size + GetMemoryStreamsLength() + PtcJumpTable.GetSerializeSize(PtcJumpTable); + + byte[] sizeBytes = BitConverter.GetBytes(size); + Debug.Assert(sizeBytes.Length == sizeof(int)); + byte[] sizeHash = md5.ComputeHash(sizeBytes); + IntPtr intPtr = IntPtr.Zero; try { - MD5 md5 = MD5.Create(); - - int hashSize = md5.HashSize / 8; - - int size = hashSize + Header.Size + GetMemoryStreamsLength() + PtcJumpTable.GetSerializeSize(PtcJumpTable); - - byte[] sizeBytes = BitConverter.GetBytes(size); - Debug.Assert(sizeBytes.Length == sizeof(int)); - byte[] sizeHash = md5.ComputeHash(sizeBytes); - intPtr = Marshal.AllocHGlobal(size); using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite)) @@ -445,8 +443,6 @@ namespace ARMeilleure.Translation.PTC stream.Seek((long)hashSize, SeekOrigin.Begin); byte[] hash = md5.ComputeHash(stream); - md5.Dispose(); - stream.Seek(0L, SeekOrigin.Begin); stream.Write(hash, 0, hashSize); @@ -860,11 +856,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, 0, ptcInfo.Code.Length); // WriteReloc. ptcInfo.RelocStream.WriteTo(_relocsStream); diff --git a/ARMeilleure/Translation/PTC/PtcInfo.cs b/ARMeilleure/Translation/PTC/PtcInfo.cs index 547fe6d8a7..bbecb56f24 100644 --- a/ARMeilleure/Translation/PTC/PtcInfo.cs +++ b/ARMeilleure/Translation/PTC/PtcInfo.cs @@ -9,7 +9,8 @@ namespace ARMeilleure.Translation.PTC private readonly BinaryWriter _relocWriter; private readonly BinaryWriter _unwindInfoWriter; - public MemoryStream CodeStream { get; } + public byte[] Code { get; set; } + public MemoryStream RelocStream { get; } public MemoryStream UnwindInfoStream { get; } @@ -17,7 +18,6 @@ namespace ARMeilleure.Translation.PTC public PtcInfo() { - CodeStream = new MemoryStream(); RelocStream = new MemoryStream(); UnwindInfoStream = new MemoryStream(); @@ -27,11 +27,6 @@ namespace ARMeilleure.Translation.PTC RelocEntriesCount = 0; } - public void WriteCode(MemoryStream codeStream) - { - codeStream.WriteTo(CodeStream); - } - public void WriteRelocEntry(RelocEntry relocEntry) { _relocWriter.Write((int)relocEntry.Position); @@ -60,7 +55,6 @@ namespace ARMeilleure.Translation.PTC _relocWriter.Dispose(); _unwindInfoWriter.Dispose(); - CodeStream.Dispose(); RelocStream.Dispose(); UnwindInfoStream.Dispose(); } diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 30b448c1c6..3368c8881c 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -246,8 +246,10 @@ namespace ARMeilleure.Translation ResetPool(highCq ? 1 : 0); } - else using (PtcInfo ptcInfo = new PtcInfo()) + else { + using PtcInfo ptcInfo = new PtcInfo(); + func = Compiler.Compile(cfg, argTypes, OperandType.I64, options, ptcInfo); ResetPool(highCq ? 1 : 0);