Use sparse memory when memory isn't software.

This commit is contained in:
riperiperi 2024-06-24 20:37:58 +01:00
parent 86f7b09b64
commit aa3b1e8996
4 changed files with 8 additions and 17 deletions

View file

@ -4,12 +4,6 @@ namespace ARMeilleure.Common
{ {
public interface IAddressTable<TEntry> : IDisposable where TEntry : unmanaged public interface IAddressTable<TEntry> : IDisposable where TEntry : unmanaged
{ {
/// <summary>
/// If true, the sparse 2-level table should be used to improve performance.
/// If false, the platform doesn't properly support it, or will be negatively impacted.
/// </summary>
static bool UseSparseTable { get; }
/// <summary> /// <summary>
/// Gets the bits used by the <see cref="Levels"/> of the <see cref="AddressTable{TEntry}"/> instance. /// Gets the bits used by the <see cref="Levels"/> of the <see cref="AddressTable{TEntry}"/> instance.
/// </summary> /// </summary>

View file

@ -1,3 +1,4 @@
using ARMeilleure.Memory;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Cpu.Signal; using Ryujinx.Cpu.Signal;
@ -17,12 +18,6 @@ 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>
/// If true, the sparse 2-level table should be used to improve performance.
/// If false, the platform doesn't properly support it, or will be negatively impacted.
/// </summary>
public static bool UseSparseTable => true;
private readonly struct AddressTablePage private readonly struct AddressTablePage
{ {
public readonly bool IsSparse; public readonly bool IsSparse;
@ -177,13 +172,15 @@ namespace ARMeilleure.Common
/// <summary> /// <summary>
/// Create an <see cref="AddressTable{TEntry}"/> instance for an ARM function table. /// Create an <see cref="AddressTable{TEntry}"/> instance for an ARM function table.
/// Selects the best table structure for A32/A64, taking into account whether sparse mapping is supported. /// Selects the best table structure for A32/A64, taking into account the selected memory manager type.
/// </summary> /// </summary>
/// <param name="for64Bits">True if the guest is A64, false otherwise</param> /// <param name="for64Bits">True if the guest is A64, false otherwise</param>
/// <param name="type">Memory manager type</param>
/// <returns>An <see cref="AddressTable{TEntry}"/> for ARM function lookup</returns> /// <returns>An <see cref="AddressTable{TEntry}"/> for ARM function lookup</returns>
public static AddressTable<TEntry> CreateForArm(bool for64Bits) public static AddressTable<TEntry> CreateForArm(bool for64Bits, MemoryManagerType type)
{ {
bool sparse = UseSparseTable; // Assume software memory means that we don't want to use any signal handlers.
bool sparse = type != MemoryManagerType.SoftwareMmu && type != MemoryManagerType.SoftwarePageTable;
return new AddressTable<TEntry>(AddressTablePresets.GetArmPreset(for64Bits, sparse), sparse); return new AddressTable<TEntry>(AddressTablePresets.GetArmPreset(for64Bits, sparse), sparse);
} }

View file

@ -15,7 +15,7 @@ namespace Ryujinx.Cpu.Jit
public JitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit) public JitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
{ {
_tickSource = tickSource; _tickSource = tickSource;
_functionTable = AddressTable<ulong>.CreateForArm(for64Bit); _functionTable = AddressTable<ulong>.CreateForArm(for64Bit, memory.Type);
_translator = new Translator(new JitMemoryAllocator(forJit: true), memory, _functionTable); _translator = new Translator(new JitMemoryAllocator(forJit: true), memory, _functionTable);

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Cpu.LightningJit
public LightningJitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit) public LightningJitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
{ {
_tickSource = tickSource; _tickSource = tickSource;
_functionTable = AddressTable<ulong>.CreateForArm(for64Bit); _functionTable = AddressTable<ulong>.CreateForArm(for64Bit, memory.Type);
_translator = new Translator(memory, _functionTable); _translator = new Translator(memory, _functionTable);