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

Add Unsafe.IsAddressGreaterThan / IsAddressLessThan #15988

Merged
merged 1 commit into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/mscorlib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,46 @@ public static bool AreSame<T>(ref T left, ref T right)
// ret
}

/// <summary>
/// Determines whether the memory address referenced by <paramref name="left"/> is greater than
/// the memory address referenced by <paramref name="right"/>.
/// </summary>
/// <remarks>
/// This check is conceptually similar to "(void*)(&amp;left) &gt; (void*)(&amp;right)".
/// </remarks>
[Intrinsic]
[NonVersionable]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Copy link
Member

Choose a reason for hiding this comment

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

Is Aggressive inlining necessary or just there for good measure?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's the same pattern used by the other methods on the type - I assume for good measure?

public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
{
throw new PlatformNotSupportedException();

// ldarg.0
// ldarg.1
// cgt.un
// ret
}

/// <summary>
/// Determines whether the memory address referenced by <paramref name="left"/> is less than
/// the memory address referenced by <paramref name="right"/>.
/// </summary>
/// <remarks>
/// This check is conceptually similar to "(void*)(&amp;left) &lt; (void*)(&amp;right)".
/// </remarks>
[Intrinsic]
[NonVersionable]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsAddressLessThan<T>(ref T left, ref T right)
{
throw new PlatformNotSupportedException();

// ldarg.0
// ldarg.1
// clt.un
// ret
}

/// <summary>
/// Initializes a block of memory at the given location with a given initial value
/// without assuming architecture dependent alignment of the address.
Expand Down
22 changes: 22 additions & 0 deletions src/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7192,6 +7192,28 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
methInfo->options = (CorInfoOptions)0;
return true;
}
else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_GREATER_THAN)->GetMemberDef())
{
// Compare the two arguments
static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CGT_UN & 0xFF), CEE_RET };
methInfo->ILCode = const_cast<BYTE*>(ilcode);
methInfo->ILCodeSize = sizeof(ilcode);
methInfo->maxStack = 2;
methInfo->EHcount = 0;
methInfo->options = (CorInfoOptions)0;
return true;
}
else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_IS_ADDRESS_LESS_THAN)->GetMemberDef())
{
// Compare the two arguments
static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CLT_UN & 0xFF), CEE_RET };
methInfo->ILCode = const_cast<BYTE*>(ilcode);
methInfo->ILCodeSize = sizeof(ilcode);
methInfo->maxStack = 2;
methInfo->EHcount = 0;
methInfo->options = (CorInfoOptions)0;
return true;
}
else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_INIT_BLOCK_UNALIGNED)->GetMemberDef())
{
static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 0x01, CEE_PREFIX1, (CEE_INITBLK & 0xFF), CEE_RET };
Expand Down
2 changes: 2 additions & 0 deletions src/vm/mscorlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,8 @@ DEFINE_METHOD(UNSAFE, PTR_ADD, Add, GM_PtrVoid_Int_
DEFINE_METHOD(UNSAFE, BYREF_BYTE_OFFSET, ByteOffset, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ADD_BYTE_OFFSET, AddByteOffset, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_IS_ADDRESS_GREATER_THAN, IsAddressGreaterThan, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_IS_ADDRESS_LESS_THAN, IsAddressLessThan, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_READ_UNALIGNED, ReadUnaligned, GM_RefByte_RetT)
DEFINE_METHOD(UNSAFE, BYREF_WRITE_UNALIGNED, WriteUnaligned, GM_RefByte_T_RetVoid)
Expand Down