Replace and remove obsolete ByteMemoryPool type (#7155)
* refactor: replace usage of ByteMemoryPool with MemoryOwner<byte> * refactor: delete unused ByteMemoryPool and ByteMemoryPool.ByteMemoryPoolBuffer types * refactor: change IMemoryOwner<byte> return types to MemoryOwner<byte> * fix(perf): get span via `MemoryOwner<T>.Span` directly instead of `MemoryOwner<T>.Memory.Span` * fix(perf): get span via MemoryOwner<T>.Span directly instead of `MemoryOwner<T>.Memory.Span` * fix(perf): get span via MemoryOwner<T>.Span directly instead of `MemoryOwner<T>.Memory.Span`
This commit is contained in:
parent
4a4b11871e
commit
7969fb6bba
6 changed files with 13 additions and 171 deletions
|
@ -1,51 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Buffers;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Memory
|
|
||||||
{
|
|
||||||
public partial class ByteMemoryPool
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a <see cref="IMemoryOwner{Byte}"/> that wraps an array rented from
|
|
||||||
/// <see cref="ArrayPool{Byte}.Shared"/> and exposes it as <see cref="Memory{Byte}"/>
|
|
||||||
/// with a length of the requested size.
|
|
||||||
/// </summary>
|
|
||||||
private sealed class ByteMemoryPoolBuffer : IMemoryOwner<byte>
|
|
||||||
{
|
|
||||||
private byte[] _array;
|
|
||||||
private readonly int _length;
|
|
||||||
|
|
||||||
public ByteMemoryPoolBuffer(int length)
|
|
||||||
{
|
|
||||||
_array = ArrayPool<byte>.Shared.Rent(length);
|
|
||||||
_length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a <see cref="Memory{Byte}"/> belonging to this owner.
|
|
||||||
/// </summary>
|
|
||||||
public Memory<byte> Memory
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
byte[] array = _array;
|
|
||||||
|
|
||||||
ObjectDisposedException.ThrowIf(array is null, this);
|
|
||||||
|
|
||||||
return new Memory<byte>(array, 0, _length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
var array = Interlocked.Exchange(ref _array, null);
|
|
||||||
|
|
||||||
if (array != null)
|
|
||||||
{
|
|
||||||
ArrayPool<byte>.Shared.Return(array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Buffers;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Memory
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a pool of re-usable byte array instances.
|
|
||||||
/// </summary>
|
|
||||||
public static partial class ByteMemoryPool
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the maximum buffer size supported by this pool.
|
|
||||||
/// </summary>
|
|
||||||
public static int MaxBufferSize => Array.MaxLength;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer may contain data from a prior use.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> Rent(long length)
|
|
||||||
=> RentImpl(checked((int)length));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer may contain data from a prior use.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> Rent(ulong length)
|
|
||||||
=> RentImpl(checked((int)length));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer may contain data from a prior use.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> Rent(int length)
|
|
||||||
=> RentImpl(length);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer's contents are cleared (set to all 0s) before returning.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> RentCleared(long length)
|
|
||||||
=> RentCleared(checked((int)length));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer's contents are cleared (set to all 0s) before returning.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> RentCleared(ulong length)
|
|
||||||
=> RentCleared(checked((int)length));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>.
|
|
||||||
/// The buffer's contents are cleared (set to all 0s) before returning.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="length">The buffer's required length in bytes</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|
||||||
public static IMemoryOwner<byte> RentCleared(int length)
|
|
||||||
{
|
|
||||||
var buffer = RentImpl(length);
|
|
||||||
|
|
||||||
buffer.Memory.Span.Clear();
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies <paramref name="buffer"/> into a newly rented byte memory buffer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="buffer">The byte buffer to copy</param>
|
|
||||||
/// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory with <paramref name="buffer"/> copied to it</returns>
|
|
||||||
public static IMemoryOwner<byte> RentCopy(ReadOnlySpan<byte> buffer)
|
|
||||||
{
|
|
||||||
var copy = RentImpl(buffer.Length);
|
|
||||||
|
|
||||||
buffer.CopyTo(copy.Memory.Span);
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ByteMemoryPoolBuffer RentImpl(int length)
|
|
||||||
{
|
|
||||||
if ((uint)length > Array.MaxLength)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(length), length, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ByteMemoryPoolBuffer(length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -42,14 +42,14 @@ namespace Ryujinx.Common
|
||||||
return StreamUtils.StreamToBytes(stream);
|
return StreamUtils.StreamToBytes(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ReadFileToRentedMemory(string filename)
|
public static MemoryOwner<byte> ReadFileToRentedMemory(string filename)
|
||||||
{
|
{
|
||||||
var (assembly, path) = ResolveManifestPath(filename);
|
var (assembly, path) = ResolveManifestPath(filename);
|
||||||
|
|
||||||
return ReadFileToRentedMemory(assembly, path);
|
return ReadFileToRentedMemory(assembly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename)
|
public static MemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename)
|
||||||
{
|
{
|
||||||
using var stream = GetStream(assembly, filename);
|
using var stream = GetStream(assembly, filename);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Microsoft.IO;
|
using Microsoft.IO;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System.Buffers;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -16,7 +15,7 @@ namespace Ryujinx.Common.Utilities
|
||||||
return output.ToArray();
|
return output.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMemoryOwner<byte> StreamToRentedMemory(Stream input)
|
public static MemoryOwner<byte> StreamToRentedMemory(Stream input)
|
||||||
{
|
{
|
||||||
if (input is MemoryStream inputMemoryStream)
|
if (input is MemoryStream inputMemoryStream)
|
||||||
{
|
{
|
||||||
|
@ -26,9 +25,9 @@ namespace Ryujinx.Common.Utilities
|
||||||
{
|
{
|
||||||
long bytesExpected = input.Length;
|
long bytesExpected = input.Length;
|
||||||
|
|
||||||
IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(bytesExpected);
|
MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)bytesExpected));
|
||||||
|
|
||||||
var destSpan = ownedMemory.Memory.Span;
|
var destSpan = ownedMemory.Span;
|
||||||
|
|
||||||
int totalBytesRead = 0;
|
int totalBytesRead = 0;
|
||||||
|
|
||||||
|
@ -66,14 +65,14 @@ namespace Ryujinx.Common.Utilities
|
||||||
return stream.ToArray();
|
return stream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMemoryOwner<byte> MemoryStreamToRentedMemory(MemoryStream input)
|
private static MemoryOwner<byte> MemoryStreamToRentedMemory(MemoryStream input)
|
||||||
{
|
{
|
||||||
input.Position = 0;
|
input.Position = 0;
|
||||||
|
|
||||||
IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(input.Length);
|
MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)input.Length));
|
||||||
|
|
||||||
// Discard the return value because we assume reading a MemoryStream always succeeds completely.
|
// Discard the return value because we assume reading a MemoryStream always succeeds completely.
|
||||||
_ = input.Read(ownedMemory.Memory.Span);
|
_ = input.Read(ownedMemory.Span);
|
||||||
|
|
||||||
return ownedMemory;
|
return ownedMemory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,9 +303,9 @@ namespace Ryujinx.Cpu.Jit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
Read(va, memoryOwner.Memory.Span);
|
Read(va, memoryOwner.Span);
|
||||||
|
|
||||||
return new WritableRegion(this, va, memoryOwner);
|
return new WritableRegion(this, va, memoryOwner);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,9 +130,9 @@ namespace Ryujinx.Memory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size);
|
MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size);
|
||||||
|
|
||||||
Read(va, memoryOwner.Memory.Span);
|
Read(va, memoryOwner.Span);
|
||||||
|
|
||||||
return new WritableRegion(this, va, memoryOwner);
|
return new WritableRegion(this, va, memoryOwner);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue