aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2022-08-30 22:15:16 -0300
committerMary-nyan <thog@protonmail.com>2022-09-10 16:23:49 +0200
commitc646638680f9b2dcc055ffbb280e970fcfe93aab (patch)
tree525568165d9fb850829b541948a3934b99539ab5
parent65f2a82b9745548748aa1d68547aff7a2cac574a (diff)
Update several methods to use GetNode directly and avoid array allocations
-rw-r--r--Ryujinx.Memory/WindowsShared/PlaceholderManager.cs125
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;
+ }
}
}
}