aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-03-26 23:33:24 -0300
committerGitHub <noreply@github.com>2024-03-26 23:33:24 -0300
commitb323a017385ac6e08db4025fe4ef1bfbb41607ab (patch)
tree33392d69cea70232cb0342e38a924dc31fb22719 /src/Ryujinx.Cpu/MemoryEhMeilleure.cs
parentf6d24449b6e1ebe753c0a8095a435820c0948f19 (diff)
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>
Diffstat (limited to 'src/Ryujinx.Cpu/MemoryEhMeilleure.cs')
-rw-r--r--src/Ryujinx.Cpu/MemoryEhMeilleure.cs32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
index f3a5b056..379ace94 100644
--- a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
+++ b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common;
using Ryujinx.Cpu.Signal;
using Ryujinx.Memory;
using Ryujinx.Memory.Tracking;
@@ -8,19 +9,27 @@ namespace Ryujinx.Cpu
{
public class MemoryEhMeilleure : IDisposable
{
- private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
+ public delegate ulong TrackingEventDelegate(ulong address, ulong size, bool write);
+ private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent;
+ private readonly ulong _pageSize;
+
private readonly ulong _baseAddress;
private readonly ulong _mirrorAddress;
- public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
+ public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking, TrackingEventDelegate trackingEvent = null)
{
_baseAddress = (ulong)addressSpace.Pointer;
+
ulong endAddress = _baseAddress + addressSpace.Size;
- _trackingEvent = tracking.VirtualMemoryEvent;
+ _tracking = tracking;
+ _trackingEvent = trackingEvent ?? VirtualMemoryEvent;
+
+ _pageSize = MemoryBlock.GetPageSize();
+
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added)
@@ -28,7 +37,7 @@ namespace Ryujinx.Cpu
throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
}
- if (OperatingSystem.IsWindows())
+ if (OperatingSystem.IsWindows() && addressSpaceMirror != null)
{
// Add a tracking event with no signal handler for the mirror on Windows.
// The native handler has its own code to check for the partial overlap race when regions are protected by accident,
@@ -46,6 +55,21 @@ namespace Ryujinx.Cpu
}
}
+ private ulong VirtualMemoryEvent(ulong address, ulong size, bool write)
+ {
+ ulong pageSize = _pageSize;
+ ulong addressAligned = BitUtils.AlignDown(address, pageSize);
+ ulong endAddressAligned = BitUtils.AlignUp(address + size, pageSize);
+ ulong sizeAligned = endAddressAligned - addressAligned;
+
+ if (_tracking.VirtualMemoryEvent(addressAligned, sizeAligned, write))
+ {
+ return _baseAddress + address;
+ }
+
+ return 0;
+ }
+
public void Dispose()
{
GC.SuppressFinalize(this);