Report POH in ETW events (#34549)
authorVladimir Sadov <vsadov@microsoft.com>
Thu, 9 Apr 2020 09:34:03 +0000 (02:34 -0700)
committerGitHub <noreply@github.com>
Thu, 9 Apr 2020 09:34:03 +0000 (09:34 +0000)
* 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

14 files changed:
src/coreclr/src/gc/env/etmdummy.h
src/coreclr/src/gc/gc.cpp
src/coreclr/src/gc/gc.h
src/coreclr/src/gc/gcee.cpp
src/coreclr/src/gc/gcevents.h
src/coreclr/src/gc/gcinterface.ee.h
src/coreclr/src/inc/corprof.idl
src/coreclr/src/pal/prebuilt/inc/corprof.h
src/coreclr/src/vm/ClrEtwAll.man
src/coreclr/src/vm/ClrEtwAllMeta.lst
src/coreclr/src/vm/gctoclreventsink.cpp
src/coreclr/src/vm/gctoclreventsink.h
src/coreclr/src/vm/proftoeeinterfaceimpl.cpp
src/coreclr/tests/src/profiler/native/gcbasicprofiler/gcbasicprofiler.cpp

index 652e919..7435df7 100644 (file)
@@ -11,6 +11,7 @@
 #define FireEtwGCRestartEEEnd_V1(ClrInstanceID) 0
 #define FireEtwGCHeapStats(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount) 0
 #define FireEtwGCHeapStats_V1(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount, ClrInstanceID) 0
+#define FireEtwGCHeapStats_V2(GenerationSize0, TotalPromotedSize0, GenerationSize1, TotalPromotedSize1, GenerationSize2, TotalPromotedSize2, GenerationSize3, TotalPromotedSize3, FinalizationPromotedSize, FinalizationPromotedCount, PinnedObjectCount, SinkBlockCount, GCHandleCount, ClrInstanceID, GenerationSize4, TotalPromotedSize4) 0
 #define FireEtwGCCreateSegment(Address, Size, Type) 0
 #define FireEtwGCCreateSegment_V1(Address, Size, Type, ClrInstanceID) 0
 #define FireEtwGCFreeSegment(Address) 0
 #define FireEtwBGCDrainMark(Objects, ClrInstanceID) 0
 #define FireEtwBGCRevisit(Pages, Objects, IsLarge, ClrInstanceID) 0
 #define FireEtwBGCOverflow(Min, Max, Objects, IsLarge, ClrInstanceID) 0
+#define FireEtwBGCOverflow_V1(Min, Max, Objects, IsLarge, ClrInstanceID, GenNumber) 0
 #define FireEtwBGCAllocWaitBegin(Reason, ClrInstanceID) 0
 #define FireEtwBGCAllocWaitEnd(Reason, ClrInstanceID) 0
 #define FireEtwGCFullNotify(GenNumber, IsAlloc) 0
index 37c1798..fb844e7 100644 (file)
@@ -5043,11 +5043,16 @@ heap_segment* gc_heap::get_segment_for_uoh (int gen_number, size_t size
 #ifdef MULTIPLE_HEAPS
         heap_segment_heap (res) = hp;
 #endif //MULTIPLE_HEAPS
-        res->flags |= gen_number == poh_generation ?
+        res->flags |= (gen_number == poh_generation) ?
                                         heap_segment_flags_poh :
                                         heap_segment_flags_loh;
 
-        FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(res), (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)), gc_etw_segment_large_object_heap);
+        FIRE_EVENT(GCCreateSegment_V1,
+            heap_segment_mem(res),
+            (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)),
+            (gen_number == poh_generation) ?
+                gc_etw_segment_pinned_object_heap :
+                gc_etw_segment_large_object_heap);
 
         GCToEEInterface::DiagUpdateGenerationBounds();
 
@@ -16591,9 +16596,9 @@ inline
 void fire_overflow_event (uint8_t* overflow_min,
                           uint8_t* overflow_max,
                           size_t marked_objects,
-                          int large_objects_p)
+                          int gen_number)
 {
-    FIRE_EVENT(BGCOverflow, (uint64_t)overflow_min, (uint64_t)overflow_max, marked_objects, large_objects_p);
+    FIRE_EVENT(BGCOverflow_V1, (uint64_t)overflow_min, (uint64_t)overflow_max, marked_objects, gen_number == loh_generation, gen_number);
 }
 
 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
             }
 
             dprintf (2, ("h%d: SOH: ov-mo: %Id", heap_number, total_marked_objects));
-            fire_overflow_event (min_add, max_add, total_marked_objects, !small_object_segments);
+            fire_overflow_event (min_add, max_add, total_marked_objects, i);
             if (small_object_segments)
             {
                 concurrent_print_time_delta (concurrent_p ? "Cov SOH" : "Nov SOH");
@@ -34880,32 +34885,32 @@ void gc_heap::descr_generations_to_profiler (gen_walk_fn fn, void *context)
 #endif // _PREFAST_
 #endif //MULTIPLE_HEAPS
 
-        int curr_gen_number0 = max_generation+1;
-        while (curr_gen_number0 >= 0)
+        for (int curr_gen_number = total_generation_count-1; curr_gen_number >= 0; curr_gen_number--)
         {
-            generation* gen = hp->generation_of (curr_gen_number0);
+            generation* gen = hp->generation_of (curr_gen_number);
             heap_segment* seg = generation_start_segment (gen);
             while (seg && (seg != hp->ephemeral_heap_segment))
             {
-                assert (curr_gen_number0 > 0);
+                assert (curr_gen_number > 0);
 
                 // report bounds from heap_segment_mem (seg) to
                 // heap_segment_allocated (seg);
-                // for generation # curr_gen_number0
+                // for generation # curr_gen_number
                 // for heap # heap_no
 
-                fn(context, curr_gen_number0, heap_segment_mem (seg),
+                fn(context, curr_gen_number, heap_segment_mem (seg),
                                               heap_segment_allocated (seg),
-                                              curr_gen_number0 == max_generation+1 ? heap_segment_reserved (seg) : heap_segment_allocated (seg));
+                                              curr_gen_number > max_generation ? heap_segment_reserved (seg) : heap_segment_allocated (seg));
 
                 seg = heap_segment_next (seg);
             }
+
             if (seg)
             {
                 assert (seg == hp->ephemeral_heap_segment);
-                assert (curr_gen_number0 <= max_generation);
+                assert (curr_gen_number <= max_generation);
                 //
-                if (curr_gen_number0 == max_generation)
+                if (curr_gen_number == max_generation)
                 {
                     if (heap_segment_mem (seg) < generation_allocation_start (hp->generation_of (max_generation-1)))
                     {
@@ -34913,33 +34918,32 @@ void gc_heap::descr_generations_to_profiler (gen_walk_fn fn, void *context)
                         // generation_allocation_start (generation_of (max_generation-1))
                         // for heap # heap_number
 
-                        fn(context, curr_gen_number0, heap_segment_mem (seg),
+                        fn(context, curr_gen_number, heap_segment_mem (seg),
                                                       generation_allocation_start (hp->generation_of (max_generation-1)),
                                                       generation_allocation_start (hp->generation_of (max_generation-1)) );
                     }
                 }
-                else if (curr_gen_number0 != 0)
+                else if (curr_gen_number != 0)
                 {
-                    //report bounds from generation_allocation_start (generation_of (curr_gen_number0))
-                    // to generation_allocation_start (generation_of (curr_gen_number0-1))
+                    //report bounds from generation_allocation_start (generation_of (curr_gen_number))
+                    // to generation_allocation_start (generation_of (curr_gen_number-1))
                     // for heap # heap_number
 
-                    fn(context, curr_gen_number0, generation_allocation_start (hp->generation_of (curr_gen_number0)),
-                                                  generation_allocation_start (hp->generation_of (curr_gen_number0-1)),
-                                                  generation_allocation_start (hp->generation_of (curr_gen_number0-1)));
+                    fn(context, curr_gen_number, generation_allocation_start (hp->generation_of (curr_gen_number)),
+                                                  generation_allocation_start (hp->generation_of (curr_gen_number-1)),
+                                                  generation_allocation_start (hp->generation_of (curr_gen_number-1)));
                 }
                 else
                 {
-                    //report bounds from generation_allocation_start (generation_of (curr_gen_number0))
+                    //report bounds from generation_allocation_start (generation_of (curr_gen_number))
                     // to heap_segment_allocated (ephemeral_heap_segment);
                     // for heap # heap_number
 
-                    fn(context, curr_gen_number0, generation_allocation_start (hp->generation_of (curr_gen_number0)),
+                    fn(context, curr_gen_number, generation_allocation_start (hp->generation_of (curr_gen_number)),
                                                   heap_segment_allocated (hp->ephemeral_heap_segment),
                                                   heap_segment_reserved (hp->ephemeral_heap_segment) );
                 }
             }
-            curr_gen_number0--;
         }
     }
 }
index 6ef6eef..a811510 100644 (file)
@@ -97,7 +97,8 @@ enum gc_etw_segment_type
 enum gc_etw_alloc_kind
 {
     gc_etw_alloc_soh = 0,
-    gc_etw_alloc_loh = 1
+    gc_etw_alloc_loh = 1,
+    gc_etw_alloc_poh = 2
 };
 
 /* forward declerations */
index c874967..0265ffe 100644 (file)
@@ -167,11 +167,12 @@ void GCHeap::UpdatePostGCCounters()
         g_GenerationSizes[3], g_GenerationPromotedSizes[3]));
 #endif //SIMPLE_DPRINTF
 
-    FIRE_EVENT(GCHeapStats_V1,
+    FIRE_EVENT(GCHeapStats_V2,
         g_GenerationSizes[0], g_GenerationPromotedSizes[0],
         g_GenerationSizes[1], g_GenerationPromotedSizes[1],
         g_GenerationSizes[2], g_GenerationPromotedSizes[2],
         g_GenerationSizes[3], g_GenerationPromotedSizes[3],
+        g_GenerationSizes[4], g_GenerationPromotedSizes[4],
         promoted_finalization_mem,
         GetFinalizablePromotedCount(),
         static_cast<uint32_t>(total_num_pinned_objects),
@@ -326,7 +327,22 @@ bool GCHeap::IsConcurrentGCInProgress()
 #ifdef FEATURE_EVENT_TRACE
 void gc_heap::fire_etw_allocation_event (size_t allocation_amount, int gen_number, uint8_t* object_address)
 {
-    gc_etw_alloc_kind kind = gen_number == 0 ? gc_etw_alloc_soh : gc_etw_alloc_loh;
+    gc_etw_alloc_kind kind;
+    switch (gen_number)
+    {
+    case 0:
+        kind = gc_etw_alloc_soh;
+        break;
+    case 3:
+        kind = gc_etw_alloc_loh;
+        break;
+    case 4:
+        kind = gc_etw_alloc_poh;
+        break;
+    default:
+        __UNREACHABLE();
+    }
+
     FIRE_EVENT(GCAllocationTick_V3, static_cast<uint64_t>(allocation_amount), kind, heap_number, object_address);
 }
 
@@ -401,12 +417,18 @@ void GCHeap::DiagTraceGCSegments()
             FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(type));
         }
 
-        // large obj segments
-        for (seg = generation_start_segment (h->generation_of (loh_generation)); seg != 0; seg = heap_segment_next(seg))
+        // uoh segments
+        for (int i = uoh_start_generation; i < total_generation_count; i++)
         {
-            uint8_t* address = heap_segment_mem (seg);
-            size_t size = heap_segment_reserved (seg) - heap_segment_mem (seg);
-            FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(gc_etw_segment_large_object_heap));
+            for (seg = generation_start_segment (h->generation_of (i)); seg != 0; seg = heap_segment_next(seg))
+            {
+                uint8_t* address = heap_segment_mem (seg);
+                size_t size = heap_segment_reserved (seg) - heap_segment_mem (seg);
+                gc_etw_segment_type segment_type = (i == loh_generation) ?
+                    gc_etw_segment_large_object_heap :
+                    gc_etw_segment_pinned_object_heap;
+                FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(segment_type));
+            }
         }
     }
 #endif // FEATURE_EVENT_TRACE
index 8709f59..cb473ee 100644 (file)
@@ -12,7 +12,7 @@
 KNOWN_EVENT(GCStart_V2, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
 KNOWN_EVENT(GCEnd_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
 KNOWN_EVENT(GCGenerationRange, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHeapSurvivalAndMovement)
-KNOWN_EVENT(GCHeapStats_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+KNOWN_EVENT(GCHeapStats_V2, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
 KNOWN_EVENT(GCCreateSegment_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
 KNOWN_EVENT(GCFreeSegment_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
 KNOWN_EVENT(GCCreateConcurrentThread_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
@@ -39,7 +39,7 @@ KNOWN_EVENT(BGC2ndConBegin, GCEventProvider_Private, GCEventLevel_Information, G
 KNOWN_EVENT(BGC2ndConEnd, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(BGCDrainMark, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(BGCRevisit, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
-KNOWN_EVENT(BGCOverflow, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
+KNOWN_EVENT(BGCOverflow_V1, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(BGCAllocWaitBegin, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(BGCAllocWaitEnd, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(GCFullNotify_V1, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
index a3a5844..b4507a5 100644 (file)
@@ -50,7 +50,7 @@ public:
     void FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength) = 0;
 
     virtual
-    void FireGCHeapStats_V1(
+    void FireGCHeapStats_V2(
         uint64_t generationSize0,
         uint64_t totalPromotedSize0,
         uint64_t generationSize1,
@@ -59,6 +59,8 @@ public:
         uint64_t totalPromotedSize2,
         uint64_t generationSize3,
         uint64_t totalPromotedSize3,
+        uint64_t generationSize4,
+        uint64_t totalPromotedSize4,
         uint64_t finalizationPromotedSize,
         uint64_t finalizationPromotedCount,
         uint32_t pinnedObjectCount,
@@ -148,7 +150,7 @@ public:
     virtual
     void FireBGCRevisit(uint64_t pages, uint64_t objects, uint32_t isLarge) = 0;
     virtual
-    void FireBGCOverflow(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge) = 0;
+    void FireBGCOverflow_V1(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge, uint32_t genNumber) = 0;
     virtual
     void FireBGCAllocWaitBegin(uint32_t reason) = 0;
     virtual
index ad76bd6..cc91068 100644 (file)
@@ -1952,7 +1952,8 @@ typedef enum
     COR_PRF_GC_GEN_0 = 0,
     COR_PRF_GC_GEN_1 = 1,
     COR_PRF_GC_GEN_2 = 2,
-    COR_PRF_GC_LARGE_OBJECT_HEAP = 3
+    COR_PRF_GC_LARGE_OBJECT_HEAP = 3,
+    COR_PRF_GC_PINNED_OBJECT_HEAP= 4
 }   COR_PRF_GC_GENERATION;
 
 
index b7ae8bc..4a2444f 100644 (file)
@@ -1523,7 +1523,8 @@ enum __MIDL___MIDL_itf_corprof_0000_0001_0004
         COR_PRF_GC_GEN_0    = 0,
         COR_PRF_GC_GEN_1    = 1,
         COR_PRF_GC_GEN_2    = 2,
-        COR_PRF_GC_LARGE_OBJECT_HEAP    = 3
+        COR_PRF_GC_LARGE_OBJECT_HEAP    = 3,
+        COR_PRF_GC_PINNED_OBJECT_HEAP   = 4
     }   COR_PRF_GC_GENERATION;
 
 typedef struct COR_PRF_GC_GENERATION_RANGE
index 557eb79..c68eac5 100644 (file)
                         </UserData>
                     </template>
 
+                    <template tid="GCHeapStats_V2">
+                        <data name="GenerationSize0" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="TotalPromotedSize0" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="GenerationSize1" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="TotalPromotedSize1" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="GenerationSize2" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="TotalPromotedSize2" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="GenerationSize3" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="TotalPromotedSize3" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="FinalizationPromotedSize" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="FinalizationPromotedCount" inType="win:UInt64" />
+                        <data name="PinnedObjectCount" inType="win:UInt32" />
+                        <data name="SinkBlockCount" inType="win:UInt32" />
+                        <data name="GCHandleCount" inType="win:UInt32" />
+                        <data name="ClrInstanceID" inType="win:UInt16" />
+                        <data name="GenerationSize4" inType="win:UInt64" outType="win:HexInt64" />
+                        <data name="TotalPromotedSize4" inType="win:UInt64" outType="win:HexInt64" />
+
+                        <UserData>
+                            <GCHeapStats_V2 xmlns="myNs">
+                                <GenerationSize0> %1 </GenerationSize0>
+                                <TotalPromotedSize0> %2 </TotalPromotedSize0>
+                                <GenerationSize1> %3 </GenerationSize1>
+                                <TotalPromotedSize1> %4 </TotalPromotedSize1>
+                                <GenerationSize2> %5 </GenerationSize2>
+                                <TotalPromotedSize2> %6 </TotalPromotedSize2>
+                                <GenerationSize3> %7 </GenerationSize3>
+                                <TotalPromotedSize3> %8 </TotalPromotedSize3>
+                                <FinalizationPromotedSize> %9 </FinalizationPromotedSize>
+                                <FinalizationPromotedCount> %10 </FinalizationPromotedCount>
+                                <PinnedObjectCount> %11 </PinnedObjectCount>
+                                <SinkBlockCount> %12 </SinkBlockCount>
+                                <GCHandleCount> %13 </GCHandleCount>
+                                <ClrInstanceID> %14 </ClrInstanceID>
+                                <GenerationSize4> %15 </GenerationSize4>
+                                <TotalPromotedSize4> %16 </TotalPromotedSize4>
+                            </GCHeapStats_V2>
+                        </UserData>
+                    </template>
+                    
                     <template tid="GCCreateSegment">
                         <data name="Address" inType="win:UInt64" outType="win:HexInt64" />
                         <data name="Size" inType="win:UInt64" outType="win:HexInt64" />
                            task="GarbageCollection"
                            symbol="GCHeapStats_V1" message="$(string.RuntimePublisher.GCHeapStats_V1EventMessage)"/>
 
+                    <event value="4" version="2" level="win:Informational"  template="GCHeapStats_V2"
+                           keywords ="GCKeyword" opcode="GCHeapStats"
+                           task="GarbageCollection"
+                           symbol="GCHeapStats_V2" message="$(string.RuntimePublisher.GCHeapStats_V2EventMessage)"/>
+
                     <event value="5" version="0" level="win:Informational"  template="GCCreateSegment"
                            keywords ="GCKeyword" opcode="GCCreateSegment"
                            task="GarbageCollection"
                         </UserData>
                     </template>
 
+                    <template tid="BGCOverflow_V1">
+                        <data name="Min" inType="win:UInt64" />
+                        <data name="Max" inType="win:UInt64" />
+                        <data name="Objects" inType="win:UInt64" />
+                        <data name="IsLarge" inType="win:UInt32" />
+                        <data name="ClrInstanceID" inType="win:UInt16" />
+                        <data name="GenNumber" inType="win:UInt32" />
+
+                        <UserData>
+                            <BGCOverflow_V1 xmlns="myNs">
+                                <Min> %1 </Min>
+                                <Max> %2 </Max>
+                                <Objects> %3 </Objects>
+                                <IsLarge> %4 </IsLarge>
+                                <ClrInstanceID> %5 </ClrInstanceID>
+                                <GenNumber> %6 </GenNumber>
+                            </BGCOverflow_V1>
+                        </UserData>
+                    </template>
+
                     <template tid="BGCAllocWait">
                         <data name="Reason" inType="win:UInt32" />
                         <data name="ClrInstanceID" inType="win:UInt16" />
                            task="GarbageCollectionPrivate"
                            symbol="BGCOverflow" message="$(string.PrivatePublisher.BGCOverflowEventMessage)"/>
 
+                    <event value="22" version="1" level="win:Informational"  template="BGCOverflow_V1"
+                           keywords ="GCPrivateKeyword"  opcode="BGCOverflow"
+                           task="GarbageCollectionPrivate"
+                           symbol="BGCOverflow_V1" message="$(string.PrivatePublisher.BGCOverflowEventMessage)"/>
+
                     <event value="23" version="0" level="win:Informational"  template="BGCAllocWait"
                            keywords ="GCPrivateKeyword"  opcode="BGCAllocWaitBegin"
                            task="GarbageCollectionPrivate"
                 <string id="RuntimePublisher.GCEnd_V1EventMessage" value="Count=%1;%nDepth=%2;%nClrInstanceID=%3" />
                 <string id="RuntimePublisher.GCHeapStatsEventMessage" value="GenerationSize0=%1;%nTotalPromotedSize0=%2;%nGenerationSize1=%3;%nTotalPromotedSize1=%4;%nGenerationSize2=%5;%nTotalPromotedSize2=%6;%nGenerationSize3=%7;%nTotalPromotedSize3=%8;%nFinalizationPromotedSize=%9;%nFinalizationPromotedCount=%10;%nPinnedObjectCount=%11;%nSinkBlockCount=%12;%nGCHandleCount=%13" />
                 <string id="RuntimePublisher.GCHeapStats_V1EventMessage" value="GenerationSize0=%1;%nTotalPromotedSize0=%2;%nGenerationSize1=%3;%nTotalPromotedSize1=%4;%nGenerationSize2=%5;%nTotalPromotedSize2=%6;%nGenerationSize3=%7;%nTotalPromotedSize3=%8;%nFinalizationPromotedSize=%9;%nFinalizationPromotedCount=%10;%nPinnedObjectCount=%11;%nSinkBlockCount=%12;%nGCHandleCount=%13;%nClrInstanceID=%14" />
+                <string id="RuntimePublisher.GCHeapStats_V2EventMessage" value="GenerationSize0=%1;%nTotalPromotedSize0=%2;%nGenerationSize1=%3;%nTotalPromotedSize1=%4;%nGenerationSize2=%5;%nTotalPromotedSize2=%6;%nGenerationSize3=%7;%nTotalPromotedSize3=%8;%nFinalizationPromotedSize=%9;%nFinalizationPromotedCount=%10;%nPinnedObjectCount=%11;%nSinkBlockCount=%12;%nGCHandleCount=%13;%nClrInstanceID=%14;%nGenerationSize4=%15;%nTotalPromotedSize4=%16" />
                 <string id="RuntimePublisher.GCCreateSegmentEventMessage" value="Address=%1;%nSize=%2;%nType=%3" />
                 <string id="RuntimePublisher.GCCreateSegment_V1EventMessage" value="Address=%1;%nSize=%2;%nType=%3;%nClrInstanceID=%4" />
                 <string id="RuntimePublisher.GCFreeSegmentEventMessage" value="Address=%1" />
                 <string id="PrivatePublisher.BGCDrainMarkEventMessage" value="Objects=%1;%nClrInstanceID=%2"/>
                 <string id="PrivatePublisher.BGCRevisitEventMessage" value="Pages=%1;%nObjects=%2;%nIsLarge=%3;%nClrInstanceID=%4"/>
                 <string id="PrivatePublisher.BGCOverflowEventMessage" value="Min=%1;%nMax=%2;%Objects=%3;%nIsLarge=%4;%nClrInstanceID=%5"/>
+                <string id="PrivatePublisher.BGCOverflow_V1EventMessage" value="Min=%1;%nMax=%2;%Objects=%3;%nIsLarge=%4;%nClrInstanceID=%5;%GenNumber=%6"/>
                 <string id="PrivatePublisher.BGCAllocWaitEventMessage" value="Reason=%1;%nClrInstanceID=%2"/>
                 <string id="PrivatePublisher.GCFullNotifyEventMessage" value="GenNumber=%1;%nIsAlloc=%2"/>
                 <string id="PrivatePublisher.GCFullNotify_V1EventMessage" value="GenNumber=%1;%nIsAlloc=%2;%nClrInstanceID=%3"/>
index 5fab02f..285e910 100644 (file)
@@ -53,11 +53,13 @@ nomac:GarbageCollection:::GCRestartEEEnd
 noclrinstanceid:GarbageCollection:::GCRestartEEEnd
 nostack:GarbageCollection:::GCRestartEEEnd
 nostack:GarbageCollection:::GCRestartEEEnd_V1
-nomac:GarbageCollection:::GCHeapStats
 noclrinstanceid:GarbageCollection:::GCHeapStats
 nostack:GarbageCollection:::GCHeapStats
 nostack:GarbageCollection:::GCHeapStats_V1
+nostack:GarbageCollection:::GCHeapStats_V2
+nomac:GarbageCollection:::GCHeapStats
 nomac:GarbageCollection:::GCHeapStats_V1
+nomac:GarbageCollection:::GCHeapStats_V2
 nomac:GarbageCollection:::GCCreateSegment
 nostack:GarbageCollection:::GCCreateSegment
 noclrinstanceid:GarbageCollection:::GCCreateSegment
@@ -447,6 +449,7 @@ nomac:GarbageCollectionPrivate:::BGCSweepEnd
 nomac:GarbageCollectionPrivate:::BGCDrainMark
 nomac:GarbageCollectionPrivate:::BGCRevisit
 nomac:GarbageCollectionPrivate:::BGCOverflow
+nomac:GarbageCollectionPrivate:::BGCOverflow_V1
 nomac:GarbageCollectionPrivate:::BGCAllocWaitBegin
 nomac:GarbageCollectionPrivate:::BGCAllocWaitEnd
 nomac:GarbageCollectionPrivate:::GCFullNotify
index a9bc4bd..57dfdef 100644 (file)
@@ -51,7 +51,7 @@ void GCToCLREventSink::FireGCEnd_V1(uint32_t count, uint32_t depth)
     FireEtwGCEnd_V1(count, depth, GetClrInstanceId());
 }
 
-void GCToCLREventSink::FireGCHeapStats_V1(
+void GCToCLREventSink::FireGCHeapStats_V2(
         uint64_t generationSize0,
         uint64_t totalPromotedSize0,
         uint64_t generationSize1,
@@ -60,6 +60,8 @@ void GCToCLREventSink::FireGCHeapStats_V1(
         uint64_t totalPromotedSize2,
         uint64_t generationSize3,
         uint64_t totalPromotedSize3,
+        uint64_t generationSize4,
+        uint64_t totalPromotedSize4,
         uint64_t finalizationPromotedSize,
         uint64_t finalizationPromotedCount,
         uint32_t pinnedObjectCount,
@@ -68,10 +70,11 @@ void GCToCLREventSink::FireGCHeapStats_V1(
 {
     LIMITED_METHOD_CONTRACT;
 
-    FireEtwGCHeapStats_V1(generationSize0, totalPromotedSize0, generationSize1, totalPromotedSize1,
+    FireEtwGCHeapStats_V2(generationSize0, totalPromotedSize0, generationSize1, totalPromotedSize1,
                           generationSize2, totalPromotedSize2, generationSize3, totalPromotedSize3,
                           finalizationPromotedSize, finalizationPromotedCount, pinnedObjectCount,
-                          sinkBlockCount, gcHandleCount, GetClrInstanceId());
+                          sinkBlockCount, gcHandleCount, GetClrInstanceId(),
+                          generationSize4, totalPromotedSize4);
 }
 
 void GCToCLREventSink::FireGCCreateSegment_V1(void* address, size_t size, uint32_t type)
@@ -303,9 +306,9 @@ void GCToCLREventSink::FireBGCRevisit(uint64_t pages, uint64_t objects, uint32_t
     FireEtwBGCRevisit(pages, objects, isLarge, GetClrInstanceId());
 }
 
-void GCToCLREventSink::FireBGCOverflow(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge)
+void GCToCLREventSink::FireBGCOverflow_V1(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge, uint32_t genNumber)
 {
-    FireEtwBGCOverflow(min, max, objects, isLarge, GetClrInstanceId());
+    FireEtwBGCOverflow_V1(min, max, objects, isLarge, GetClrInstanceId(), genNumber);
 }
 
 void GCToCLREventSink::FireBGCAllocWaitBegin(uint32_t reason)
index 38b1b0a..3312b07 100644 (file)
@@ -14,7 +14,7 @@ public:
     void FireGCStart_V2(uint32_t count, uint32_t depth, uint32_t reason, uint32_t type);
     void FireGCEnd_V1(uint32_t count, uint32_t depth);
     void FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength);
-    void FireGCHeapStats_V1(uint64_t generationSize0,
+    void FireGCHeapStats_V2(uint64_t generationSize0,
                             uint64_t totalPromotedSize0,
                             uint64_t generationSize1,
                             uint64_t totalPromotedSize1,
@@ -22,6 +22,8 @@ public:
                             uint64_t totalPromotedSize2,
                             uint64_t generationSize3,
                             uint64_t totalPromotedSize3,
+                            uint64_t generationSize4,
+                            uint64_t totalPromotedSize4,
                             uint64_t finalizationPromotedSize,
                             uint64_t finalizationPromotedCount,
                             uint32_t pinnedObjectCount,
@@ -74,7 +76,7 @@ public:
     void FireBGC2ndConEnd();
     void FireBGCDrainMark(uint64_t objects);
     void FireBGCRevisit(uint64_t pages, uint64_t objects, uint32_t isLarge);
-    void FireBGCOverflow(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge);
+    void FireBGCOverflow_V1(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge, uint32_t genNumber);
     void FireBGCAllocWaitBegin(uint32_t reason);
     void FireBGCAllocWaitEnd(uint32_t reason);
     void FireGCFullNotify_V1(uint32_t genNumber, uint32_t isAlloc);
index cbdae62..385ff4a 100644 (file)
@@ -665,14 +665,14 @@ void __stdcall GarbageCollectionStartedCallback(int generation, BOOL induced)
     // Notify the profiler of start of the collection
     {
         BEGIN_PIN_PROFILER(CORProfilerTrackGC() || CORProfilerTrackBasicGC());
-        BOOL generationCollected[COR_PRF_GC_LARGE_OBJECT_HEAP+1];
+        BOOL generationCollected[COR_PRF_GC_PINNED_OBJECT_HEAP+1];
         if (generation == COR_PRF_GC_GEN_2)
-            generation = COR_PRF_GC_LARGE_OBJECT_HEAP;
-        for (int gen = 0; gen <= COR_PRF_GC_LARGE_OBJECT_HEAP; gen++)
+            generation = COR_PRF_GC_PINNED_OBJECT_HEAP;
+        for (int gen = 0; gen <= COR_PRF_GC_PINNED_OBJECT_HEAP; gen++)
             generationCollected[gen] = gen <= generation;
 
         g_profControlBlock.pProfInterface->GarbageCollectionStarted(
-            COR_PRF_GC_LARGE_OBJECT_HEAP+1,
+            COR_PRF_GC_PINNED_OBJECT_HEAP+1,
             generationCollected,
             induced ? COR_PRF_GC_INDUCED : COR_PRF_GC_OTHER);
         END_PIN_PROFILER();
@@ -726,7 +726,7 @@ struct GenerationTable
 {
     ULONG count;
     ULONG capacity;
-    static const ULONG defaultCapacity = 4; // that's the minimum for 3 generation plus the large object heap
+    static const ULONG defaultCapacity = 5; // that's the minimum for Gen0-2 + LOH + POH
     GenerationTable *prev;
     GenerationDesc *genDescTable;
 #ifdef  _DEBUG
@@ -765,7 +765,7 @@ static void GenWalkFunc(void * context,
         GC_NOTRIGGER;
         MODE_ANY; // can be called even on GC threads
         PRECONDITION(CheckPointer(context));
-        PRECONDITION(0 <= generation && generation <= 3);
+        PRECONDITION(0 <= generation && generation <= 4);
         PRECONDITION(CheckPointer(rangeStart));
         PRECONDITION(CheckPointer(rangeEnd));
         PRECONDITION(CheckPointer(rangeEndReserved));
index 2beb48e..d5d2412 100644 (file)
@@ -96,6 +96,7 @@ HRESULT GCBasicProfiler::GarbageCollectionStarted(int cGenerations, BOOL generat
             {
             case 0:
             case 3:
+            case 4:
                 // no useful verification
                 break;
             case 1:
@@ -132,4 +133,4 @@ HRESULT GCBasicProfiler::GarbageCollectionFinished()
         printf("GCBasicProfiler::GarbageCollectionFinished: FAIL: Expected GCStart >= GCFinish. Start=%d, Finish=%d\n", (int)_gcStarts, (int)_gcFinishes);
     }
     return S_OK;
-}
\ No newline at end of file
+}