Make Emit and AdvanceOpCode private, simplify it a bit now that it starts emiting from the entry point
This commit is contained in:
parent
508899f8bb
commit
0d448cde37
2 changed files with 72 additions and 78 deletions
|
@ -21,7 +21,7 @@ namespace ChocolArm64.Translation
|
||||||
private Block _currBlock;
|
private Block _currBlock;
|
||||||
|
|
||||||
public Block CurrBlock => _currBlock;
|
public Block CurrBlock => _currBlock;
|
||||||
public OpCode64 CurrOp => _currBlock.OpCodes[_opcIndex];
|
public OpCode64 CurrOp => _currBlock?.OpCodes[_opcIndex];
|
||||||
|
|
||||||
private Dictionary<Block, ILBlock> _visitedBlocks;
|
private Dictionary<Block, ILBlock> _visitedBlocks;
|
||||||
|
|
||||||
|
@ -67,7 +67,63 @@ namespace ChocolArm64.Translation
|
||||||
AdvanceOpCode();
|
AdvanceOpCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AdvanceOpCode()
|
public ILBlock[] GetILBlocks()
|
||||||
|
{
|
||||||
|
EmitAllOpCodes();
|
||||||
|
|
||||||
|
return _ilBlocks.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmitAllOpCodes()
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
EmitOpCode();
|
||||||
|
}
|
||||||
|
while (AdvanceOpCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmitOpCode()
|
||||||
|
{
|
||||||
|
if (_currBlock == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_opcIndex == 0)
|
||||||
|
{
|
||||||
|
MarkLabel(GetLabel(_currBlock.Position));
|
||||||
|
|
||||||
|
EmitSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrOp.Emitter(this);
|
||||||
|
|
||||||
|
_ilBlock.Add(new ILBarrier());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmitSynchronization()
|
||||||
|
{
|
||||||
|
EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
EmitLdc_I4(_currBlock.OpCodes.Count);
|
||||||
|
|
||||||
|
EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.Synchronize));
|
||||||
|
|
||||||
|
EmitLdc_I4(0);
|
||||||
|
|
||||||
|
ILLabel lblContinue = new ILLabel();
|
||||||
|
|
||||||
|
Emit(OpCodes.Bne_Un_S, lblContinue);
|
||||||
|
|
||||||
|
EmitLdc_I8(0);
|
||||||
|
|
||||||
|
Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
MarkLabel(lblContinue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AdvanceOpCode()
|
||||||
{
|
{
|
||||||
if (_currBlock == null)
|
if (_currBlock == null)
|
||||||
{
|
{
|
||||||
|
@ -144,51 +200,6 @@ namespace ChocolArm64.Translation
|
||||||
return new ILBlock();
|
return new ILBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EmitOpCode()
|
|
||||||
{
|
|
||||||
if (_currBlock == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_opcIndex == 0)
|
|
||||||
{
|
|
||||||
MarkLabel(GetLabel(_currBlock.Position));
|
|
||||||
|
|
||||||
EmitSynchronization();
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrOp.Emitter(this);
|
|
||||||
|
|
||||||
_ilBlock.Add(new ILBarrier());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EmitSynchronization()
|
|
||||||
{
|
|
||||||
EmitLdarg(TranslatedSub.StateArgIdx);
|
|
||||||
|
|
||||||
EmitLdc_I4(_currBlock.OpCodes.Count);
|
|
||||||
|
|
||||||
EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.Synchronize));
|
|
||||||
|
|
||||||
EmitLdc_I4(0);
|
|
||||||
|
|
||||||
ILLabel lblContinue = new ILLabel();
|
|
||||||
|
|
||||||
Emit(OpCodes.Bne_Un_S, lblContinue);
|
|
||||||
|
|
||||||
EmitLdc_I8(0);
|
|
||||||
|
|
||||||
Emit(OpCodes.Ret);
|
|
||||||
|
|
||||||
MarkLabel(lblContinue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ILBlock[] GetILBlocks()
|
|
||||||
{
|
|
||||||
return _ilBlocks.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryOptEmitSubroutineCall()
|
public bool TryOptEmitSubroutineCall()
|
||||||
{
|
{
|
||||||
if (_currBlock.Next == null)
|
if (_currBlock.Next == null)
|
||||||
|
|
|
@ -85,12 +85,6 @@ namespace ChocolArm64
|
||||||
|
|
||||||
ILEmitterCtx context = new ILEmitterCtx(_cache, block);
|
ILEmitterCtx context = new ILEmitterCtx(_cache, block);
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
context.EmitOpCode();
|
|
||||||
}
|
|
||||||
while (context.AdvanceOpCode());
|
|
||||||
|
|
||||||
string subName = GetSubroutineName(position);
|
string subName = GetSubroutineName(position);
|
||||||
|
|
||||||
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName);
|
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName);
|
||||||
|
@ -110,34 +104,10 @@ namespace ChocolArm64
|
||||||
|
|
||||||
ILEmitterCtx context = new ILEmitterCtx(_cache, graph);
|
ILEmitterCtx context = new ILEmitterCtx(_cache, graph);
|
||||||
|
|
||||||
if (context.CurrBlock.Position != position)
|
ILBlock[] ilBlocks = context.GetILBlocks();
|
||||||
{
|
|
||||||
context.Emit(OpCodes.Br, context.GetLabel(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
context.EmitOpCode();
|
|
||||||
}
|
|
||||||
while (context.AdvanceOpCode());
|
|
||||||
|
|
||||||
//Mark all methods that calls this method for ReJiting,
|
|
||||||
//since we can now call it directly which is faster.
|
|
||||||
if (_cache.TryGetSubroutine(position, out TranslatedSub oldSub))
|
|
||||||
{
|
|
||||||
foreach (long callerPos in oldSub.GetCallerPositions())
|
|
||||||
{
|
|
||||||
if (_cache.TryGetSubroutine(position, out TranslatedSub callerSub))
|
|
||||||
{
|
|
||||||
callerSub.MarkForReJit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string subName = GetSubroutineName(position);
|
string subName = GetSubroutineName(position);
|
||||||
|
|
||||||
ILBlock[] ilBlocks = context.GetILBlocks();
|
|
||||||
|
|
||||||
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName);
|
ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName);
|
||||||
|
|
||||||
TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
|
TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
|
||||||
|
@ -152,6 +122,19 @@ namespace ChocolArm64
|
||||||
}
|
}
|
||||||
|
|
||||||
_cache.AddOrUpdate(position, subroutine, ilOpCount);
|
_cache.AddOrUpdate(position, subroutine, ilOpCount);
|
||||||
|
|
||||||
|
//Mark all methods that calls this method for ReJiting,
|
||||||
|
//since we can now call it directly which is faster.
|
||||||
|
if (_cache.TryGetSubroutine(position, out TranslatedSub oldSub))
|
||||||
|
{
|
||||||
|
foreach (long callerPos in oldSub.GetCallerPositions())
|
||||||
|
{
|
||||||
|
if (_cache.TryGetSubroutine(position, out TranslatedSub callerSub))
|
||||||
|
{
|
||||||
|
callerSub.MarkForReJit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetSubroutineName(long position)
|
private string GetSubroutineName(long position)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue