{
public MemoryHandle(IRetainable owner, void* pinnedPointer = null, System.Runtime.InteropServices.GCHandle handle = default(System.Runtime.InteropServices.GCHandle)) { throw null; }
public void* PinnedPointer { get { throw null; } }
- public void Dispose() { throw null; }
+ internal void AddOffset(int offset) { throw null; }
+ public void Dispose() { throw null; }
}
public interface IRetainable
public void* PinnedPointer => _pointer;
/// <summary>
+ /// Adds an offset to the pinned pointer.
+ /// </summary>
+ /// <exception cref="System.ArgumentNullException">
+ /// Throw when pinned pointer is null.
+ /// </exception>
+ internal void AddOffset(int offset)
+ {
+ if (_pointer == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pointer);
+ }
+ else
+ {
+ _pointer = (void*)((byte*)_pointer + offset);
+ }
+ }
+
+ /// <summary>
/// Frees the pinned handle and releases IRetainable.
/// </summary>
public void Dispose()
if (_index < 0)
{
memoryHandle = ((OwnedMemory<T>)_arrayOrOwnedMemory).Pin();
+ memoryHandle.AddOffset((_index & RemoveOwnedFlagBitMask) * Unsafe.SizeOf<T>());
}
else
{
if (_index < 0)
{
memoryHandle = ((OwnedMemory<T>)_arrayOrOwnedMemory).Pin();
+ memoryHandle.AddOffset((_index & RemoveOwnedFlagBitMask) * Unsafe.SizeOf<T>());
}
else
{
start,
text,
obj,
- ownedMemory
+ ownedMemory,
+ pointer
}
}
}
[Fact]
+ public static void MemoryRetainWithPinningAndSlice()
+ {
+ int[] array = { 1, 2, 3, 4, 5 };
+ Memory<int> memory = array;
+ memory = memory.Slice(1);
+ MemoryHandle handle = memory.Retain(pin: true);
+ Span<int> span = memory.Span;
+ unsafe
+ {
+ int* pointer = (int*)handle.PinnedPointer;
+ Assert.True(pointer != null);
+
+ GC.Collect();
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], pointer[i]);
+ }
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], span[i]);
+ }
+ }
+ handle.Dispose();
+ }
+
+ [Fact]
public static void OwnedMemoryRetainWithoutPinning()
{
int[] array = { 1, 2, 3, 4, 5 };
}
handle.Dispose();
}
+
+ [Fact]
+ public static void OwnedMemoryRetainWithPinningAndSlice()
+ {
+ int[] array = { 1, 2, 3, 4, 5 };
+ OwnedMemory<int> owner = new CustomMemoryForTest<int>(array);
+ Memory<int> memory = owner.Memory.Slice(1);
+ MemoryHandle handle = memory.Retain(pin: true);
+ Span<int> span = memory.Span;
+ unsafe
+ {
+ int* pointer = (int*)handle.PinnedPointer;
+ Assert.True(pointer != null);
+
+ GC.Collect();
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], pointer[i]);
+ }
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], span[i]);
+ }
+ }
+ handle.Dispose();
+ }
}
}
}
[Fact]
+ public static void MemoryRetainWithPinningAndSlice()
+ {
+ int[] array = { 1, 2, 3, 4, 5 };
+ ReadOnlyMemory<int> memory = array;
+ memory = memory.Slice(1);
+ MemoryHandle handle = memory.Retain(pin: true);
+ ReadOnlySpan<int> span = memory.Span;
+ unsafe
+ {
+ int* pointer = (int*)handle.PinnedPointer;
+ Assert.True(pointer != null);
+
+ GC.Collect();
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], pointer[i]);
+ }
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], span[i]);
+ }
+ }
+ handle.Dispose();
+ }
+
+ [Fact]
public static void OwnedMemoryRetainWithoutPinning()
{
int[] array = { 1, 2, 3, 4, 5 };
}
handle.Dispose();
}
+
+ [Fact]
+ public static void OwnedMemoryRetainWithPinningAndSlice()
+ {
+ int[] array = { 1, 2, 3, 4, 5 };
+ OwnedMemory<int> owner = new CustomMemoryForTest<int>(array);
+ ReadOnlyMemory<int> memory = owner.Memory.Slice(1);
+ MemoryHandle handle = memory.Retain(pin: true);
+ ReadOnlySpan<int> span = memory.Span;
+ unsafe
+ {
+ int* pointer = (int*)handle.PinnedPointer;
+ Assert.True(pointer != null);
+
+ GC.Collect();
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], pointer[i]);
+ }
+
+ for (int i = 0; i < memory.Length; i++)
+ {
+ Assert.Equal(array[i + 1], span[i]);
+ }
+ }
+ handle.Dispose();
+ }
}
}
public MemoryHandle(IRetainable owner, void* pinnedPointer = null, System.Runtime.InteropServices.GCHandle handle = default(System.Runtime.InteropServices.GCHandle)) { throw null; }
[System.CLSCompliantAttribute(false)]
public void* PinnedPointer { get { throw null; } }
- public void Dispose() { throw null; }
+ internal void AddOffset(int offset) { throw null; }
+ public void Dispose() { throw null; }
}
public interface IRetainable