Skip to content

Commit c9d69e3

Browse files
authored
Report POH in ETW events (dotnet#34549)
* Report POH in existing events, when fitting. * GCGenerationRange (descr_generations_to_profiler) * GCBasicProfiler::GarbageCollectionStarted tolerate gen 4 * More profiler fixes * BGCOverflow_V1 * GCHeapStats_V1 * PR feedback
1 parent 4eda1d7 commit c9d69e3

14 files changed

Lines changed: 167 additions & 53 deletions

File tree

src/coreclr/src/gc/env/etmdummy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define FireEtwGCRestartEEEnd_V1(ClrInstanceID) 0
1212
#define FireEtwGCHeapStats(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount) 0
1313
#define FireEtwGCHeapStats_V1(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount, ClrInstanceID) 0
14+
#define FireEtwGCHeapStats_V2(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount, ClrInstanceID, GenerationSize4, TotalPromotedSize4) 0
1415
#define FireEtwGCCreateSegment(Address, Size, Type) 0
1516
#define FireEtwGCCreateSegment_V1(Address, Size, Type, ClrInstanceID) 0
1617
#define FireEtwGCFreeSegment(Address) 0
@@ -249,6 +250,7 @@
249250
#define FireEtwBGCDrainMark(Objects, ClrInstanceID) 0
250251
#define FireEtwBGCRevisit(Pages, Objects, IsLarge, ClrInstanceID) 0
251252
#define FireEtwBGCOverflow(Min, Max, Objects, IsLarge, ClrInstanceID) 0
253+
#define FireEtwBGCOverflow_V1(Min, Max, Objects, IsLarge, ClrInstanceID, GenNumber) 0
252254
#define FireEtwBGCAllocWaitBegin(Reason, ClrInstanceID) 0
253255
#define FireEtwBGCAllocWaitEnd(Reason, ClrInstanceID) 0
254256
#define FireEtwGCFullNotify(GenNumber, IsAlloc) 0

src/coreclr/src/gc/gc.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5043,11 +5043,16 @@ heap_segment* gc_heap::get_segment_for_uoh (int gen_number, size_t size
50435043
#ifdef MULTIPLE_HEAPS
50445044
heap_segment_heap (res) = hp;
50455045
#endif //MULTIPLE_HEAPS
5046-
res->flags |= gen_number == poh_generation ?
5046+
res->flags |= (gen_number == poh_generation) ?
50475047
heap_segment_flags_poh :
50485048
heap_segment_flags_loh;
50495049

5050-
FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(res), (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)), gc_etw_segment_large_object_heap);
5050+
FIRE_EVENT(GCCreateSegment_V1,
5051+
heap_segment_mem(res),
5052+
(size_t)(heap_segment_reserved (res) - heap_segment_mem(res)),
5053+
(gen_number == poh_generation) ?
5054+
gc_etw_segment_pinned_object_heap :
5055+
gc_etw_segment_large_object_heap);
50515056

50525057
GCToEEInterface::DiagUpdateGenerationBounds();
50535058

@@ -16591,9 +16596,9 @@ inline
1659116596
void fire_overflow_event (uint8_t* overflow_min,
1659216597
uint8_t* overflow_max,
1659316598
size_t marked_objects,
16594-
int large_objects_p)
16599+
int gen_number)
1659516600
{
16596-
FIRE_EVENT(BGCOverflow, (uint64_t)overflow_min, (uint64_t)overflow_max, marked_objects, large_objects_p);
16601+
FIRE_EVENT(BGCOverflow_V1, (uint64_t)overflow_min, (uint64_t)overflow_max, marked_objects, gen_number == loh_generation, gen_number);
1659716602
}
1659816603

1659916604
void gc_heap::concurrent_print_time_delta (const char* msg)
@@ -20359,7 +20364,7 @@ void gc_heap::background_process_mark_overflow_internal (int condemned_gen_numbe
2035920364
}
2036020365

2036120366
dprintf (2, ("h%d: SOH: ov-mo: %Id", heap_number, total_marked_objects));
20362-
fire_overflow_event (min_add, max_add, total_marked_objects, !small_object_segments);
20367+
fire_overflow_event (min_add, max_add, total_marked_objects, i);
2036320368
if (small_object_segments)
2036420369
{
2036520370
concurrent_print_time_delta (concurrent_p ? "Cov SOH" : "Nov SOH");
@@ -34880,66 +34885,65 @@ void gc_heap::descr_generations_to_profiler (gen_walk_fn fn, void *context)
3488034885
#endif // _PREFAST_
3488134886
#endif //MULTIPLE_HEAPS
3488234887

34883-
int curr_gen_number0 = max_generation+1;
34884-
while (curr_gen_number0 >= 0)
34888+
for (int curr_gen_number = total_generation_count-1; curr_gen_number >= 0; curr_gen_number--)
3488534889
{
34886-
generation* gen = hp->generation_of (curr_gen_number0);
34890+
generation* gen = hp->generation_of (curr_gen_number);
3488734891
heap_segment* seg = generation_start_segment (gen);
3488834892
while (seg && (seg != hp->ephemeral_heap_segment))
3488934893
{
34890-
assert (curr_gen_number0 > 0);
34894+
assert (curr_gen_number > 0);
3489134895

3489234896
// report bounds from heap_segment_mem (seg) to
3489334897
// heap_segment_allocated (seg);
34894-
// for generation # curr_gen_number0
34898+
// for generation # curr_gen_number
3489534899
// for heap # heap_no
3489634900

34897-
fn(context, curr_gen_number0, heap_segment_mem (seg),
34901+
fn(context, curr_gen_number, heap_segment_mem (seg),
3489834902
heap_segment_allocated (seg),
34899-
curr_gen_number0 == max_generation+1 ? heap_segment_reserved (seg) : heap_segment_allocated (seg));
34903+
curr_gen_number > max_generation ? heap_segment_reserved (seg) : heap_segment_allocated (seg));
3490034904

3490134905
seg = heap_segment_next (seg);
3490234906
}
34907+
3490334908
if (seg)
3490434909
{
3490534910
assert (seg == hp->ephemeral_heap_segment);
34906-
assert (curr_gen_number0 <= max_generation);
34911+
assert (curr_gen_number <= max_generation);
3490734912
//
34908-
if (curr_gen_number0 == max_generation)
34913+
if (curr_gen_number == max_generation)
3490934914
{
3491034915
if (heap_segment_mem (seg) < generation_allocation_start (hp->generation_of (max_generation-1)))
3491134916
{
3491234917
// report bounds from heap_segment_mem (seg) to
3491334918
// generation_allocation_start (generation_of (max_generation-1))
3491434919
// for heap # heap_number
3491534920

34916-
fn(context, curr_gen_number0, heap_segment_mem (seg),
34921+
fn(context, curr_gen_number, heap_segment_mem (seg),
3491734922
generation_allocation_start (hp->generation_of (max_generation-1)),
3491834923
generation_allocation_start (hp->generation_of (max_generation-1)) );
3491934924
}
3492034925
}
34921-
else if (curr_gen_number0 != 0)
34926+
else if (curr_gen_number != 0)
3492234927
{
34923-
//report bounds from generation_allocation_start (generation_of (curr_gen_number0))
34924-
// to generation_allocation_start (generation_of (curr_gen_number0-1))
34928+
//report bounds from generation_allocation_start (generation_of (curr_gen_number))
34929+
// to generation_allocation_start (generation_of (curr_gen_number-1))
3492534930
// for heap # heap_number
3492634931

34927-
fn(context, curr_gen_number0, generation_allocation_start (hp->generation_of (curr_gen_number0)),
34928-
generation_allocation_start (hp->generation_of (curr_gen_number0-1)),
34929-
generation_allocation_start (hp->generation_of (curr_gen_number0-1)));
34932+
fn(context, curr_gen_number, generation_allocation_start (hp->generation_of (curr_gen_number)),
34933+
generation_allocation_start (hp->generation_of (curr_gen_number-1)),
34934+
generation_allocation_start (hp->generation_of (curr_gen_number-1)));
3493034935
}
3493134936
else
3493234937
{
34933-
//report bounds from generation_allocation_start (generation_of (curr_gen_number0))
34938+
//report bounds from generation_allocation_start (generation_of (curr_gen_number))
3493434939
// to heap_segment_allocated (ephemeral_heap_segment);
3493534940
// for heap # heap_number
3493634941

34937-
fn(context, curr_gen_number0, generation_allocation_start (hp->generation_of (curr_gen_number0)),
34942+
fn(context, curr_gen_number, generation_allocation_start (hp->generation_of (curr_gen_number)),
3493834943
heap_segment_allocated (hp->ephemeral_heap_segment),
3493934944
heap_segment_reserved (hp->ephemeral_heap_segment) );
3494034945
}
3494134946
}
34942-
curr_gen_number0--;
3494334947
}
3494434948
}
3494534949
}

src/coreclr/src/gc/gc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ enum gc_etw_segment_type
9797
enum gc_etw_alloc_kind
9898
{
9999
gc_etw_alloc_soh = 0,
100-
gc_etw_alloc_loh = 1
100+
gc_etw_alloc_loh = 1,
101+
gc_etw_alloc_poh = 2
101102
};
102103

103104
/* forward declerations */

src/coreclr/src/gc/gcee.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,12 @@ void GCHeap::UpdatePostGCCounters()
167167
g_GenerationSizes[3], g_GenerationPromotedSizes[3]));
168168
#endif //SIMPLE_DPRINTF
169169

170-
FIRE_EVENT(GCHeapStats_V1,
170+
FIRE_EVENT(GCHeapStats_V2,
171171
g_GenerationSizes[0], g_GenerationPromotedSizes[0],
172172
g_GenerationSizes[1], g_GenerationPromotedSizes[1],
173173
g_GenerationSizes[2], g_GenerationPromotedSizes[2],
174174
g_GenerationSizes[3], g_GenerationPromotedSizes[3],
175+
g_GenerationSizes[4], g_GenerationPromotedSizes[4],
175176
promoted_finalization_mem,
176177
GetFinalizablePromotedCount(),
177178
static_cast<uint32_t>(total_num_pinned_objects),
@@ -326,7 +327,22 @@ bool GCHeap::IsConcurrentGCInProgress()
326327
#ifdef FEATURE_EVENT_TRACE
327328
void gc_heap::fire_etw_allocation_event (size_t allocation_amount, int gen_number, uint8_t* object_address)
328329
{
329-
gc_etw_alloc_kind kind = gen_number == 0 ? gc_etw_alloc_soh : gc_etw_alloc_loh;
330+
gc_etw_alloc_kind kind;
331+
switch (gen_number)
332+
{
333+
case 0:
334+
kind = gc_etw_alloc_soh;
335+
break;
336+
case 3:
337+
kind = gc_etw_alloc_loh;
338+
break;
339+
case 4:
340+
kind = gc_etw_alloc_poh;
341+
break;
342+
default:
343+
__UNREACHABLE();
344+
}
345+
330346
FIRE_EVENT(GCAllocationTick_V3, static_cast<uint64_t>(allocation_amount), kind, heap_number, object_address);
331347
}
332348

@@ -401,12 +417,18 @@ void GCHeap::DiagTraceGCSegments()
401417
FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(type));
402418
}
403419

404-
// large obj segments
405-
for (seg = generation_start_segment (h->generation_of (loh_generation)); seg != 0; seg = heap_segment_next(seg))
420+
// uoh segments
421+
for (int i = uoh_start_generation; i < total_generation_count; i++)
406422
{
407-
uint8_t* address = heap_segment_mem (seg);
408-
size_t size = heap_segment_reserved (seg) - heap_segment_mem (seg);
409-
FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(gc_etw_segment_large_object_heap));
423+
for (seg = generation_start_segment (h->generation_of (i)); seg != 0; seg = heap_segment_next(seg))
424+
{
425+
uint8_t* address = heap_segment_mem (seg);
426+
size_t size = heap_segment_reserved (seg) - heap_segment_mem (seg);
427+
gc_etw_segment_type segment_type = (i == loh_generation) ?
428+
gc_etw_segment_large_object_heap :
429+
gc_etw_segment_pinned_object_heap;
430+
FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(segment_type));
431+
}
410432
}
411433
}
412434
#endif // FEATURE_EVENT_TRACE

src/coreclr/src/gc/gcevents.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
KNOWN_EVENT(GCStart_V2, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
1313
KNOWN_EVENT(GCEnd_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
1414
KNOWN_EVENT(GCGenerationRange, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHeapSurvivalAndMovement)
15-
KNOWN_EVENT(GCHeapStats_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
15+
KNOWN_EVENT(GCHeapStats_V2, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
1616
KNOWN_EVENT(GCCreateSegment_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
1717
KNOWN_EVENT(GCFreeSegment_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
1818
KNOWN_EVENT(GCCreateConcurrentThread_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
@@ -39,7 +39,7 @@ KNOWN_EVENT(BGC2ndConBegin, GCEventProvider_Private, GCEventLevel_Information, G
3939
KNOWN_EVENT(BGC2ndConEnd, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
4040
KNOWN_EVENT(BGCDrainMark, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
4141
KNOWN_EVENT(BGCRevisit, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
42-
KNOWN_EVENT(BGCOverflow, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
42+
KNOWN_EVENT(BGCOverflow_V1, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
4343
KNOWN_EVENT(BGCAllocWaitBegin, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
4444
KNOWN_EVENT(BGCAllocWaitEnd, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
4545
KNOWN_EVENT(GCFullNotify_V1, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)

src/coreclr/src/gc/gcinterface.ee.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class IGCToCLREventSink
5050
void FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength) = 0;
5151

5252
virtual
53-
void FireGCHeapStats_V1(
53+
void FireGCHeapStats_V2(
5454
uint64_t generationSize0,
5555
uint64_t totalPromotedSize0,
5656
uint64_t generationSize1,
@@ -59,6 +59,8 @@ class IGCToCLREventSink
5959
uint64_t totalPromotedSize2,
6060
uint64_t generationSize3,
6161
uint64_t totalPromotedSize3,
62+
uint64_t generationSize4,
63+
uint64_t totalPromotedSize4,
6264
uint64_t finalizationPromotedSize,
6365
uint64_t finalizationPromotedCount,
6466
uint32_t pinnedObjectCount,
@@ -148,7 +150,7 @@ class IGCToCLREventSink
148150
virtual
149151
void FireBGCRevisit(uint64_t pages, uint64_t objects, uint32_t isLarge) = 0;
150152
virtual
151-
void FireBGCOverflow(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge) = 0;
153+
void FireBGCOverflow_V1(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge, uint32_t genNumber) = 0;
152154
virtual
153155
void FireBGCAllocWaitBegin(uint32_t reason) = 0;
154156
virtual

src/coreclr/src/inc/corprof.idl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,8 @@ typedef enum
19521952
COR_PRF_GC_GEN_0 = 0,
19531953
COR_PRF_GC_GEN_1 = 1,
19541954
COR_PRF_GC_GEN_2 = 2,
1955-
COR_PRF_GC_LARGE_OBJECT_HEAP = 3
1955+
COR_PRF_GC_LARGE_OBJECT_HEAP = 3,
1956+
COR_PRF_GC_PINNED_OBJECT_HEAP= 4
19561957
} COR_PRF_GC_GENERATION;
19571958

19581959

src/coreclr/src/pal/prebuilt/inc/corprof.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,8 @@ enum __MIDL___MIDL_itf_corprof_0000_0001_0004
15231523
COR_PRF_GC_GEN_0 = 0,
15241524
COR_PRF_GC_GEN_1 = 1,
15251525
COR_PRF_GC_GEN_2 = 2,
1526-
COR_PRF_GC_LARGE_OBJECT_HEAP = 3
1526+
COR_PRF_GC_LARGE_OBJECT_HEAP = 3,
1527+
COR_PRF_GC_PINNED_OBJECT_HEAP = 4
15271528
} COR_PRF_GC_GENERATION;
15281529

15291530
typedef struct COR_PRF_GC_GENERATION_RANGE

0 commit comments

Comments
 (0)