Skip to content

Commit

Permalink
Ensure syncblock is cleared with GC_ALLOC_ZEROING_OPTIONAL (dotnet#97174
Browse files Browse the repository at this point in the history
)

Fixes dotnet#96790
  • Loading branch information
jkotas authored and tmds committed Jan 23, 2024
1 parent 4c30457 commit 6c04b48
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/coreclr/vm/gchelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
Expand Down

0 comments on commit 6c04b48

Please sign in to comment.