From cd3929d5b7649213998dbc039d08bb0bd61d079d Mon Sep 17 00:00:00 2001 From: Maoni0 Date: Tue, 21 Jun 2022 21:02:31 -0700 Subject: [PATCH] NextObj fix --- src/coreclr/gc/gc.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index ec96a2e6fb65db..1021d669b2dc36 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44526,9 +44526,25 @@ Object * GCHeap::NextObj (Object * object) return NULL; } - if ((nextobj < heap_segment_mem(hs)) || - (nextobj >= heap_segment_allocated(hs) && hs != hp->ephemeral_heap_segment) || - (nextobj >= hp->alloc_allocated)) + if (nextobj < heap_segment_mem (hs)) + { + return NULL; + } + + uint8_t* saved_alloc_allocated = hp->alloc_allocated; + heap_segment* saved_ephemeral_heap_segment = hp->ephemeral_heap_segment; + + // We still want to verify nextobj that lands between heap_segment_allocated and alloc_allocated + // on the ephemeral segment. In regions these 2 could be changed by another thread so we need + // to make sure they are still in sync by the time we check. If they are not in sync, we just + // bail which means we don't validate the next object during that small window and that's fine. + // + // We also miss validating nextobj if it's in the segment that just turned into the new ephemeral + // segment since we saved which is also a very small window and again that's fine. + if ((nextobj >= heap_segment_allocated (hs)) && + ((hs != saved_ephemeral_heap_segment) || + !in_range_for_segment(saved_alloc_allocated, saved_ephemeral_heap_segment) || + (nextobj >= saved_alloc_allocated))) { return NULL; }