From 5d32e28449b5f05766685239ab414250265ca301 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 3 Jul 2018 18:18:03 -0300 Subject: [PATCH] Remove unused tracing functionality from the CPU --- ChocolArm64/AOptimizations.cs | 2 - ChocolArm64/ATranslator.cs | 49 +------- ChocolArm64/Events/ACpuTraceEventArgs.cs | 17 --- ChocolArm64/Instruction/AInstEmitFlow.cs | 31 ------ ChocolArm64/State/AThreadState.cs | 30 ----- Ryujinx.HLE/Loaders/Executable.cs | 19 ++-- Ryujinx.HLE/OsHle/Process.cs | 135 +++++++++++------------ 7 files changed, 79 insertions(+), 204 deletions(-) delete mode 100644 ChocolArm64/Events/ACpuTraceEventArgs.cs diff --git a/ChocolArm64/AOptimizations.cs b/ChocolArm64/AOptimizations.cs index 800cf363d..d6b546918 100644 --- a/ChocolArm64/AOptimizations.cs +++ b/ChocolArm64/AOptimizations.cs @@ -4,8 +4,6 @@ public static class AOptimizations { public static bool DisableMemoryChecks = false; - public static bool GenerateCallStack = true; - private static bool UseAllSseIfAvailable = true; private static bool UseSseIfAvailable = true; diff --git a/ChocolArm64/ATranslator.cs b/ChocolArm64/ATranslator.cs index 2d9fcb141..a51d88496 100644 --- a/ChocolArm64/ATranslator.cs +++ b/ChocolArm64/ATranslator.cs @@ -1,12 +1,9 @@ using ChocolArm64.Decoder; -using ChocolArm64.Events; using ChocolArm64.Instruction; using ChocolArm64.Memory; using ChocolArm64.State; using ChocolArm64.Translation; -using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Reflection.Emit; namespace ChocolArm64 @@ -15,24 +12,9 @@ namespace ChocolArm64 { private ConcurrentDictionary CachedSubs; - private ConcurrentDictionary SymbolTable; - - public event EventHandler CpuTrace; - - public bool EnableCpuTrace { get; set; } - - public ATranslator(IReadOnlyDictionary SymbolTable = null) + public ATranslator() { CachedSubs = new ConcurrentDictionary(); - - if (SymbolTable != null) - { - this.SymbolTable = new ConcurrentDictionary(SymbolTable); - } - else - { - this.SymbolTable = new ConcurrentDictionary(); - } } internal void ExecuteSubroutine(AThread Thread, long Position) @@ -68,16 +50,6 @@ namespace ChocolArm64 { do { - if (EnableCpuTrace) - { - if (!SymbolTable.TryGetValue(Position, out string SubName)) - { - SubName = string.Empty; - } - - CpuTrace?.Invoke(this, new ACpuTraceEventArgs(Position, SubName)); - } - if (!CachedSubs.TryGetValue(Position, out ATranslatedSub Sub)) { Sub = TranslateTier0(State, Memory, Position); @@ -148,8 +120,6 @@ namespace ChocolArm64 string SubName = GetSubName(Position); - PropagateName(Cfg.Graph, SubName); - AILEmitterCtx Context = new AILEmitterCtx(this, Cfg.Graph, Cfg.Root, SubName); if (Context.CurrBlock.Position != Position) @@ -185,22 +155,7 @@ namespace ChocolArm64 private string GetSubName(long Position) { - return SymbolTable.GetOrAdd(Position, $"Sub{Position:x16}"); - } - - private void PropagateName(ABlock[] Graph, string Name) - { - foreach (ABlock Block in Graph) - { - AOpCode LastOp = Block.GetLastOp(); - - if (LastOp != null && - (LastOp.Emitter == AInstEmit.Bl || - LastOp.Emitter == AInstEmit.Blr)) - { - SymbolTable.TryAdd(LastOp.Position + 4, Name); - } - } + return $"Sub{Position:x16}"; } } } \ No newline at end of file diff --git a/ChocolArm64/Events/ACpuTraceEventArgs.cs b/ChocolArm64/Events/ACpuTraceEventArgs.cs deleted file mode 100644 index fedf3865b..000000000 --- a/ChocolArm64/Events/ACpuTraceEventArgs.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace ChocolArm64.Events -{ - public class ACpuTraceEventArgs : EventArgs - { - public long Position { get; private set; } - - public string SubName { get; private set; } - - public ACpuTraceEventArgs(long Position, string SubName) - { - this.Position = Position; - this.SubName = SubName; - } - } -} \ No newline at end of file diff --git a/ChocolArm64/Instruction/AInstEmitFlow.cs b/ChocolArm64/Instruction/AInstEmitFlow.cs index 89979d050..91262834f 100644 --- a/ChocolArm64/Instruction/AInstEmitFlow.cs +++ b/ChocolArm64/Instruction/AInstEmitFlow.cs @@ -35,14 +35,6 @@ namespace ChocolArm64.Instruction { AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp; - if (AOptimizations.GenerateCallStack) - { - Context.EmitLdarg(ATranslatedSub.StateArgIdx); - Context.EmitLdc_I8(Op.Imm); - - Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod)); - } - Context.EmitLdc_I(Op.Position + 4); Context.EmitStint(AThreadState.LRIndex); Context.EmitStoreState(); @@ -80,14 +72,6 @@ namespace ChocolArm64.Instruction { AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp; - if (AOptimizations.GenerateCallStack) - { - Context.EmitLdarg(ATranslatedSub.StateArgIdx); - Context.EmitLdintzr(Op.Rn); - - Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod)); - } - Context.EmitLdc_I(Op.Position + 4); Context.EmitStint(AThreadState.LRIndex); Context.EmitStoreState(); @@ -100,14 +84,6 @@ namespace ChocolArm64.Instruction { AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp; - if (AOptimizations.GenerateCallStack) - { - Context.EmitLdarg(ATranslatedSub.StateArgIdx); - Context.EmitLdintzr(Op.Rn); - - Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.JumpMethod)); - } - Context.EmitStoreState(); Context.EmitLdintzr(Op.Rn); @@ -129,13 +105,6 @@ namespace ChocolArm64.Instruction public static void Ret(AILEmitterCtx Context) { - if (AOptimizations.GenerateCallStack) - { - Context.EmitLdarg(ATranslatedSub.StateArgIdx); - - Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.ExitMethod)); - } - Context.EmitStoreState(); Context.EmitLdint(AThreadState.LRIndex); diff --git a/ChocolArm64/State/AThreadState.cs b/ChocolArm64/State/AThreadState.cs index a84e3242b..66cca5c3d 100644 --- a/ChocolArm64/State/AThreadState.cs +++ b/ChocolArm64/State/AThreadState.cs @@ -1,6 +1,5 @@ using ChocolArm64.Events; using System; -using System.Collections.Generic; using System.Diagnostics; using System.Runtime.Intrinsics; @@ -80,17 +79,10 @@ namespace ChocolArm64.State public event EventHandler SvcCall; public event EventHandler Undefined; - private Stack CallStack; - private static Stopwatch TickCounter; private static double HostTickFreq; - public AThreadState() - { - CallStack = new Stack(); - } - static AThreadState() { HostTickFreq = 1.0 / Stopwatch.Frequency; @@ -114,27 +106,5 @@ namespace ChocolArm64.State { Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode)); } - - internal void EnterMethod(long Position) - { - CallStack.Push(Position); - } - - internal void ExitMethod() - { - CallStack.TryPop(out _); - } - - internal void JumpMethod(long Position) - { - CallStack.TryPop(out _); - - CallStack.Push(Position); - } - - public long[] GetCallStack() - { - return CallStack.ToArray(); - } } } \ No newline at end of file diff --git a/Ryujinx.HLE/Loaders/Executable.cs b/Ryujinx.HLE/Loaders/Executable.cs index 618ee241a..440f61a51 100644 --- a/Ryujinx.HLE/Loaders/Executable.cs +++ b/Ryujinx.HLE/Loaders/Executable.cs @@ -1,22 +1,23 @@ using ChocolArm64.Memory; using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.OsHle; +using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; namespace Ryujinx.HLE.Loaders { class Executable { + private AMemory Memory; + private List Dynamic; - private Dictionary m_SymbolTable; - - public IReadOnlyDictionary SymbolTable => m_SymbolTable; + public ReadOnlyCollection SymbolTable; public string Name { get; private set; } - private AMemory Memory; - public long ImageBase { get; private set; } public long ImageEnd { get; private set; } @@ -24,8 +25,6 @@ namespace Ryujinx.HLE.Loaders { Dynamic = new List(); - m_SymbolTable = new Dictionary(); - Name = Exe.Name; this.Memory = Memory; @@ -84,14 +83,18 @@ namespace Ryujinx.HLE.Loaders long SymEntSize = GetFirstValue(ElfDynTag.DT_SYMENT); + List Symbols = new List(); + while ((ulong)SymTblAddr < (ulong)StrTblAddr) { ElfSym Sym = GetSymbol(SymTblAddr, StrTblAddr); - m_SymbolTable.TryAdd(Sym.Value, Sym.Name); + Symbols.Add(Sym); SymTblAddr += SymEntSize; } + + SymbolTable = Array.AsReadOnly(Symbols.OrderBy(x => x.Value).ToArray()); } private void WriteData( diff --git a/Ryujinx.HLE/OsHle/Process.cs b/Ryujinx.HLE/OsHle/Process.cs index 53e357ab9..2fb48974f 100644 --- a/Ryujinx.HLE/OsHle/Process.cs +++ b/Ryujinx.HLE/OsHle/Process.cs @@ -57,8 +57,6 @@ namespace Ryujinx.HLE.OsHle private List Executables; - private Dictionary SymbolTable; - private long ImageBase; private bool ShouldDispose; @@ -133,8 +131,6 @@ namespace Ryujinx.HLE.OsHle return false; } - MakeSymbolTable(); - MapRWMemRegion( MemoryRegions.MainStackAddress, MemoryRegions.MainStackSize, @@ -201,7 +197,7 @@ namespace Ryujinx.HLE.OsHle throw new ObjectDisposedException(nameof(Process)); } - AThread CpuThread = new AThread(GetTranslator(), Memory, EntryPoint); + AThread CpuThread = new AThread(new ATranslator(), Memory, EntryPoint); KThread Thread = new KThread(CpuThread, this, ProcessorId, Priority); @@ -243,69 +239,22 @@ namespace Ryujinx.HLE.OsHle throw new UndefinedInstructionException(e.Position, e.RawOpCode); } - private void MakeSymbolTable() - { - SymbolTable = new Dictionary(); - - foreach (Executable Exe in Executables) - { - foreach (KeyValuePair KV in Exe.SymbolTable) - { - SymbolTable.TryAdd(Exe.ImageBase + KV.Key, KV.Value); - } - } - } - - private ATranslator GetTranslator() - { - if (Translator == null) - { - Translator = new ATranslator(SymbolTable); - - Translator.CpuTrace += CpuTraceHandler; - } - - return Translator; - } - - public void EnableCpuTracing() - { - Translator.EnableCpuTrace = true; - } - - public void DisableCpuTracing() - { - Translator.EnableCpuTrace = false; - } - - private void CpuTraceHandler(object sender, ACpuTraceEventArgs e) - { - string NsoName = string.Empty; - - for (int Index = Executables.Count - 1; Index >= 0; Index--) - { - if (e.Position >= Executables[Index].ImageBase) - { - NsoName = $"{(e.Position - Executables[Index].ImageBase):x16}"; - - break; - } - } - - Ns.Log.PrintDebug(LogClass.Cpu, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}"); - } - public void PrintStackTrace(AThreadState ThreadState) { - long[] Positions = ThreadState.GetCallStack(); - StringBuilder Trace = new StringBuilder(); Trace.AppendLine("Guest stack trace:"); - foreach (long Position in Positions) + void AppendTrace(long Position) { - if (!SymbolTable.TryGetValue(Position, out string SubName)) + Executable Exe = GetNsoExecutable(Position); + + if (Exe == null) + { + return; + } + + if (!TryGetSubName(Exe, Position, out string SubName)) { SubName = $"Sub{Position:x16}"; } @@ -314,13 +263,65 @@ namespace Ryujinx.HLE.OsHle SubName = Demangler.Parse(SubName); } - Trace.AppendLine(" " + SubName + " (" + GetNsoNameAndAddress(Position) + ")"); + long Offset = Position - Exe.ImageBase; + + string ExeNameWithAddr = $"{Exe.Name}:{Offset:x8}"; + + Trace.AppendLine(" " + SubName + " (" + ExeNameWithAddr + ")"); + } + + long FramePointer = (long)ThreadState.X29; + + while (FramePointer != 0) + { + AppendTrace(Memory.ReadInt64(FramePointer + 8)); + + FramePointer = Memory.ReadInt64(FramePointer); } Ns.Log.PrintInfo(LogClass.Cpu, Trace.ToString()); } - private string GetNsoNameAndAddress(long Position) + private bool TryGetSubName(Executable Exe, long Position, out string Name) + { + Position -= Exe.ImageBase; + + int Left = 0; + int Right = Exe.SymbolTable.Count - 1; + + while (Left <= Right) + { + int Size = Right - Left; + + int Middle = Left + (Size >> 1); + + ElfSym Symbol = Exe.SymbolTable[Middle]; + + long EndPosition = Symbol.Value + Symbol.Size; + + if ((ulong)Position >= (ulong)Symbol.Value && (ulong)Position < (ulong)EndPosition) + { + Name = Symbol.Name; + + return true; + } + + if ((ulong)Position < (ulong)Symbol.Value) + { + Right = Middle - 1; + } + else + { + Left = Middle + 1; + } + } + + Name = null; + + return false; + } + + private Executable GetNsoExecutable(long Position) { string Name = string.Empty; @@ -328,15 +329,11 @@ namespace Ryujinx.HLE.OsHle { if (Position >= Executables[Index].ImageBase) { - long Offset = Position - Executables[Index].ImageBase; - - Name = $"{Executables[Index].Name}:{Offset:x8}"; - - break; + return Executables[Index]; } } - return Name; + return null; } private int GetFreeTlsSlot(AThread Thread)