Skip to content

Commit 27daa14

Browse files
Koundinya VeluriJosé Rivero
Koundinya Veluri
authored and
José Rivero
committed
Improve span copy of pointers and structs containing pointers (dotnet#9999)
Improve span copy of pointers and structs containing pointers Fixes #9161 PR dotnet#9786 fixes perf of span copy of types that don't contain references
1 parent 0f4785d commit 27daa14

File tree

11 files changed

+602
-187
lines changed

11 files changed

+602
-187
lines changed

src/classlibnative/bcltype/arraynative.cpp

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "security.h"
1818
#include "invokeutil.h"
1919

20+
#include "arraynative.inl"
21+
2022
FCIMPL1(INT32, ArrayNative::GetRank, ArrayBase* array)
2123
{
2224
FCALL_CONTRACT;
@@ -883,85 +885,25 @@ void memmoveGCRefs(void *dest, const void *src, size_t len)
883885
NOTHROW;
884886
GC_NOTRIGGER;
885887
MODE_COOPERATIVE;
886-
PRECONDITION(CheckPointer(dest));
887-
PRECONDITION(CheckPointer(src));
888-
PRECONDITION(len >= 0);
889888
SO_TOLERANT;
890889
}
891890
CONTRACTL_END;
892891

892+
_ASSERTE(dest != nullptr);
893+
_ASSERTE(src != nullptr);
894+
893895
// Make sure everything is pointer aligned
894896
_ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
895897
_ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
896898
_ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
897899

898-
size_t size = len;
899-
BYTE * dmem = (BYTE *)dest;
900-
BYTE * smem = (BYTE *)src;
901-
902-
GCHeapMemoryBarrier();
903-
904-
if (dmem <= smem || smem + size <= dmem)
905-
{
906-
// copy 16 bytes at a time
907-
while (size >= 4 * sizeof(SIZE_T))
908-
{
909-
size -= 4 * sizeof(SIZE_T);
910-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
911-
((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
912-
((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
913-
((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
914-
smem += 4 * sizeof(SIZE_T);
915-
dmem += 4 * sizeof(SIZE_T);
916-
}
917-
918-
if ((size & (2 * sizeof(SIZE_T))) != 0)
919-
{
920-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
921-
((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
922-
smem += 2 * sizeof(SIZE_T);
923-
dmem += 2 * sizeof(SIZE_T);
924-
}
900+
_ASSERTE(CheckPointer(dest));
901+
_ASSERTE(CheckPointer(src));
925902

926-
if ((size & sizeof(SIZE_T)) != 0)
927-
{
928-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
929-
}
930-
}
931-
else
903+
if (len != 0 && dest != src)
932904
{
933-
smem += size;
934-
dmem += size;
935-
936-
// copy 16 bytes at a time
937-
while (size >= 4 * sizeof(SIZE_T))
938-
{
939-
size -= 4 * sizeof(SIZE_T);
940-
smem -= 4 * sizeof(SIZE_T);
941-
dmem -= 4 * sizeof(SIZE_T);
942-
((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
943-
((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
944-
((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
945-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
946-
}
947-
948-
if ((size & (2 * sizeof(SIZE_T))) != 0)
949-
{
950-
smem -= 2 * sizeof(SIZE_T);
951-
dmem -= 2 * sizeof(SIZE_T);
952-
((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
953-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
954-
}
955-
956-
if ((size & sizeof(SIZE_T)) != 0)
957-
{
958-
smem -= sizeof(SIZE_T);
959-
dmem -= sizeof(SIZE_T);
960-
((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
961-
}
905+
InlinedMemmoveGCRefsHelper(dest, src, len);
962906
}
963-
964-
SetCardsAfterBulkCopy((Object**)dest, len);
965907
}
966908

967909
void ArrayNative::ArrayCopyNoTypeCheck(BASEARRAYREF pSrc, unsigned int srcIndex, BASEARRAYREF pDest, unsigned int destIndex, unsigned int length)

0 commit comments

Comments
 (0)