Automatically size sparse blocks to minimize tracking ranges
This commit is contained in:
parent
74fe391150
commit
86f7b09b64
3 changed files with 39 additions and 8 deletions
|
@ -1,3 +1,4 @@
|
|||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Cpu.Signal;
|
||||
using Ryujinx.Memory;
|
||||
|
@ -89,9 +90,9 @@ namespace ARMeilleure.Common
|
|||
private readonly TEntry* _fillBottomLevelPtr;
|
||||
|
||||
private readonly List<TableSparseBlock> _sparseReserved;
|
||||
private readonly ulong _sparseBlockSize;
|
||||
private readonly ReaderWriterLockSlim _sparseLock;
|
||||
|
||||
private ulong _sparseBlockSize;
|
||||
private ulong _sparseReservedOffset;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -170,7 +171,7 @@ namespace ARMeilleure.Common
|
|||
_sparseReserved = new List<TableSparseBlock>();
|
||||
_sparseLock = new ReaderWriterLockSlim();
|
||||
|
||||
_sparseBlockSize = bottomLevelSize << 3;
|
||||
_sparseBlockSize = bottomLevelSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,6 +203,23 @@ namespace ARMeilleure.Common
|
|||
_fill = fillValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signal that the given code range exists.
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="size"></param>
|
||||
public void SignalCodeRange(ulong address, ulong size)
|
||||
{
|
||||
AddressTableLevel bottom = Levels.Last();
|
||||
ulong bottomLevelEntries = 1ul << bottom.Length;
|
||||
|
||||
ulong entryIndex = address >> bottom.Index;
|
||||
ulong entries = size >> bottom.Index;
|
||||
entries += entryIndex - BitUtils.AlignDown(entryIndex, bottomLevelEntries);
|
||||
|
||||
_sparseBlockSize = Math.Max(_sparseBlockSize, BitUtils.AlignUp(entries, bottomLevelEntries) * (ulong)sizeof(TEntry));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsValid(ulong address)
|
||||
{
|
||||
|
@ -341,12 +359,14 @@ namespace ARMeilleure.Common
|
|||
Ryujinx.Common.Logging.Logger.Info?.PrintMsg(LogClass.Cpu, $"Using memory {initedSize}/{reservedSize} bytes");
|
||||
}
|
||||
|
||||
private void ReserveNewSparseBlock()
|
||||
private TableSparseBlock ReserveNewSparseBlock()
|
||||
{
|
||||
var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
|
||||
|
||||
_sparseReserved.Add(block);
|
||||
_sparseReservedOffset = 0;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -369,12 +389,21 @@ namespace ARMeilleure.Common
|
|||
{
|
||||
_sparseLock.EnterWriteLock();
|
||||
|
||||
if (_sparseReserved.Count == 0 || _sparseReservedOffset == _sparseBlockSize)
|
||||
{
|
||||
ReserveNewSparseBlock();
|
||||
}
|
||||
SparseMemoryBlock block;
|
||||
|
||||
SparseMemoryBlock block = _sparseReserved.Last().Block;
|
||||
if (_sparseReserved.Count == 0)
|
||||
{
|
||||
block = ReserveNewSparseBlock().Block;
|
||||
}
|
||||
else
|
||||
{
|
||||
block = _sparseReserved.Last().Block;
|
||||
|
||||
if (_sparseReservedOffset == block.Block.Size)
|
||||
{
|
||||
block = ReserveNewSparseBlock().Block;
|
||||
}
|
||||
}
|
||||
|
||||
page = new AddressTablePage(true, block.Block.Pointer + (IntPtr)_sparseReservedOffset);
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace Ryujinx.Cpu.Jit
|
|||
/// <inheritdoc/>
|
||||
public void PrepareCodeRange(ulong address, ulong size)
|
||||
{
|
||||
_functionTable.SignalCodeRange(address, size);
|
||||
_translator.PrepareCodeRange(address, size);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace Ryujinx.Cpu.LightningJit
|
|||
/// <inheritdoc/>
|
||||
public void PrepareCodeRange(ulong address, ulong size)
|
||||
{
|
||||
_functionTable.SignalCodeRange(address, size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
Loading…
Reference in a new issue