Memory Changes part 2

* Slightly refactors RangeLists from the last Memory Changes MR, which fixes issue 61.

* Convert as many const size array iterators to span iterators as possible. When iterating over a const size array, every iteration created a Span, now only the first iteration does in most places.

* Now using object pooling for a few object types that were rapidly deleted and recreated.

* Converted a few flag checks to binary operations to save memory allocations.
This commit is contained in:
LotP
2025-09-12 21:24:19 -05:00
committed by KeatonTheBot
parent ff0daa9f35
commit 3deddbd491
89 changed files with 2121 additions and 1154 deletions
@@ -10,7 +10,7 @@ namespace Ryujinx.Memory.Range
/// A range list that assumes ranges are non-overlapping, with list items that can be split in two to avoid overlaps.
/// </summary>
/// <typeparam name="T">Type of the range.</typeparam>
public class NonOverlappingRangeList<T> : RangeListBase<T> where T : INonOverlappingRange
public unsafe class NonOverlappingRangeList<T> : RangeListBase<T> where T : class, INonOverlappingRange
{
private readonly Dictionary<ulong, RangeItem<T>> _quickAccess = new(AddressEqualityComparer.Comparer);
private readonly Dictionary<ulong, RangeItem<T>> _fastQuickAccess = new(AddressEqualityComparer.Comparer);
@@ -196,6 +196,16 @@ namespace Ryujinx.Memory.Range
int startIndex = BinarySearch(startItem.Address);
int endIndex = BinarySearch(endItem.Address);
for (int i = startIndex; i <= endIndex; i++)
{
_quickAccess.Remove(Items[i].Address);
foreach (ulong addr in Items[i].QuickAccessAddresses)
{
_quickAccess.Remove(addr);
_fastQuickAccess.Remove(addr);
}
}
if (endIndex < Count - 1)
{
Items[endIndex + 1].Previous = startIndex > 0 ? Items[startIndex - 1] : null;
@@ -213,17 +223,6 @@ namespace Ryujinx.Memory.Range
}
Count -= endIndex - startIndex + 1;
while (startItem != endItem.Next)
{
_quickAccess.Remove(startItem.Address);
foreach (ulong addr in startItem.QuickAccessAddresses)
{
_quickAccess.Remove(addr);
_fastQuickAccess.Remove(addr);
}
startItem = startItem.Next;
}
}
/// <summary>
@@ -240,19 +239,22 @@ namespace Ryujinx.Memory.Range
return;
}
RangeItem<T> startItem = Items[startIndex];
int endIndex = startIndex;
while (startItem is not null && startItem.Address < address + size)
while (Items[endIndex] is not null && Items[endIndex].Address < address + size)
{
_quickAccess.Remove(startItem.Address);
foreach (ulong addr in startItem.QuickAccessAddresses)
_quickAccess.Remove(Items[endIndex].Address);
foreach (ulong addr in Items[endIndex].QuickAccessAddresses)
{
_quickAccess.Remove(addr);
_fastQuickAccess.Remove(addr);
}
startItem = startItem.Next;
if (endIndex == Count - 1)
{
break;
}
endIndex++;
}