Some cleanup
This commit is contained in:
parent
aa3b1e8996
commit
a37f65e87d
5 changed files with 39 additions and 14 deletions
|
@ -5,12 +5,18 @@ namespace ARMeilleure.Common
|
||||||
public interface IAddressTable<TEntry> : IDisposable where TEntry : unmanaged
|
public interface IAddressTable<TEntry> : IDisposable where TEntry : unmanaged
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the bits used by the <see cref="Levels"/> of the <see cref="AddressTable{TEntry}"/> instance.
|
/// True if the address table's bottom level is sparsely mapped.
|
||||||
|
/// This also ensures the second bottom level is filled with a dummy page rather than 0.
|
||||||
|
/// </summary>
|
||||||
|
bool Sparse { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the bits used by the <see cref="Levels"/> of the <see cref="IAddressTable{TEntry}"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ulong Mask { get; }
|
ulong Mask { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="Level"/>s used by the <see cref="AddressTable{TEntry}"/> instance.
|
/// Gets the <see cref="AddressTableLevel"/>s used by the <see cref="IAddressTable{TEntry}"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
AddressTableLevel[] Levels { get; }
|
AddressTableLevel[] Levels { get; }
|
||||||
|
|
||||||
|
@ -27,7 +33,7 @@ namespace ARMeilleure.Common
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if the specified <paramref name="address"/> is in the range of the
|
/// Determines if the specified <paramref name="address"/> is in the range of the
|
||||||
/// <see cref="AddressTable{TEntry}"/>.
|
/// <see cref="IAddressTable{TEntry}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">Guest address</param>
|
/// <param name="address">Guest address</param>
|
||||||
/// <returns><see langword="true"/> if is valid; otherwise <see langword="false"/></returns>
|
/// <returns><see langword="true"/> if is valid; otherwise <see langword="false"/></returns>
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
hostAddress = context.Load(OperandType.I64, hostAddressAddr);
|
hostAddress = context.Load(OperandType.I64, hostAddressAddr);
|
||||||
}
|
}
|
||||||
else if (table.Levels.Length == 2)
|
else if (table.Sparse && table.Levels.Length == 2)
|
||||||
{
|
{
|
||||||
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||||
// Deliberately attempts to avoid branches.
|
// Deliberately attempts to avoid branches.
|
||||||
|
|
|
@ -18,9 +18,19 @@ namespace ARMeilleure.Common
|
||||||
/// <typeparam name="TEntry">Type of the value</typeparam>
|
/// <typeparam name="TEntry">Type of the value</typeparam>
|
||||||
public unsafe class AddressTable<TEntry> : IAddressTable<TEntry> where TEntry : unmanaged
|
public unsafe class AddressTable<TEntry> : IAddressTable<TEntry> where TEntry : unmanaged
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a page of the address table.
|
||||||
|
/// </summary>
|
||||||
private readonly struct AddressTablePage
|
private readonly struct AddressTablePage
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True if the allocation belongs to a sparse block, false otherwise.
|
||||||
|
/// </summary>
|
||||||
public readonly bool IsSparse;
|
public readonly bool IsSparse;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base address for the page.
|
||||||
|
/// </summary>
|
||||||
public readonly IntPtr Address;
|
public readonly IntPtr Address;
|
||||||
|
|
||||||
public AddressTablePage(bool isSparse, IntPtr address)
|
public AddressTablePage(bool isSparse, IntPtr address)
|
||||||
|
@ -36,13 +46,13 @@ namespace ARMeilleure.Common
|
||||||
private readonly struct TableSparseBlock : IDisposable
|
private readonly struct TableSparseBlock : IDisposable
|
||||||
{
|
{
|
||||||
public readonly SparseMemoryBlock Block;
|
public readonly SparseMemoryBlock Block;
|
||||||
public readonly TrackingEventDelegate TrackingEvent;
|
private readonly TrackingEventDelegate _trackingEvent;
|
||||||
|
|
||||||
public TableSparseBlock(ulong size, Action<IntPtr> ensureMapped, PageInitDelegate pageInit)
|
public TableSparseBlock(ulong size, Action<IntPtr> ensureMapped, PageInitDelegate pageInit)
|
||||||
{
|
{
|
||||||
var block = new SparseMemoryBlock(size, pageInit, null);
|
var block = new SparseMemoryBlock(size, pageInit, null);
|
||||||
|
|
||||||
TrackingEvent = (ulong address, ulong size, bool write) =>
|
_trackingEvent = (ulong address, ulong size, bool write) =>
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.Cpu, $"Triggered from exception");
|
Logger.Error?.PrintMsg(LogClass.Cpu, $"Triggered from exception");
|
||||||
|
|
||||||
|
@ -56,7 +66,7 @@ namespace ARMeilleure.Common
|
||||||
bool added = NativeSignalHandler.AddTrackedRegion(
|
bool added = NativeSignalHandler.AddTrackedRegion(
|
||||||
(nuint)block.Block.Pointer,
|
(nuint)block.Block.Pointer,
|
||||||
(nuint)(block.Block.Pointer + (IntPtr)block.Block.Size),
|
(nuint)(block.Block.Pointer + (IntPtr)block.Block.Size),
|
||||||
Marshal.GetFunctionPointerForDelegate(TrackingEvent));
|
Marshal.GetFunctionPointerForDelegate(_trackingEvent));
|
||||||
|
|
||||||
if (!added)
|
if (!added)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +89,6 @@ namespace ARMeilleure.Common
|
||||||
private readonly List<AddressTablePage> _pages;
|
private readonly List<AddressTablePage> _pages;
|
||||||
private TEntry _fill;
|
private TEntry _fill;
|
||||||
|
|
||||||
private readonly bool _sparse;
|
|
||||||
private readonly MemoryBlock _sparseFill;
|
private readonly MemoryBlock _sparseFill;
|
||||||
private readonly SparseMemoryBlock _fillBottomLevel;
|
private readonly SparseMemoryBlock _fillBottomLevel;
|
||||||
private readonly TEntry* _fillBottomLevelPtr;
|
private readonly TEntry* _fillBottomLevelPtr;
|
||||||
|
@ -90,6 +99,8 @@ namespace ARMeilleure.Common
|
||||||
private ulong _sparseBlockSize;
|
private ulong _sparseBlockSize;
|
||||||
private ulong _sparseReservedOffset;
|
private ulong _sparseReservedOffset;
|
||||||
|
|
||||||
|
public bool Sparse { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ulong Mask { get; }
|
public ulong Mask { get; }
|
||||||
|
|
||||||
|
@ -150,7 +161,7 @@ namespace ARMeilleure.Common
|
||||||
Mask |= level.Mask;
|
Mask |= level.Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sparse = sparse;
|
Sparse = sparse;
|
||||||
|
|
||||||
if (sparse)
|
if (sparse)
|
||||||
{
|
{
|
||||||
|
@ -279,9 +290,13 @@ namespace ARMeilleure.Common
|
||||||
return (TEntry*)page;
|
return (TEntry*)page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensure the given pointer is mapped in any overlapping sparse reservations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ptr">Pointer to be mapped</param>
|
||||||
private void EnsureMapped(IntPtr ptr)
|
private void EnsureMapped(IntPtr ptr)
|
||||||
{
|
{
|
||||||
if (_sparse)
|
if (Sparse)
|
||||||
{
|
{
|
||||||
// Check sparse allocations to see if the pointer is in any of them.
|
// Check sparse allocations to see if the pointer is in any of them.
|
||||||
// Ensure the page is committed if there's a match.
|
// Ensure the page is committed if there's a match.
|
||||||
|
@ -356,6 +371,10 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reserve a new sparse block, and add it to the list.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The new sparse block that was added</returns>
|
||||||
private TableSparseBlock ReserveNewSparseBlock()
|
private TableSparseBlock ReserveNewSparseBlock()
|
||||||
{
|
{
|
||||||
var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
|
var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
|
||||||
|
@ -382,7 +401,7 @@ namespace ARMeilleure.Common
|
||||||
|
|
||||||
AddressTablePage page;
|
AddressTablePage page;
|
||||||
|
|
||||||
if (_sparse && leaf)
|
if (Sparse && leaf)
|
||||||
{
|
{
|
||||||
_sparseLock.EnterWriteLock();
|
_sparseLock.EnterWriteLock();
|
||||||
|
|
||||||
|
@ -450,7 +469,7 @@ namespace ARMeilleure.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sparse)
|
if (Sparse)
|
||||||
{
|
{
|
||||||
foreach (TableSparseBlock block in _sparseReserved)
|
foreach (TableSparseBlock block in _sparseReserved)
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
int tempRegister;
|
int tempRegister;
|
||||||
int tempGuestAddress = -1;
|
int tempGuestAddress = -1;
|
||||||
|
|
||||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Sparse && funcTable.Levels.Length == 2;
|
||||||
|
|
||||||
if (guestAddress.Kind == OperandKind.Constant)
|
if (guestAddress.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
|
|
|
@ -307,7 +307,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
||||||
int tempRegister;
|
int tempRegister;
|
||||||
int tempGuestAddress = -1;
|
int tempGuestAddress = -1;
|
||||||
|
|
||||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Sparse && funcTable.Levels.Length == 2;
|
||||||
|
|
||||||
if (guestAddress.Kind == OperandKind.Constant)
|
if (guestAddress.Kind == OperandKind.Constant)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue