diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index 5bffc9a00ad4d..ecbf8f09ce293 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -434,7 +434,8 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS // dummy object. // If the GC gives us a 8 byte aligned address, we use it for the array and place the dummy // object after the array, otherwise we put the dummy object first, shifting the base of - // the array to an 8 byte aligned address. + // the array to an 8 byte aligned address. Also, we need to make sure that the syncblock of the + // second object is zeroed. GC won't take care of zeroing it out with GC_ALLOC_ZEROING_OPTIONAL. // // Note: on 64 bit platforms, the GC always returns 8 byte aligned addresses, and we don't // execute this code because DATA_ALIGNMENT < sizeof(double) is false. @@ -447,14 +448,24 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS orArray = (ArrayBase*)Alloc(totalSize + MIN_OBJECT_SIZE, flags); Object* orDummyObject; - if ((size_t)orArray % sizeof(double)) + if (((size_t)orArray % sizeof(double)) != 0) { orDummyObject = orArray; orArray = (ArrayBase*)((size_t)orArray + MIN_OBJECT_SIZE); + if (flags & GC_ALLOC_ZEROING_OPTIONAL) + { + // clean the syncblock of the aligned array. + *(((void**)orArray)-1) = 0; + } } else { orDummyObject = (Object*)((size_t)orArray + totalSize); + if (flags & GC_ALLOC_ZEROING_OPTIONAL) + { + // clean the syncblock of the dummy object. + *(((void**)orDummyObject)-1) = 0; + } } _ASSERTE(((size_t)orArray % sizeof(double)) == 0); orDummyObject->SetMethodTable(g_pObjectClass);