diff options
| author | gdk <gab.dark.100@gmail.com> | 2022-08-30 22:15:16 -0300 |
|---|---|---|
| committer | Mary-nyan <thog@protonmail.com> | 2022-09-10 16:23:49 +0200 |
| commit | c646638680f9b2dcc055ffbb280e970fcfe93aab (patch) | |
| tree | 525568165d9fb850829b541948a3934b99539ab5 | |
| parent | 65f2a82b9745548748aa1d68547aff7a2cac574a (diff) | |
Update several methods to use GetNode directly and avoid array allocations
| -rw-r--r-- | Ryujinx.Memory/WindowsShared/PlaceholderManager.cs | 125 |
1 files changed, 74 insertions, 51 deletions
diff --git a/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs b/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs index 1722d528..8624f817 100644 --- a/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs +++ b/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs @@ -89,9 +89,12 @@ namespace Ryujinx.Memory.WindowsShared lock (_mappings) { RangeNode<ulong> node = _mappings.GetNode(new RangeNode<ulong>(address, address + 1UL, default)); + RangeNode<ulong> successorNode; - for (; node != null; node = node.Successor) + for (; node != null; node = successorNode) { + successorNode = node.Successor; + if (IsMapped(node.Value)) { if (!WindowsApi.UnmapViewOfFile2(WindowsApi.CurrentProcessHandle, (IntPtr)node.Start, 2)) @@ -372,25 +375,25 @@ namespace Ryujinx.Memory.WindowsShared ulong endAddress = address + size; ulong blockAddress = (ulong)owner.Pointer; ulong blockEnd = blockAddress + owner.Size; - var overlaps = new RangeNode<ulong>[InitialOverlapsSize]; int unmappedCount = 0; lock (_mappings) { - int count = _mappings.GetNodes(address, endAddress, ref overlaps); + RangeNode<ulong> node = _mappings.GetNode(new RangeNode<ulong>(address, address + 1UL, default)); - if (count == 0) + if (node == null) { - // Nothing to coalesce if we no overlaps. + // Nothing to coalesce if we have no overlaps. return; } - RangeNode<ulong> predecessor = overlaps[0].Predecessor; - RangeNode<ulong> successor = overlaps[count - 1].Successor; + RangeNode<ulong> predecessor = node.Predecessor; + RangeNode<ulong> successor = null; - for (int index = 0; index < count; index++) + for (; node != null; node = successor) { - var overlap = overlaps[index]; + successor = node.Successor; + var overlap = node; if (!IsMapped(overlap.Value)) { @@ -400,6 +403,11 @@ namespace Ryujinx.Memory.WindowsShared _mappings.Remove(overlap); unmappedCount++; } + + if (node.End >= endAddress) + { + break; + } } if (predecessor != null && !IsMapped(predecessor.Value) && predecessor.Start >= blockAddress) @@ -469,46 +477,50 @@ namespace Ryujinx.Memory.WindowsShared ulong reprotectSize = (ulong)size; ulong endAddress = reprotectAddress + reprotectSize; - var overlaps = new RangeNode<ulong>[InitialOverlapsSize]; - int count; + bool success = true; lock (_mappings) { - count = _mappings.GetNodes(reprotectAddress, endAddress, ref overlaps); - } + RangeNode<ulong> node = _mappings.GetNode(new RangeNode<ulong>(reprotectAddress, reprotectAddress + 1UL, default)); + RangeNode<ulong> successorNode; - bool success = true; - - for (int index = 0; index < count; index++) - { - var overlap = overlaps[index]; + for (; node != null; node = successorNode) + { + successorNode = node.Successor; + var overlap = node; - ulong mappedAddress = overlap.Start; - ulong mappedSize = overlap.End - overlap.Start; + ulong mappedAddress = overlap.Start; + ulong mappedSize = overlap.End - overlap.Start; - if (mappedAddress < reprotectAddress) - { - ulong delta = reprotectAddress - mappedAddress; - mappedAddress = reprotectAddress; - mappedSize -= delta; - } + if (mappedAddress < reprotectAddress) + { + ulong delta = reprotectAddress - mappedAddress; + mappedAddress = reprotectAddress; + mappedSize -= delta; + } - ulong mappedEndAddress = mappedAddress + mappedSize; + ulong mappedEndAddress = mappedAddress + mappedSize; - if (mappedEndAddress > endAddress) - { - ulong delta = mappedEndAddress - endAddress; - mappedSize -= delta; - } + if (mappedEndAddress > endAddress) + { + ulong delta = mappedEndAddress - endAddress; + mappedSize -= delta; + } - if (!WindowsApi.VirtualProtect((IntPtr)mappedAddress, (IntPtr)mappedSize, WindowsApi.GetProtection(permission), out _)) - { - if (throwOnError) + if (!WindowsApi.VirtualProtect((IntPtr)mappedAddress, (IntPtr)mappedSize, WindowsApi.GetProtection(permission), out _)) { - throw new WindowsApiException("VirtualProtect"); + if (throwOnError) + { + throw new WindowsApiException("VirtualProtect"); + } + + success = false; } - success = false; + if (node.End >= endAddress) + { + break; + } } } @@ -565,26 +577,27 @@ namespace Ryujinx.Memory.WindowsShared private void UpdateProtection(ulong address, ulong size, MemoryPermission permission) { ulong endAddress = address + size; - var overlaps = new RangeNode<MemoryPermission>[InitialOverlapsSize]; - int count; lock (_protections) { - count = _protections.GetNodes(address, endAddress, ref overlaps); + RangeNode<MemoryPermission> node = _protections.GetNode(new RangeNode<MemoryPermission>(address, address + 1UL, default)); - if (count == 1 && - overlaps[0].Start <= address && - overlaps[0].End >= endAddress && - overlaps[0].Value == permission) + if (node != null && + node.Start <= address && + node.End >= endAddress && + node.Value == permission) { return; } + RangeNode<MemoryPermission> successorNode; + ulong startAddress = address; - for (int index = 0; index < count; index++) + for (; node != null; node = successorNode) { - var protection = overlaps[index]; + successorNode = node.Successor; + var protection = node; ulong protAddress = protection.Start; ulong protEndAddress = protection.End; @@ -616,6 +629,11 @@ namespace Ryujinx.Memory.WindowsShared _protections.Add(new RangeNode<MemoryPermission>(endAddress, protEndAddress, protPermission)); } } + + if (node.End >= endAddress) + { + break; + } } _protections.Add(new RangeNode<MemoryPermission>(startAddress, endAddress, permission)); @@ -630,16 +648,16 @@ namespace Ryujinx.Memory.WindowsShared private void RemoveProtection(ulong address, ulong size) { ulong endAddress = address + size; - var overlaps = new RangeNode<MemoryPermission>[InitialOverlapsSize]; - int count; lock (_protections) { - count = _protections.GetNodes(address, endAddress, ref overlaps); + RangeNode<MemoryPermission> node = _protections.GetNode(new RangeNode<MemoryPermission>(address, address + 1UL, default)); + RangeNode<MemoryPermission> successorNode; - for (int index = 0; index < count; index++) + for (; node != null; node = successorNode) { - var protection = overlaps[index]; + successorNode = node.Successor; + var protection = node; ulong protAddress = protection.Start; ulong protEndAddress = protection.End; @@ -656,6 +674,11 @@ namespace Ryujinx.Memory.WindowsShared { _protections.Add(new RangeNode<MemoryPermission>(endAddress, protEndAddress, protPermission)); } + + if (node.End >= endAddress) + { + break; + } } } } |
