diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-03-04 14:09:59 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-04 14:09:59 -0300 |
| commit | 3edb66f389ac279bdcde26c5682aa39b9bf5f853 (patch) | |
| tree | b3082b45648417a289ba10c2b40f6c134b93fa98 /ChocolArm64/ATranslatedSub.cs | |
| parent | ee9df32e3e13fe982c8154a6454566c8edfa13d3 (diff) | |
Improve CPU initial translation speeds (#50)
* Add background translation to the CPU
* Do not use a separate thread for translation, implement 2 tiers translation
* Remove unnecessary usings
* Lower MinCallCountForReJit
* Remove unused variable
Diffstat (limited to 'ChocolArm64/ATranslatedSub.cs')
| -rw-r--r-- | ChocolArm64/ATranslatedSub.cs | 92 |
1 files changed, 61 insertions, 31 deletions
diff --git a/ChocolArm64/ATranslatedSub.cs b/ChocolArm64/ATranslatedSub.cs index 71a6793a..414038ab 100644 --- a/ChocolArm64/ATranslatedSub.cs +++ b/ChocolArm64/ATranslatedSub.cs @@ -2,6 +2,7 @@ using ChocolArm64.Memory; using ChocolArm64.State; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Reflection; using System.Reflection.Emit; @@ -13,35 +14,47 @@ namespace ChocolArm64 private AA64Subroutine ExecDelegate; - private bool HasDelegate; - - public static Type[] FixedArgTypes { get; private set; } - public static int StateArgIdx { get; private set; } public static int MemoryArgIdx { get; private set; } + public static Type[] FixedArgTypes { get; private set; } + public DynamicMethod Method { get; private set; } - public HashSet<long> SubCalls { get; private set; } + public ReadOnlyCollection<ARegister> Params { get; private set; } - public List<ARegister> Params { get; private set; } + private HashSet<long> Callees; - public bool NeedsReJit { get; private set; } + private ATranslatedSubType Type; - public ATranslatedSub() - { - SubCalls = new HashSet<long>(); - } + private int CallCount; + + private bool NeedsReJit; + + private int MinCallCountForReJit = 250; - public ATranslatedSub(DynamicMethod Method, List<ARegister> Params) : this() + public ATranslatedSub(DynamicMethod Method, List<ARegister> Params, HashSet<long> Callees) { + if (Method == null) + { + throw new ArgumentNullException(nameof(Method)); + } + if (Params == null) { throw new ArgumentNullException(nameof(Params)); } - this.Method = Method; - this.Params = Params; + if (Callees == null) + { + throw new ArgumentNullException(nameof(Callees)); + } + + this.Method = Method; + this.Params = Params.AsReadOnly(); + this.Callees = Callees; + + PrepareDelegate(); } static ATranslatedSub() @@ -69,36 +82,53 @@ namespace ChocolArm64 } } - public long Execute(AThreadState ThreadState, AMemory Memory) + private void PrepareDelegate() { - if (!HasDelegate) - { - string Name = $"{Method.Name}_Dispatch"; + string Name = $"{Method.Name}_Dispatch"; - DynamicMethod Mthd = new DynamicMethod(Name, typeof(long), FixedArgTypes); + DynamicMethod Mthd = new DynamicMethod(Name, typeof(long), FixedArgTypes); - ILGenerator Generator = Mthd.GetILGenerator(); + ILGenerator Generator = Mthd.GetILGenerator(); - Generator.EmitLdargSeq(FixedArgTypes.Length); + Generator.EmitLdargSeq(FixedArgTypes.Length); - foreach (ARegister Reg in Params) - { - Generator.EmitLdarg(StateArgIdx); + foreach (ARegister Reg in Params) + { + Generator.EmitLdarg(StateArgIdx); - Generator.Emit(OpCodes.Ldfld, Reg.GetField()); - } + Generator.Emit(OpCodes.Ldfld, Reg.GetField()); + } - Generator.Emit(OpCodes.Call, Method); - Generator.Emit(OpCodes.Ret); + Generator.Emit(OpCodes.Call, Method); + Generator.Emit(OpCodes.Ret); - ExecDelegate = (AA64Subroutine)Mthd.CreateDelegate(typeof(AA64Subroutine)); + ExecDelegate = (AA64Subroutine)Mthd.CreateDelegate(typeof(AA64Subroutine)); + } - HasDelegate = true; + public bool ShouldReJit() + { + if (Type == ATranslatedSubType.SubTier0) + { + if (CallCount < MinCallCountForReJit) + { + CallCount++; + } + + return CallCount == MinCallCountForReJit; } + return Type == ATranslatedSubType.SubTier1 && NeedsReJit; + } + + public long Execute(AThreadState ThreadState, AMemory Memory) + { return ExecDelegate(ThreadState, Memory); } - public void MarkForReJit() => NeedsReJit = true; + public void SetType(ATranslatedSubType Type) => this.Type = Type; + + public bool HasCallee(long Position) => Callees.Contains(Position); + + public void MarkForReJit() => NeedsReJit = true; } }
\ No newline at end of file |
