diff options
| author | jhorv <38920027+jhorv@users.noreply.github.com> | 2024-04-21 15:34:04 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-21 16:34:04 -0300 |
| commit | 9b94662b4bb2ebf846e1baf45ba8097fcd7da684 (patch) | |
| tree | 2aa80e567d0c7b3828466b2888daa02039b1e4cc | |
| parent | 216026c096d844f8bf09ee0e185dec4111c64095 (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
| -rw-r--r-- | src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs | 64 | ||||
| -rw-r--r-- | src/Ryujinx.Memory/NativeMemoryManager.cs | 5 |
2 files changed, 69 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) { diff --git a/src/Ryujinx.Memory/NativeMemoryManager.cs b/src/Ryujinx.Memory/NativeMemoryManager.cs index 9ca63293..cb8d5c24 100644 --- a/src/Ryujinx.Memory/NativeMemoryManager.cs +++ b/src/Ryujinx.Memory/NativeMemoryManager.cs @@ -8,6 +8,11 @@ namespace Ryujinx.Memory private readonly T* _pointer; private readonly int _length; + public NativeMemoryManager(nuint pointer, int length) + : this((T*)pointer, length) + { + } + public NativeMemoryManager(T* pointer, int length) { _pointer = pointer; |
