[CPU] Speed up translation a little bit
This commit is contained in:
parent
46548bbc41
commit
9227b0ea59
4 changed files with 48 additions and 33 deletions
|
@ -3,6 +3,7 @@ using ChocolArm64.State;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ namespace ChocolArm64
|
||||||
|
|
||||||
public ReadOnlyCollection<ARegister> Params { get; private set; }
|
public ReadOnlyCollection<ARegister> Params { get; private set; }
|
||||||
|
|
||||||
private HashSet<long> Callees;
|
private HashSet<long> Callers;
|
||||||
|
|
||||||
private ATranslatedSubType Type;
|
private ATranslatedSubType Type;
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ namespace ChocolArm64
|
||||||
|
|
||||||
private int MinCallCountForReJit = 250;
|
private int MinCallCountForReJit = 250;
|
||||||
|
|
||||||
public ATranslatedSub(DynamicMethod Method, List<ARegister> Params, HashSet<long> Callees)
|
public ATranslatedSub(DynamicMethod Method, List<ARegister> Params)
|
||||||
{
|
{
|
||||||
if (Method == null)
|
if (Method == null)
|
||||||
{
|
{
|
||||||
|
@ -45,14 +46,10 @@ namespace ChocolArm64
|
||||||
throw new ArgumentNullException(nameof(Params));
|
throw new ArgumentNullException(nameof(Params));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Callees == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(Callees));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Method = Method;
|
this.Method = Method;
|
||||||
this.Params = Params.AsReadOnly();
|
this.Params = Params.AsReadOnly();
|
||||||
this.Callees = Callees;
|
|
||||||
|
Callers = new HashSet<long>();
|
||||||
|
|
||||||
PrepareDelegate();
|
PrepareDelegate();
|
||||||
}
|
}
|
||||||
|
@ -107,17 +104,14 @@ namespace ChocolArm64
|
||||||
|
|
||||||
public bool ShouldReJit()
|
public bool ShouldReJit()
|
||||||
{
|
{
|
||||||
if (Type == ATranslatedSubType.SubTier0)
|
if (NeedsReJit && CallCount < MinCallCountForReJit)
|
||||||
{
|
|
||||||
if (CallCount < MinCallCountForReJit)
|
|
||||||
{
|
{
|
||||||
CallCount++;
|
CallCount++;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallCount == MinCallCountForReJit;
|
return NeedsReJit;
|
||||||
}
|
|
||||||
|
|
||||||
return Type == ATranslatedSubType.SubTier1 && NeedsReJit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long Execute(AThreadState ThreadState, AMemory Memory)
|
public long Execute(AThreadState ThreadState, AMemory Memory)
|
||||||
|
@ -125,9 +119,31 @@ namespace ChocolArm64
|
||||||
return ExecDelegate(ThreadState, Memory);
|
return ExecDelegate(ThreadState, Memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetType(ATranslatedSubType Type) => this.Type = Type;
|
public void AddCaller(long Position)
|
||||||
|
{
|
||||||
|
lock (Callers)
|
||||||
|
{
|
||||||
|
Callers.Add(Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasCallee(long Position) => Callees.Contains(Position);
|
public long[] GetCallerPositions()
|
||||||
|
{
|
||||||
|
lock (Callers)
|
||||||
|
{
|
||||||
|
return Callers.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetType(ATranslatedSubType Type)
|
||||||
|
{
|
||||||
|
this.Type = Type;
|
||||||
|
|
||||||
|
if (Type == ATranslatedSubType.SubTier0)
|
||||||
|
{
|
||||||
|
NeedsReJit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkForReJit() => NeedsReJit = true;
|
public void MarkForReJit() => NeedsReJit = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,11 +160,14 @@ namespace ChocolArm64
|
||||||
|
|
||||||
//Mark all methods that calls this method for ReJiting,
|
//Mark all methods that calls this method for ReJiting,
|
||||||
//since we can now call it directly which is faster.
|
//since we can now call it directly which is faster.
|
||||||
foreach (ATranslatedSub TS in CachedSubs.Values)
|
if (CachedSubs.TryGetValue(Position, out ATranslatedSub OldSub))
|
||||||
{
|
{
|
||||||
if (TS.HasCallee(Position))
|
foreach (long CallerPos in OldSub.GetCallerPositions())
|
||||||
{
|
{
|
||||||
TS.MarkForReJit();
|
if (CachedSubs.TryGetValue(Position, out ATranslatedSub CallerSub))
|
||||||
|
{
|
||||||
|
CallerSub.MarkForReJit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,11 @@ namespace ChocolArm64.Translation
|
||||||
|
|
||||||
public AILBlock GetILBlock(int Index) => ILBlocks[Index];
|
public AILBlock GetILBlock(int Index) => ILBlocks[Index];
|
||||||
|
|
||||||
public ATranslatedSub GetSubroutine(HashSet<long> Callees)
|
public ATranslatedSub GetSubroutine()
|
||||||
{
|
{
|
||||||
LocalAlloc = new ALocalAlloc(ILBlocks, Root);
|
LocalAlloc = new ALocalAlloc(ILBlocks, Root);
|
||||||
|
|
||||||
InitSubroutine(Callees);
|
InitSubroutine();
|
||||||
InitLocals();
|
InitLocals();
|
||||||
|
|
||||||
foreach (AILBlock ILBlock in ILBlocks)
|
foreach (AILBlock ILBlock in ILBlocks)
|
||||||
|
@ -75,7 +75,7 @@ namespace ChocolArm64.Translation
|
||||||
return Subroutine;
|
return Subroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitSubroutine(HashSet<long> Callees)
|
private void InitSubroutine()
|
||||||
{
|
{
|
||||||
List<ARegister> Params = new List<ARegister>();
|
List<ARegister> Params = new List<ARegister>();
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace ChocolArm64.Translation
|
||||||
|
|
||||||
Generator = Mthd.GetILGenerator();
|
Generator = Mthd.GetILGenerator();
|
||||||
|
|
||||||
Subroutine = new ATranslatedSub(Mthd, Params, Callees);
|
Subroutine = new ATranslatedSub(Mthd, Params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitLocals()
|
private void InitLocals()
|
||||||
|
|
|
@ -12,8 +12,6 @@ namespace ChocolArm64.Translation
|
||||||
{
|
{
|
||||||
private ATranslator Translator;
|
private ATranslator Translator;
|
||||||
|
|
||||||
private HashSet<long> Callees;
|
|
||||||
|
|
||||||
private Dictionary<long, AILLabel> Labels;
|
private Dictionary<long, AILLabel> Labels;
|
||||||
|
|
||||||
private int BlkIndex;
|
private int BlkIndex;
|
||||||
|
@ -66,8 +64,6 @@ namespace ChocolArm64.Translation
|
||||||
this.Graph = Graph;
|
this.Graph = Graph;
|
||||||
this.Root = Root;
|
this.Root = Root;
|
||||||
|
|
||||||
Callees = new HashSet<long>();
|
|
||||||
|
|
||||||
Labels = new Dictionary<long, AILLabel>();
|
Labels = new Dictionary<long, AILLabel>();
|
||||||
|
|
||||||
Emitter = new AILEmitter(Graph, Root, SubName);
|
Emitter = new AILEmitter(Graph, Root, SubName);
|
||||||
|
@ -84,7 +80,7 @@ namespace ChocolArm64.Translation
|
||||||
|
|
||||||
public ATranslatedSub GetSubroutine()
|
public ATranslatedSub GetSubroutine()
|
||||||
{
|
{
|
||||||
return Emitter.GetSubroutine(Callees);
|
return Emitter.GetSubroutine();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AdvanceOpCode()
|
public bool AdvanceOpCode()
|
||||||
|
@ -123,8 +119,6 @@ namespace ChocolArm64.Translation
|
||||||
|
|
||||||
public bool TryOptEmitSubroutineCall()
|
public bool TryOptEmitSubroutineCall()
|
||||||
{
|
{
|
||||||
Callees.Add(((AOpCodeBImm)CurrOp).Imm);
|
|
||||||
|
|
||||||
if (CurrBlock.Next == null)
|
if (CurrBlock.Next == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -152,6 +146,8 @@ namespace ChocolArm64.Translation
|
||||||
|
|
||||||
EmitCall(Sub.Method);
|
EmitCall(Sub.Method);
|
||||||
|
|
||||||
|
Sub.AddCaller(Root.Position);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue