Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Change Pin to take an optional integer offset #25770

Merged
merged 9 commits into from
Jan 22, 2018

Conversation

ahsonkhan
Copy link
Member

@ahsonkhan ahsonkhan commented Dec 7, 2017

Resolves: https://github.com/dotnet/corefx/issues/25229

Depends on similar changes to be made in coreclr first for CI to pass - dotnet/coreclr#15410

Depends on the following for the CI to pass: dotnet/coreclr#15946

cc @KrzysztofCwalina, @jkotas, @stephentoub, @pakrym, @davidfowl

@@ -53,7 +53,11 @@ protected override bool IsRetained

public override unsafe Span<byte> Span => new Span<byte>((void*)_ptr, _length);

public override unsafe MemoryHandle Pin() => new MemoryHandle(this, (void*)_ptr);
public override unsafe MemoryHandle Pin(int offset = 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when offset is negative? Is it important to handle that case in more robust way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar case - offset is more than the length of the block?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NativeOwnedMemory is implementing OwnedMemory for testing purposes only so it isn't crucial for this implementation to validate offset.

It makes sense that for an array backed OwnedMemory, we can't support negative offset, but for NativeOwnedMemory, should a negative offset be allowed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see the difference between the two cases. Negative offset does not make sense to either, I think.

@stephentoub
Copy link
Member

Tests for the new parameter?

@KrzysztofCwalina
Copy link
Member

Looks good after validating the parameter range.

@ahsonkhan
Copy link
Member Author

Tests for the new parameter?

Since Pin is an abstract class, we don't really have direct tests for it. We already test the relevant scenarios through our Retain tests (the only place where we call Pin):
https://github.com/dotnet/corefx/blob/master/src/System.Memory/tests/Memory/Retain.cs
https://github.com/dotnet/corefx/blob/master/src/System.Memory/tests/ReadOnlyMemory/Retain.cs

I can't add tests for offsets that are negative or out of bounds because our Memory.Retain implementation guarantees that the offset is within range.

@ahsonkhan
Copy link
Member Author

ahsonkhan commented Dec 9, 2017

Cherry-picked into #25787 to unblock the update.

Edit: Updated this PR - #25821

Edit2: cherry-pick didn't make it in. PR remains open and blocked

@ahsonkhan
Copy link
Member Author

Flagging this as a breaking change

cc @marek-safar

@ahsonkhan ahsonkhan added the blocked Issue/PR is blocked on something - see comments label Dec 15, 2017
@karelz
Copy link
Member

karelz commented Jan 18, 2018

@ahsonkhan any update on this PR?

@ahsonkhan
Copy link
Member Author

@ahsonkhan any update on this PR?

I am working on figure out what caused the test failure. I should have an update by eod tomorrow.

@stephentoub
Copy link
Member

@ahsonkhan, was the issue not what I emailed you?

"My guess is it’s due to this line:
https://github.com/dotnet/corefx/pull/25770/files#diff-eecad12eaed49ff891666e48f29f84b8R58
These tests are testing 0-length sends/receives, which means it’s allocating a 0-length NativeOwnedMemory. Calling Pin on that would previously succeed, but your change makes it an exception. Calling Pin() on a 0-length memory should not throw."

@ahsonkhan
Copy link
Member Author

ahsonkhan commented Jan 20, 2018

My guess is it’s due to this line

Yes, @stephentoub. That was the cause. I have fixed the implementation and added the tests. Thanks!

This PR depends on the following for the CI to pass: dotnet/coreclr#15946

{
unsafe
{
Retain();
if (offset < 0 || (_array.Length > 0 && offset >= _array.Length)) throw new ArgumentOutOfRangeException(nameof(offset));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should rather be: if (offset < 0 || offset > _array.Length)

Copy link
Member Author

@ahsonkhan ahsonkhan Jan 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK to get a pointer past the _array.Length for non-empty arrays?

Should I make the same change here?
https://github.com/dotnet/corefx/pull/25770/files#diff-eecad12eaed49ff891666e48f29f84b8R58

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is ok to get a pointer that points right past the array, but not beyond it. It matches how offsets or index checks are done everywhere else. For example, the condition in Span.Slice is if ((uint)index > (uint)_count) ... error ....

{
int* pointer = (int*)handle.Pointer;

GC.Collect();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is useless. GC.Collect will not affect unmanaged pointer stored in a local.

I have merged your changes into the mirror PR already. If you would like to clean this up, do it in a follow up PR.

@jkotas jkotas merged commit 94e3346 into dotnet:master Jan 22, 2018
@ahsonkhan ahsonkhan deleted the OwnedMemoryOffset branch January 22, 2018 18:23
@ahsonkhan ahsonkhan removed the blocked Issue/PR is blocked on something - see comments label Jan 25, 2018
@jkotas jkotas mentioned this pull request Jan 25, 2018
@karelz karelz added this to the 2.1.0 milestone Feb 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants