aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Cpu/Jit
diff options
context:
space:
mode:
authorjhorv <38920027+jhorv@users.noreply.github.com>2024-04-21 15:34:04 -0400
committerGitHub <noreply@github.com>2024-04-21 16:34:04 -0300
commit9b94662b4bb2ebf846e1baf45ba8097fcd7da684 (patch)
tree2aa80e567d0c7b3828466b2888daa02039b1e4cc /src/Ryujinx.Cpu/Jit
parent216026c096d844f8bf09ee0e185dec4111c64095 (diff)
implement `MemoryManagerHostTracked.GetReadOnlySequence()` (#6695)
* implement `MemoryManagerHostTracked.GetReadOnlySequence()`, fixes crashes on game starts on MacOS * whitespace fixes * whitespace fixes * add missing call to `SignalMemoryTracking()` * adjust call to `SignalMemoryTracking()`` * don't use GetPhysicalAddressMemory() * add newline for consistency
Diffstat (limited to 'src/Ryujinx.Cpu/Jit')
-rw-r--r--src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs
index 0acb57be..663d0aeb 100644
--- a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs
+++ b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs
@@ -85,6 +85,70 @@ namespace Ryujinx.Cpu.Jit
_addressSpace = new(Tracking, backingMemory, _nativePageTable, useProtectionMirrors);
}
+ public override ReadOnlySequence<byte> GetReadOnlySequence(ulong va, int size, bool tracked = false)
+ {
+ if (size == 0)
+ {
+ return ReadOnlySequence<byte>.Empty;
+ }
+
+ try
+ {
+ if (tracked)
+ {
+ SignalMemoryTracking(va, (ulong)size, false);
+ }
+ else
+ {
+ AssertValidAddressAndSize(va, (ulong)size);
+ }
+
+ ulong endVa = va + (ulong)size;
+ int offset = 0;
+
+ BytesReadOnlySequenceSegment first = null, last = null;
+
+ while (va < endVa)
+ {
+ (MemoryBlock memory, ulong rangeOffset, ulong copySize) = GetMemoryOffsetAndSize(va, (ulong)(size - offset));
+
+ Memory<byte> physicalMemory = memory.GetMemory(rangeOffset, (int)copySize);
+
+ if (first is null)
+ {
+ first = last = new BytesReadOnlySequenceSegment(physicalMemory);
+ }
+ else
+ {
+ if (last.IsContiguousWith(physicalMemory, out nuint contiguousStart, out int contiguousSize))
+ {
+ Memory<byte> contiguousPhysicalMemory = new NativeMemoryManager<byte>(contiguousStart, contiguousSize).Memory;
+
+ last.Replace(contiguousPhysicalMemory);
+ }
+ else
+ {
+ last = last.Append(physicalMemory);
+ }
+ }
+
+ va += copySize;
+ offset += (int)copySize;
+ }
+
+ return new ReadOnlySequence<byte>(first, 0, last, (int)(size - last.RunningIndex));
+ }
+ catch (InvalidMemoryRegionException)
+ {
+ if (_invalidAccessHandler == null || !_invalidAccessHandler(va))
+ {
+ throw;
+ }
+
+ return ReadOnlySequence<byte>.Empty;
+ }
+ }
+
/// <inheritdoc/>
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
{