-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug
Milestone
Description
Looking at #102531, I realized the logic will miss implicit safe points created by the somewhat recent block store lowering changes.
Reproduction:
object x = null;
byte* p = stackalloc byte[1000];
Random.Shared.NextBytes(new Span<byte>(p, 1000));
Problem(p, p, &x);
[MethodImpl(MethodImplOptions.NoInlining)]
static void Problem(void* pDst, void* pSrc, object* pObj)
{
Unsafe.CopyBlock(pDst, pSrc, 1000);
StructWithManyObjs x = default;
if (pDst != null)
{
x.ObjFour = *pObj;
*(StructWithManyObjs*)pDst = x;
}
}
struct StructWithManyObjs
{
public object ObjOne;
public object ObjTwo;
public object ObjThree;
public object ObjFour;
public object ObjFive;
}DOTNET_TieredCompilation=0, DOTNET_GCStress=0xC, DOTNET_ReadyToRun=0 (it looks like GC stress doesn't apply to precompiled code).
Expected result: nothing happens.
Actual result:
Assert failure(PID 17360 [0x000043d0], Thread: 14716 [0x397c]): !CREATE_CHECK_STRING(!"Detected use of a corrupted OBJECTREF. Possible GC hole.")Cause: optRemoveRedundantZeroInits doesn't know that the block copy may become a safe point. Zero-init and future calls introduced late suffer from the same problem.
The most robust fix for this would probably be to move optRemoveRedundantZeroInits later (make it part of late liveness, say).
Metadata
Metadata
Assignees
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug