summaryrefslogtreecommitdiff
path: root/src/classlibnative/bcltype/arraynative.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/classlibnative/bcltype/arraynative.cpp')
-rw-r--r--src/classlibnative/bcltype/arraynative.cpp99
1 files changed, 14 insertions, 85 deletions
diff --git a/src/classlibnative/bcltype/arraynative.cpp b/src/classlibnative/bcltype/arraynative.cpp
index 0eae8b2d07..c54d2f3c31 100644
--- a/src/classlibnative/bcltype/arraynative.cpp
+++ b/src/classlibnative/bcltype/arraynative.cpp
@@ -17,6 +17,8 @@
#include "security.h"
#include "invokeutil.h"
+#include "arraynative.inl"
+
FCIMPL1(INT32, ArrayNative::GetRank, ArrayBase* array)
{
FCALL_CONTRACT;
@@ -173,7 +175,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
PCODE ctorFtn = pCanonMT->GetSlot(slot);
-#ifdef _X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
BEGIN_CALL_TO_MANAGED();
@@ -204,7 +206,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
}
END_CALL_TO_MANAGED();
-#else // _X86_
+#else // _TARGET_X86_ && !FEATURE_PAL
//
// This is quite a bit slower, but it is portable.
//
@@ -228,7 +230,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
offset += size;
}
-#endif // _X86_
+#endif // !_TARGET_X86_ || FEATURE_PAL
}
@@ -883,85 +885,25 @@ void memmoveGCRefs(void *dest, const void *src, size_t len)
NOTHROW;
GC_NOTRIGGER;
MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(dest));
- PRECONDITION(CheckPointer(src));
- PRECONDITION(len >= 0);
SO_TOLERANT;
}
CONTRACTL_END;
+ _ASSERTE(dest != nullptr);
+ _ASSERTE(src != nullptr);
+
// Make sure everything is pointer aligned
_ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
_ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
_ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
- size_t size = len;
- BYTE * dmem = (BYTE *)dest;
- BYTE * smem = (BYTE *)src;
-
- GCHeapMemoryBarrier();
-
- if (dmem <= smem || smem + size <= dmem)
- {
- // copy 16 bytes at a time
- while (size >= 4 * sizeof(SIZE_T))
- {
- size -= 4 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
- ((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
- smem += 4 * sizeof(SIZE_T);
- dmem += 4 * sizeof(SIZE_T);
- }
-
- if ((size & (2 * sizeof(SIZE_T))) != 0)
- {
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- smem += 2 * sizeof(SIZE_T);
- dmem += 2 * sizeof(SIZE_T);
- }
+ _ASSERTE(CheckPointer(dest));
+ _ASSERTE(CheckPointer(src));
- if ((size & sizeof(SIZE_T)) != 0)
- {
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
- }
- else
+ if (len != 0 && dest != src)
{
- smem += size;
- dmem += size;
-
- // copy 16 bytes at a time
- while (size >= 4 * sizeof(SIZE_T))
- {
- size -= 4 * sizeof(SIZE_T);
- smem -= 4 * sizeof(SIZE_T);
- dmem -= 4 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
- ((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
-
- if ((size & (2 * sizeof(SIZE_T))) != 0)
- {
- smem -= 2 * sizeof(SIZE_T);
- dmem -= 2 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
-
- if ((size & sizeof(SIZE_T)) != 0)
- {
- smem -= sizeof(SIZE_T);
- dmem -= sizeof(SIZE_T);
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
+ InlinedMemmoveGCRefsHelper(dest, src, len);
}
-
- SetCardsAfterBulkCopy((Object**)dest, len);
}
void ArrayNative::ArrayCopyNoTypeCheck(BASEARRAYREF pSrc, unsigned int srcIndex, BASEARRAYREF pDest, unsigned int destIndex, unsigned int length)
@@ -1186,18 +1128,6 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
// TODO: We also should check for type/member visibility here. To do that we can replace
// the following chunk of code with a simple InvokeUtil::CanAccessClass call.
// But it's too late to make this change in Dev10 and we want SL4 to be compatible with Dev10.
-#ifndef FEATURE_CORECLR
- // Make sure security allows us access to the array type - if it is critical, convert that to a
- // demand for full trust
- if (!SecurityStackWalk::HasFlagsOrFullyTrusted(0))
- {
- if (Security::TypeRequiresTransparencyCheck(pMT, true))
- {
- // If we're creating a critical type, convert the critical check into a demand for full trust
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
- }
-#else
if (Security::TypeRequiresTransparencyCheck(pMT))
{
// The AccessCheckOptions flag doesn't matter because we just need to get the caller.
@@ -1210,11 +1140,10 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
accessCheckOptions.DemandMemberAccessOrFail(&sCtx, pMT, FALSE /*visibilityCheck*/);
}
-#endif // !FEATURE_CORECLR
// Check for byref-like types.
if (pMT->IsByRefLike())
- COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLike[]"));
+ COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLikeArray"));
// Check for open generic types.
if (pMT->IsGenericTypeDefinition() || pMT->ContainsGenericVariables())
@@ -1222,7 +1151,7 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
// Check for Void.
if (elementType.GetSignatureCorElementType() == ELEMENT_TYPE_VOID)
- COMPlusThrow(kNotSupportedException, W("NotSupported_Void[]"));
+ COMPlusThrow(kNotSupportedException, W("NotSupported_VoidArray"));
// That's all the dangerous simple types we know, it must be OK.
return;