@@ -3021,6 +3021,93 @@ HCIMPL2(Object *, JIT_StrCns, unsigned rid, CORINFO_MODULE_HANDLE scopeHnd)
3021
3021
HCIMPLEND
3022
3022
3023
3023
3024
+ // ========================================================================
3025
+ //
3026
+ // ARRAY FAST PATHS
3027
+ //
3028
+ // ========================================================================
3029
+
3030
+ #include < optsmallperfcritical.h>
3031
+
3032
+ // *************************************************************
3033
+ // Array allocation fast path for arrays of value type elements
3034
+ //
3035
+
3036
+ HCIMPL2 (Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size)
3037
+ {
3038
+ FCALL_CONTRACT;
3039
+
3040
+ do
3041
+ {
3042
+ _ASSERTE (GCHeap::UseAllocationContexts ());
3043
+
3044
+ // Do a conservative check here. This is to avoid overflow while doing the calculations. We don't
3045
+ // have to worry about "large" objects, since the allocation quantum is never big enough for
3046
+ // LARGE_OBJECT_SIZE.
3047
+ //
3048
+ // For Value Classes, this needs to be 2^16 - slack (2^32 / max component size),
3049
+ // The slack includes the size for the array header and round-up ; for alignment. Use 256 for the
3050
+ // slack value out of laziness.
3051
+ SIZE_T componentCount = static_cast <SIZE_T>(size);
3052
+ if (componentCount >= static_cast <SIZE_T>(65535 - 256 ))
3053
+ {
3054
+ break ;
3055
+ }
3056
+
3057
+ // This is typically the only call in the fast path. Making the call early seems to be better, as it allows the compiler
3058
+ // to use volatile registers for intermediate values. This reduces the number of push/pop instructions and eliminates
3059
+ // some reshuffling of intermediate values into nonvolatile registers around the call.
3060
+ Thread *thread = GetThread ();
3061
+
3062
+ TypeHandle arrayTypeHandle (arrayTypeHnd_);
3063
+ ArrayTypeDesc *arrayTypeDesc = arrayTypeHandle.AsArray ();
3064
+ MethodTable *arrayMethodTable = arrayTypeDesc->GetTemplateMethodTable ();
3065
+
3066
+ _ASSERTE (arrayMethodTable->HasComponentSize ());
3067
+ SIZE_T componentSize = arrayMethodTable->RawGetComponentSize ();
3068
+ SIZE_T totalSize = componentCount * componentSize;
3069
+ _ASSERTE (totalSize / componentSize == componentCount);
3070
+
3071
+ SIZE_T baseSize = arrayMethodTable->GetBaseSize ();
3072
+ totalSize += baseSize;
3073
+ _ASSERTE (totalSize >= baseSize);
3074
+
3075
+ SIZE_T alignedTotalSize = ALIGN_UP (totalSize, DATA_ALIGNMENT);
3076
+ _ASSERTE (alignedTotalSize >= totalSize);
3077
+ totalSize = alignedTotalSize;
3078
+
3079
+ alloc_context *allocContext = thread->GetAllocContext ();
3080
+ BYTE *allocPtr = allocContext->alloc_ptr ;
3081
+ _ASSERTE (allocPtr <= allocContext->alloc_limit );
3082
+ if (totalSize > static_cast <SIZE_T>(allocContext->alloc_limit - allocPtr))
3083
+ {
3084
+ break ;
3085
+ }
3086
+ allocContext->alloc_ptr = allocPtr + totalSize;
3087
+
3088
+ _ASSERTE (allocPtr != nullptr );
3089
+ ArrayBase *array = reinterpret_cast <ArrayBase *>(allocPtr);
3090
+ array->SetMethodTable (arrayMethodTable);
3091
+ _ASSERTE (static_cast <DWORD>(componentCount) == componentCount);
3092
+ array->m_NumComponents = static_cast <DWORD>(componentCount);
3093
+
3094
+ #if CHECK_APP_DOMAIN_LEAKS
3095
+ if (g_pConfig->AppDomainLeaks ())
3096
+ {
3097
+ array->SetAppDomain ();
3098
+ }
3099
+ #endif // CHECK_APP_DOMAIN_LEAKS
3100
+
3101
+ return array;
3102
+ } while (false );
3103
+
3104
+ // Tail call to the slow helper
3105
+ ENDFORBIDGC ();
3106
+ return HCCALL2 (JIT_NewArr1, arrayTypeHnd_, size);
3107
+ }
3108
+ HCIMPLEND
3109
+
3110
+ #include < optdefault.h>
3024
3111
3025
3112
// ========================================================================
3026
3113
//
@@ -3068,7 +3155,8 @@ HCIMPL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size)
3068
3155
&& (elemType != ELEMENT_TYPE_U8)
3069
3156
&& (elemType != ELEMENT_TYPE_R8)
3070
3157
#endif
3071
- ) {
3158
+ )
3159
+ {
3072
3160
#ifdef _DEBUG
3073
3161
if (g_pConfig->FastGCStressLevel ()) {
3074
3162
GetThread ()->DisableStressHeap ();
0 commit comments