From f93be68ef71a64506cac3bb262b926259cde2466 Mon Sep 17 00:00:00 2001 From: Maoni Stephens Date: Thu, 23 Mar 2017 18:24:55 -0700 Subject: [PATCH] GetContainingObject is inconsistent with the lowest address it chooses. (dotnet/coreclr#10438) For profiling purpose it only cares about condemned ranges; for byref validation it cares about any object on the heap. Commit migrated from https://github.com/dotnet/coreclr/commit/c5bfdd98204d7cb265f633534d593ca9c008ca6b --- src/coreclr/src/gc/gc.cpp | 10 +++++++--- src/coreclr/src/gc/gcimpl.h | 2 +- src/coreclr/src/gc/gcinterface.h | 4 +++- src/coreclr/src/vm/gcenv.ee.cpp | 4 +++- src/coreclr/src/vm/stubhelpers.cpp | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 53a68cc..1a5072e 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -34639,14 +34639,18 @@ GCHeap::FixAllocContext (gc_alloc_context* context, BOOL lockp, void* arg, void } Object* -GCHeap::GetContainingObject (void *pInteriorPtr) +GCHeap::GetContainingObject (void *pInteriorPtr, bool fCollectedGenOnly) { uint8_t *o = (uint8_t*)pInteriorPtr; gc_heap* hp = gc_heap::heap_of (o); - if (o >= hp->lowest_address && o < hp->highest_address) + + uint8_t* lowest = (fCollectedGenOnly ? hp->gc_low : hp->lowest_address); + uint8_t* highest = (fCollectedGenOnly ? hp->gc_high : hp->highest_address); + + if (o >= lowest && o < highest) { - o = hp->find_object (o, hp->gc_low); + o = hp->find_object (o, lowest); } else { diff --git a/src/coreclr/src/gc/gcimpl.h b/src/coreclr/src/gc/gcimpl.h index 7b4b2eb..e0008b9 100644 --- a/src/coreclr/src/gc/gcimpl.h +++ b/src/coreclr/src/gc/gcimpl.h @@ -108,7 +108,7 @@ public: void FixAllocContext (gc_alloc_context* acontext, BOOL lockp, void* arg, void *heap); - Object* GetContainingObject(void *pInteriorPtr); + Object* GetContainingObject(void *pInteriorPtr, bool fCollectedGenOnly); #ifdef MULTIPLE_HEAPS static void AssignHeap (alloc_context* acontext); diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h index f67aef7..215f6ce 100644 --- a/src/coreclr/src/gc/gcinterface.h +++ b/src/coreclr/src/gc/gcinterface.h @@ -654,7 +654,9 @@ public: // Given an interior pointer, return a pointer to the object // containing that pointer. This is safe to call only when the EE is suspended. - virtual Object* GetContainingObject(void* pInteriorPtr) = 0; + // When fCollectedGenOnly is true, it only returns the object if it's found in + // the generation(s) that are being collected. + virtual Object* GetContainingObject(void* pInteriorPtr, bool fCollectedGenOnly) = 0; /* =========================================================================== diff --git a/src/coreclr/src/vm/gcenv.ee.cpp b/src/coreclr/src/vm/gcenv.ee.cpp index 2833c99..380c31a 100644 --- a/src/coreclr/src/vm/gcenv.ee.cpp +++ b/src/coreclr/src/vm/gcenv.ee.cpp @@ -885,7 +885,9 @@ void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags) Object *pObj = *ppObject; if (dwFlags & GC_CALL_INTERIOR) { - pObj = GCHeapUtilities::GetGCHeap()->GetContainingObject(pObj); + pObj = GCHeapUtilities::GetGCHeap()->GetContainingObject(pObj, true); + if (pObj == nullptr) + return; } ScanRootsHelper(pObj, ppObject, pSC, dwFlags); #endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE) diff --git a/src/coreclr/src/vm/stubhelpers.cpp b/src/coreclr/src/vm/stubhelpers.cpp index bf83c72..0a5c143 100644 --- a/src/coreclr/src/vm/stubhelpers.cpp +++ b/src/coreclr/src/vm/stubhelpers.cpp @@ -158,7 +158,7 @@ void StubHelpers::ProcessByrefValidationList() { entry = s_ByrefValidationEntries[i]; - Object *pObjUNSAFE = GCHeapUtilities::GetGCHeap()->GetContainingObject(entry.pByref); + Object *pObjUNSAFE = GCHeapUtilities::GetGCHeap()->GetContainingObject(entry.pByref, false); ValidateObjectInternal(pObjUNSAFE, TRUE); } } -- 2.7.4