Merge branch 'master' into pptc_and_pool_enhancements
This commit is contained in:
@@ -15,7 +15,7 @@ namespace Ryujinx.Memory
|
||||
|
||||
void Fill(ulong va, ulong size, byte value)
|
||||
{
|
||||
const int MaxChunkSize = 1 << 30;
|
||||
const int MaxChunkSize = 1 << 24;
|
||||
|
||||
for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Ryujinx.Memory
|
||||
/// <exception cref="InvalidMemoryRegionException">Throw when <paramref name="srcOffset"/>, <paramref name="dstOffset"/> or <paramref name="size"/> is out of range</exception>
|
||||
public void Copy(ulong dstOffset, ulong srcOffset, ulong size)
|
||||
{
|
||||
const int MaxChunkSize = 1 << 30;
|
||||
const int MaxChunkSize = 1 << 24;
|
||||
|
||||
for (ulong offset = 0; offset < size; offset += MaxChunkSize)
|
||||
{
|
||||
@@ -153,7 +153,7 @@ namespace Ryujinx.Memory
|
||||
/// <exception cref="InvalidMemoryRegionException">Throw when either <paramref name="offset"/> or <paramref name="size"/> are out of range</exception>
|
||||
public void ZeroFill(ulong offset, ulong size)
|
||||
{
|
||||
const int MaxChunkSize = 1 << 30;
|
||||
const int MaxChunkSize = 1 << 24;
|
||||
|
||||
for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
|
||||
{
|
||||
|
||||
@@ -12,16 +12,16 @@ namespace Ryujinx.Memory.Range
|
||||
{
|
||||
private const int ArrayGrowthSize = 32;
|
||||
|
||||
private readonly List<T> _items;
|
||||
protected readonly List<T> Items;
|
||||
|
||||
public int Count => _items.Count;
|
||||
public int Count => Items.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new range list.
|
||||
/// </summary>
|
||||
public RangeList()
|
||||
{
|
||||
_items = new List<T>();
|
||||
Items = new List<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -37,7 +37,7 @@ namespace Ryujinx.Memory.Range
|
||||
index = ~index;
|
||||
}
|
||||
|
||||
_items.Insert(index, item);
|
||||
Items.Insert(index, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -51,21 +51,21 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
while (index > 0 && _items[index - 1].Address == item.Address)
|
||||
while (index > 0 && Items[index - 1].Address == item.Address)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
|
||||
while (index < _items.Count)
|
||||
while (index < Items.Count)
|
||||
{
|
||||
if (_items[index].Equals(item))
|
||||
if (Items[index].Equals(item))
|
||||
{
|
||||
_items.RemoveAt(index);
|
||||
Items.RemoveAt(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_items[index].Address > item.Address)
|
||||
if (Items[index].Address > item.Address)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ namespace Ryujinx.Memory.Range
|
||||
return default(T);
|
||||
}
|
||||
|
||||
return _items[index];
|
||||
return Items[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,7 +137,7 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
ulong endAddress = address + size;
|
||||
|
||||
foreach (T item in _items)
|
||||
foreach (T item in Items)
|
||||
{
|
||||
if (item.Address >= endAddress)
|
||||
{
|
||||
@@ -196,7 +196,7 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
while (index > 0 && _items[index - 1].OverlapsWith(address, size))
|
||||
while (index > 0 && Items[index - 1].OverlapsWith(address, size))
|
||||
{
|
||||
index--;
|
||||
}
|
||||
@@ -208,9 +208,9 @@ namespace Ryujinx.Memory.Range
|
||||
Array.Resize(ref output, outputIndex + ArrayGrowthSize);
|
||||
}
|
||||
|
||||
output[outputIndex++] = _items[index++];
|
||||
output[outputIndex++] = Items[index++];
|
||||
}
|
||||
while (index < _items.Count && _items[index].OverlapsWith(address, size));
|
||||
while (index < Items.Count && Items[index].OverlapsWith(address, size));
|
||||
}
|
||||
|
||||
return outputIndex;
|
||||
@@ -230,14 +230,14 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
while (index > 0 && _items[index - 1].Address == address)
|
||||
while (index > 0 && Items[index - 1].Address == address)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
|
||||
while (index < _items.Count)
|
||||
while (index < Items.Count)
|
||||
{
|
||||
T overlap = _items[index++];
|
||||
T overlap = Items[index++];
|
||||
|
||||
if (overlap.Address != address)
|
||||
{
|
||||
@@ -264,7 +264,7 @@ namespace Ryujinx.Memory.Range
|
||||
private int BinarySearch(ulong address)
|
||||
{
|
||||
int left = 0;
|
||||
int right = _items.Count - 1;
|
||||
int right = Items.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
@@ -272,7 +272,7 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
int middle = left + (range >> 1);
|
||||
|
||||
T item = _items[middle];
|
||||
T item = Items[middle];
|
||||
|
||||
if (item.Address == address)
|
||||
{
|
||||
@@ -301,7 +301,7 @@ namespace Ryujinx.Memory.Range
|
||||
private int BinarySearch(ulong address, ulong size)
|
||||
{
|
||||
int left = 0;
|
||||
int right = _items.Count - 1;
|
||||
int right = Items.Count - 1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
@@ -309,7 +309,7 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
int middle = left + (range >> 1);
|
||||
|
||||
T item = _items[middle];
|
||||
T item = Items[middle];
|
||||
|
||||
if (item.OverlapsWith(address, size))
|
||||
{
|
||||
@@ -331,12 +331,12 @@ namespace Ryujinx.Memory.Range
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
return Items.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return _items.GetEnumerator();
|
||||
return Items.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,17 @@ namespace Ryujinx.Memory.Tracking
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterAction(ulong address, ulong size, RegionSignal action)
|
||||
{
|
||||
int startHandle = (int)((address - Address) / Granularity);
|
||||
int lastHandle = (int)((address + (size - 1) - Address) / Granularity);
|
||||
|
||||
for (int i = startHandle; i <= lastHandle; i++)
|
||||
{
|
||||
_handles[i].RegisterAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var handle in _handles)
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Ryujinx.Memory.Tracking
|
||||
private readonly MemoryTracking _tracking;
|
||||
|
||||
internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read);
|
||||
internal RegionSignal PreAction => _preAction;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new region handle. The handle is registered with the given tracking object,
|
||||
|
||||
@@ -41,6 +41,17 @@ namespace Ryujinx.Memory.Tracking
|
||||
Dirty = true;
|
||||
}
|
||||
|
||||
public void RegisterAction(RegionSignal action)
|
||||
{
|
||||
foreach (var handle in _handles)
|
||||
{
|
||||
if (handle != null)
|
||||
{
|
||||
handle?.RegisterAction((address, size) => action(handle.Address, handle.Size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void QueryModified(Action<ulong, ulong> modifiedAction)
|
||||
{
|
||||
if (!Dirty)
|
||||
@@ -66,14 +77,23 @@ namespace Ryujinx.Memory.Tracking
|
||||
ulong size = HandlesToBytes(splitIndex - handleIndex);
|
||||
|
||||
// First, the target handle must be removed. Its data can still be used to determine the new handles.
|
||||
RegionSignal signal = handle.PreAction;
|
||||
handle.Dispose();
|
||||
|
||||
RegionHandle splitLow = _tracking.BeginTracking(address, size);
|
||||
splitLow.Parent = this;
|
||||
if (signal != null)
|
||||
{
|
||||
splitLow.RegisterAction(signal);
|
||||
}
|
||||
_handles[handleIndex] = splitLow;
|
||||
|
||||
RegionHandle splitHigh = _tracking.BeginTracking(address + size, handle.Size - size);
|
||||
splitHigh.Parent = this;
|
||||
if (signal != null)
|
||||
{
|
||||
splitHigh.RegisterAction(signal);
|
||||
}
|
||||
_handles[splitIndex] = splitHigh;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace Ryujinx.Memory.Tracking
|
||||
|
||||
public override void Signal(ulong address, ulong size, bool write)
|
||||
{
|
||||
_tracking.ProtectVirtualRegion(this, MemoryPermission.ReadAndWrite); // Remove our protection immedately.
|
||||
|
||||
foreach (var handle in Handles)
|
||||
{
|
||||
handle.Signal(address, size, write);
|
||||
}
|
||||
|
||||
UpdateProtection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user