GetContainingObject is inconsistent with the lowest address it chooses. (dotnet/corec...
authorMaoni Stephens <Maoni0@users.noreply.github.com>
Fri, 24 Mar 2017 01:24:55 +0000 (18:24 -0700)
committerGitHub <noreply@github.com>
Fri, 24 Mar 2017 01:24:55 +0000 (18:24 -0700)
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
src/coreclr/src/gc/gcimpl.h
src/coreclr/src/gc/gcinterface.h
src/coreclr/src/vm/gcenv.ee.cpp
src/coreclr/src/vm/stubhelpers.cpp

index 53a68cc..1a5072e 100644 (file)
@@ -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
     {
index 7b4b2eb..e0008b9 100644 (file)
@@ -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);
index f67aef7..215f6ce 100644 (file)
@@ -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;
 
     /*
     ===========================================================================
index 2833c99..380c31a 100644 (file)
@@ -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)
index bf83c72..0a5c143 100644 (file)
@@ -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);
         }
     }