Automatically size sparse blocks to minimize tracking ranges

This commit is contained in:
riperiperi 2024-06-24 19:43:22 +01:00
parent 74fe391150
commit 86f7b09b64
3 changed files with 39 additions and 8 deletions

View file

@ -1,3 +1,4 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Cpu.Signal; using Ryujinx.Cpu.Signal;
using Ryujinx.Memory; using Ryujinx.Memory;
@ -89,9 +90,9 @@ namespace ARMeilleure.Common
private readonly TEntry* _fillBottomLevelPtr; private readonly TEntry* _fillBottomLevelPtr;
private readonly List<TableSparseBlock> _sparseReserved; private readonly List<TableSparseBlock> _sparseReserved;
private readonly ulong _sparseBlockSize;
private readonly ReaderWriterLockSlim _sparseLock; private readonly ReaderWriterLockSlim _sparseLock;
private ulong _sparseBlockSize;
private ulong _sparseReservedOffset; private ulong _sparseReservedOffset;
/// <inheritdoc/> /// <inheritdoc/>
@ -170,7 +171,7 @@ namespace ARMeilleure.Common
_sparseReserved = new List<TableSparseBlock>(); _sparseReserved = new List<TableSparseBlock>();
_sparseLock = new ReaderWriterLockSlim(); _sparseLock = new ReaderWriterLockSlim();
_sparseBlockSize = bottomLevelSize << 3; _sparseBlockSize = bottomLevelSize;
} }
} }
@ -202,6 +203,23 @@ namespace ARMeilleure.Common
_fill = fillValue; _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/> /// <inheritdoc/>
public bool IsValid(ulong address) 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"); 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); var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
_sparseReserved.Add(block); _sparseReserved.Add(block);
_sparseReservedOffset = 0; _sparseReservedOffset = 0;
return block;
} }
/// <summary> /// <summary>
@ -369,12 +389,21 @@ namespace ARMeilleure.Common
{ {
_sparseLock.EnterWriteLock(); _sparseLock.EnterWriteLock();
if (_sparseReserved.Count == 0 || _sparseReservedOffset == _sparseBlockSize) SparseMemoryBlock block;
{
ReserveNewSparseBlock();
}
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); page = new AddressTablePage(true, block.Block.Pointer + (IntPtr)_sparseReservedOffset);

View file

@ -59,6 +59,7 @@ namespace Ryujinx.Cpu.Jit
/// <inheritdoc/> /// <inheritdoc/>
public void PrepareCodeRange(ulong address, ulong size) public void PrepareCodeRange(ulong address, ulong size)
{ {
_functionTable.SignalCodeRange(address, size);
_translator.PrepareCodeRange(address, size); _translator.PrepareCodeRange(address, size);
} }

View file

@ -53,6 +53,7 @@ namespace Ryujinx.Cpu.LightningJit
/// <inheritdoc/> /// <inheritdoc/>
public void PrepareCodeRange(ulong address, ulong size) public void PrepareCodeRange(ulong address, ulong size)
{ {
_functionTable.SignalCodeRange(address, size);
} }
public void Dispose() public void Dispose()