Optimize address translation and write tracking on the MMU (#571)

* Implement faster address translation and write tracking on the MMU

* Rename MemoryAlloc to MemoryManagement, and other nits

* Support multi-level page tables

* Fix typo

* Reword comment a bit

* Support scalar vector loads/stores on the memory fast path, and minor fixes

* Add missing cast

* Alignment

* Fix VirtualFree function signature

* Change MemoryProtection enum to uint aswell for consistency
This commit is contained in:
gdkchan 2019-02-24 04:24:35 -03:00 committed by jduncanator
parent a3d46e4133
commit 5001f78b1d
24 changed files with 1005 additions and 621 deletions

View file

@ -80,12 +80,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public bool IsPaused { get; private set; }
public Translator Translator { get; private set; }
public MemoryManager CpuMemory { get; private set; }
public Translator Translator { get; private set; }
private SvcHandler _svcHandler;
private Horizon _system;
public HleProcessDebugger Debugger { get; private set; }
public KProcess(Horizon system) : base(system)
@ -93,14 +95,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_processLock = new object();
_threadingLock = new object();
CpuMemory = new MemoryManager(system.Device.Memory.RamPointer);
CpuMemory.InvalidAccess += InvalidAccessHandler;
_system = system;
AddressArbiter = new KAddressArbiter(system);
MemoryManager = new KMemoryManager(system, CpuMemory);
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
_freeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
@ -110,10 +108,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_threads = new LinkedList<KThread>();
Translator = new Translator(CpuMemory);
Translator.CpuTrace += CpuTraceHandler;
_svcHandler = new SvcHandler(system.Device, this);
Debugger = new HleProcessDebugger(this);
@ -131,6 +125,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);
InitializeMemoryManager(addrSpaceType, memRegion);
bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;
ulong codeAddress = creationInfo.CodeAddress;
@ -238,6 +234,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);
InitializeMemoryManager(addrSpaceType, memRegion);
bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;
ulong codeAddress = creationInfo.CodeAddress;
@ -405,7 +403,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
case AddressSpaceType.Addr36Bits:
case AddressSpaceType.Addr39Bits:
_memoryUsageCapacity = MemoryManager.HeapRegionEnd -
MemoryManager.HeapRegionStart;
MemoryManager.HeapRegionStart;
break;
case AddressSpaceType.Addr32BitsNoMap:
@ -1010,9 +1008,29 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
private void InvalidAccessHandler(object sender, MemoryAccessEventArgs e)
private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
{
PrintCurrentThreadStackTrace();
int addrSpaceBits;
switch (addrSpaceType)
{
case AddressSpaceType.Addr32Bits: addrSpaceBits = 32; break;
case AddressSpaceType.Addr36Bits: addrSpaceBits = 36; break;
case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;
case AddressSpaceType.Addr39Bits: addrSpaceBits = 39; break;
default: throw new ArgumentException(nameof(addrSpaceType));
}
bool useFlatPageTable = memRegion == MemoryRegion.Application;
CpuMemory = new MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);
MemoryManager = new KMemoryManager(_system, CpuMemory);
Translator = new Translator(CpuMemory);
Translator.CpuTrace += CpuTraceHandler;
}
public void PrintCurrentThreadStackTrace()