* include POH in diagnostic APIs like walk_survivors.
* PR feedback
static void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent);
static void DiagWalkFReachableObjects(void* gcContext);
static void DiagWalkSurvivors(void* gcContext, bool fCompacting);
- static void DiagWalkLOHSurvivors(void* gcContext);
+ static void DiagWalkUOHSurvivors(void* gcContext, int gen);
static void DiagWalkBGCSurvivors(void* gcContext);
static void StompWriteBarrier(WriteBarrierParameters* args);
if (!loh_compacted_p)
#endif //FEATURE_LOH_COMPACTION
{
- GCToEEInterface::DiagWalkLOHSurvivors(__this);
+ GCToEEInterface::DiagWalkUOHSurvivors(__this, loh_generation);
sweep_uoh_objects (loh_generation);
}
+ GCToEEInterface::DiagWalkUOHSurvivors(__this, poh_generation);
sweep_uoh_objects (poh_generation);
}
else
else if (type == walk_for_bgc)
walk_survivors_for_bgc (context, fn);
#endif //BACKGROUND_GC && FEATURE_EVENT_TRACE
- else if (type == walk_for_loh)
- walk_survivors_for_loh (context, fn);
else
assert (!"unknown type!");
}
}
}
-BOOL gc_heap::large_object_marked (uint8_t* o, BOOL clearp)
+BOOL gc_heap::uoh_object_marked (uint8_t* o, BOOL clearp)
{
BOOL m = FALSE;
// It shouldn't be necessary to do these comparisons because this is only used for blocking
#endif //FEATURE_LOH_COMPACTION
}
-void gc_heap::walk_survivors_for_loh (void* profiling_context, record_surv_fn fn)
+void gc_heap::walk_survivors_for_uoh (void* profiling_context, record_surv_fn fn, int gen_number)
{
- generation* gen = large_object_generation;
+ generation* gen = generation_of (gen_number);
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));;
PREFIX_ASSUME(seg != NULL);
else
o = heap_segment_mem (seg);
}
- if (large_object_marked(o, FALSE))
+ if (uoh_object_marked(o, FALSE))
{
plug_start = o;
{
break;
}
- m = large_object_marked (o, FALSE);
+ m = uoh_object_marked (o, FALSE);
}
plug_end = o;
}
else
{
- while (o < heap_segment_allocated (seg) && !large_object_marked(o, FALSE))
+ while (o < heap_segment_allocated (seg) && !uoh_object_marked(o, FALSE))
{
o = o + AlignQword (size (o));
}
(size_t)heap_segment_allocated (seg)));
}
}
- if (large_object_marked(o, TRUE))
+ if (uoh_object_marked(o, TRUE))
{
plug_start = o;
//everything between plug_end and plug_start is free
{
break;
}
- m = large_object_marked (o, TRUE);
+ m = uoh_object_marked (o, TRUE);
}
plug_end = o;
dprintf (3, ("plug [%Ix, %Ix[", (size_t)plug_start, (size_t)plug_end));
}
else
{
- while (o < heap_segment_allocated (seg) && !large_object_marked(o, FALSE))
+ while (o < heap_segment_allocated (seg) && !uoh_object_marked(o, FALSE))
{
o = o + AlignQword (size (o));
}
}
}
-void GCHeap::DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type)
+void GCHeap::DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type, int gen_number)
{
gc_heap* hp = (gc_heap*)gc_context;
- hp->walk_survivors (fn, diag_context, type);
+
+ if (type == walk_for_uoh)
+ {
+ hp->walk_survivors_for_uoh (diag_context, fn, gen_number);
+ }
+ else
+ {
+ hp->walk_survivors (fn, diag_context, type);
+ }
}
void GCHeap::DiagWalkHeap (walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p)
g_theGCToCLR->DiagWalkSurvivors(gcContext, fCompacting);
}
-inline void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+inline void GCToEEInterface::DiagWalkUOHSurvivors(void* gcContext, int gen)
{
assert(g_theGCToCLR != nullptr);
- g_theGCToCLR->DiagWalkLOHSurvivors(gcContext);
+ g_theGCToCLR->DiagWalkUOHSurvivors(gcContext, gen);
}
inline void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
virtual void DiagDescrGenerations (gen_walk_fn fn, void *context);
- virtual void DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type);
+ virtual void DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type, int gen_number=-1);
virtual void DiagWalkFinalizeQueue (void* gc_context, fq_walk_fn fn);
virtual
void DiagWalkSurvivors(void* gcContext, bool fCompacting) = 0;
- // During a full GC after we discover what objects to survive on LOH,
+ // During a full GC after we discover what objects to survive on UOH,
// gives the diagnostics code a chance to run.
virtual
- void DiagWalkLOHSurvivors(void* gcContext) = 0;
+ void DiagWalkUOHSurvivors(void* gcContext, int gen) = 0;
// At the end of a background GC, gives the diagnostics code a chance to run.
virtual
{
walk_for_gc = 1,
walk_for_bgc = 2,
- walk_for_loh = 3
+ walk_for_uoh = 3
} walk_surv_type;
// Different operations that can be done by GCToEEInterface::StompWriteBarrier
virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) = 0;
// Walks the survivors and get the relocation information if objects have moved.
- virtual void DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type) = 0;
+ // gen_number is used when type == walk_for_uoh, otherwise ignored
+ virtual void DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type, int gen_number=-1) = 0;
// Walks the finalization queue.
virtual void DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn) = 0;
PER_HEAP
void walk_survivors_relocation (void* profiling_context, record_surv_fn fn);
PER_HEAP
- void walk_survivors_for_loh (void* profiling_context, record_surv_fn fn);
+ void walk_survivors_for_uoh (void* profiling_context, record_surv_fn fn, int gen_number);
PER_HEAP
int generation_to_condemn (int n,
#endif //MARK_ARRAY
PER_HEAP
- BOOL large_object_marked (uint8_t* o, BOOL clearp);
+ BOOL uoh_object_marked (uint8_t* o, BOOL clearp);
#ifdef BACKGROUND_GC
PER_HEAP
{
}
-void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+void GCToEEInterface::DiagWalkUOHSurvivors(void* gcContext, int gen)
{
}
#endif //GC_PROFILING || FEATURE_EVENT_TRACE
}
-void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+void GCToEEInterface::DiagWalkUOHSurvivors(void* gcContext, int gen)
{
#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
if (ShouldTrackSurvivorsForProfilerOrEtw())
{
size_t context = 0;
ETW::GCLog::BeginMovedReferences(&context);
- GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, (void*)context, walk_for_loh);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, (void*)context, walk_for_uoh, gen);
ETW::GCLog::EndMovedReferences(context);
}
#endif //GC_PROFILING || FEATURE_EVENT_TRACE
void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent);
void DiagWalkFReachableObjects(void* gcContext);
void DiagWalkSurvivors(void* gcContext, bool fCompacting);
- void DiagWalkLOHSurvivors(void* gcContext);
+ void DiagWalkUOHSurvivors(void* gcContext, int gen);
void DiagWalkBGCSurvivors(void* gcContext);
void StompWriteBarrier(WriteBarrierParameters* args);