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

Commit

Permalink
Avoid Unsafe.AsRef in Span<T> implementation (#8657)
Browse files Browse the repository at this point in the history
The JIT is not able to inline the current implementation of Unsafe.AsRef because of it has type mismatch on return. Change the the corelib Span to call Unsafe.As instead since fixing the type mismatch is not easy in the internal corelib version of Unsafe.AsRef.
  • Loading branch information
jkotas committed Dec 16, 2016
1 parent 3d95989 commit a03946c
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/mscorlib/src/System/ReadOnlySpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public unsafe ReadOnlySpan(void* pointer, int length)
if (length < 0)
ThrowHelper.ThrowArgumentOutOfRangeException();

_pointer = new ByReference<T>(ref Unsafe.AsRef<T>(pointer));
_pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
_length = length;
}

Expand Down
12 changes: 0 additions & 12 deletions src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,6 @@ public static int SizeOf<T>()
throw new InvalidOperationException();
}

/// <summary>
/// Reinterprets the given location as a reference to a value of type<typeparamref name="T"/>.
/// </summary>
[NonVersionable]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AsRef<T>(void * source)
{
// The body of this function will be replaced by the EE with unsafe code!!!
// See getILIntrinsicImplementationForUnsafe for how this happens.
throw new InvalidOperationException();
}

/// <summary>
/// Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/mscorlib/src/System/Span.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public unsafe Span(void* pointer, int length)
if (length < 0)
ThrowHelper.ThrowArgumentOutOfRangeException();

_pointer = new ByReference<T>(ref Unsafe.AsRef<T>(pointer));
_pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
_length = length;
}

Expand Down
4 changes: 1 addition & 3 deletions src/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7033,9 +7033,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
methInfo->options = (CorInfoOptions)0;
return true;
}
else if ((tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_REF)->GetMemberDef()) ||
(tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef()))

else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef())
{
// Return the argument that was passed in.
static const BYTE ilcode[] = { CEE_LDARG_0, CEE_RET };
Expand Down
1 change: 0 additions & 1 deletion src/vm/mscorlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,6 @@ DEFINE_METHOD(JIT_HELPERS, CONTAINSREFERENCES, ContainsReferences,
DEFINE_CLASS(UNSAFE, CompilerServices, Unsafe)
DEFINE_METHOD(UNSAFE, AS_POINTER, AsPointer, NoSig)
DEFINE_METHOD(UNSAFE, SIZEOF, SizeOf, NoSig)
DEFINE_METHOD(UNSAFE, AS_REF, AsRef, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_AS, As, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig)
Expand Down

0 comments on commit a03946c

Please sign in to comment.