Implement host tracked memory manager mode (#6356)
* Add host tracked memory manager mode * Skipping flush is no longer needed * Formatting + revert unrelated change * LightningJit: Ensure that dest register is saved for load ops that do partial updates * avoid allocations when doing address space lookup Add missing improvement * IsRmwMemory -> IsPartialRegisterUpdateMemory * Ensure we iterate all private allocations in range * PR feedback and potential fixes * Simplified bridges a lot * Skip calling SignalMappingChanged if Guest is true * Late map bridge too * Force address masking for prefetch instructions * Reprotection for bridges * Move partition list validation to separate debug method * Move host tracked related classes to HostTracked folder * New HostTracked namespace * Move host tracked modes to the end of enum to avoid PPTC invalidation --------- Co-authored-by: riperiperi <rhy3756547@hotmail.com>
This commit is contained in:
@ -0,0 +1,101 @@
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Cpu.Jit.HostTracked
|
||||
{
|
||||
class AddressSpacePartitionMultiAllocation : IDisposable
|
||||
{
|
||||
private readonly AddressSpacePartitionAllocation _baseMemory;
|
||||
private AddressSpacePartitionAllocation _baseMemoryRo;
|
||||
private AddressSpacePartitionAllocation _baseMemoryNone;
|
||||
|
||||
public AddressSpacePartitionMultiAllocation(AddressSpacePartitionAllocation baseMemory)
|
||||
{
|
||||
_baseMemory = baseMemory;
|
||||
}
|
||||
|
||||
public void MapView(MemoryBlock srcBlock, ulong srcOffset, ulong dstOffset, ulong size)
|
||||
{
|
||||
_baseMemory.MapView(srcBlock, srcOffset, dstOffset, size);
|
||||
|
||||
if (_baseMemoryRo.IsValid)
|
||||
{
|
||||
_baseMemoryRo.MapView(srcBlock, srcOffset, dstOffset, size);
|
||||
_baseMemoryRo.Reprotect(dstOffset, size, MemoryPermission.Read, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void LateMapView(MemoryBlock srcBlock, ulong srcOffset, ulong dstOffset, ulong size)
|
||||
{
|
||||
_baseMemoryRo.MapView(srcBlock, srcOffset, dstOffset, size);
|
||||
_baseMemoryRo.Reprotect(dstOffset, size, MemoryPermission.Read, false);
|
||||
}
|
||||
|
||||
public void UnmapView(MemoryBlock srcBlock, ulong offset, ulong size)
|
||||
{
|
||||
_baseMemory.UnmapView(srcBlock, offset, size);
|
||||
|
||||
if (_baseMemoryRo.IsValid)
|
||||
{
|
||||
_baseMemoryRo.UnmapView(srcBlock, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reprotect(ulong offset, ulong size, MemoryPermission permission, bool throwOnFail)
|
||||
{
|
||||
_baseMemory.Reprotect(offset, size, permission, throwOnFail);
|
||||
}
|
||||
|
||||
public IntPtr GetPointer(ulong offset, ulong size)
|
||||
{
|
||||
return _baseMemory.GetPointer(offset, size);
|
||||
}
|
||||
|
||||
public bool LazyInitMirrorForProtection(AddressSpacePartitioned addressSpace, ulong blockAddress, ulong blockSize, MemoryPermission permission)
|
||||
{
|
||||
if (permission == MemoryPermission.None && !_baseMemoryNone.IsValid)
|
||||
{
|
||||
_baseMemoryNone = addressSpace.CreateAsPartitionAllocation(blockAddress, blockSize);
|
||||
}
|
||||
else if (permission == MemoryPermission.Read && !_baseMemoryRo.IsValid)
|
||||
{
|
||||
_baseMemoryRo = addressSpace.CreateAsPartitionAllocation(blockAddress, blockSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IntPtr GetPointerForProtection(ulong offset, ulong size, MemoryPermission permission)
|
||||
{
|
||||
AddressSpacePartitionAllocation allocation = permission switch
|
||||
{
|
||||
MemoryPermission.ReadAndWrite => _baseMemory,
|
||||
MemoryPermission.Read => _baseMemoryRo,
|
||||
MemoryPermission.None => _baseMemoryNone,
|
||||
_ => throw new ArgumentException($"Invalid protection \"{permission}\"."),
|
||||
};
|
||||
|
||||
Debug.Assert(allocation.IsValid);
|
||||
|
||||
return allocation.GetPointer(offset, size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_baseMemory.Dispose();
|
||||
|
||||
if (_baseMemoryRo.IsValid)
|
||||
{
|
||||
_baseMemoryRo.Dispose();
|
||||
}
|
||||
|
||||
if (_baseMemoryNone.IsValid)
|
||||
{
|
||||
_baseMemoryNone.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user