diff options
Diffstat (limited to 'src/classlibnative/bcltype/arraynative.cpp')
-rw-r--r-- | src/classlibnative/bcltype/arraynative.cpp | 99 |
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; |