[Local GC] FEATURE_EVENT_TRACE 4/n: Event ports for all GC-keyword events (#16031)
authorSean Gillespie <sean@pulumi.com>
Tue, 30 Jan 2018 22:27:16 +0000 (14:27 -0800)
committerDavid Mason <davmason@microsoft.com>
Tue, 30 Jan 2018 22:27:16 +0000 (14:27 -0800)
* [Local GC] Event ports: GCStart and GCGenerationRange

* [Local GC] Event ports: GCEnd

* [Local GC] Event ports: GCHeapStats

* [Local GC] Event ports: GCCreateSegment

* [Local GC] Event ports: GCFreeSegment

* Event ports: GCCreateConcurrentThread and GCTerminateConcurrentThread

* [Local GC] Event ports: GCTriggered

* [Local GC] Event ports: GCMarkWithType

* [Local GC] Event ports: GCJoin_V2

* [Local GC] Event ports: GCGlobalHeapHistory_V2

* [Local GC] Event ports: GCAllocationTick_V3

* [Local GC] Event ports: GCAllocationTick_V1

* [Local GC] Event porting: PinObjectAtGCTime

* one last merge conflict

src/gc/gc.cpp
src/gc/gc.h
src/gc/gcee.cpp
src/gc/gcevents.h
src/gc/gcinterface.ee.h
src/inc/eventtrace.h
src/vm/eventtrace.cpp
src/vm/gctoclreventsink.cpp
src/vm/gctoclreventsink.h

index 2b31388..d6ab65a 100644 (file)
@@ -816,7 +816,7 @@ public:
 
     inline void fire_event (int heap, join_time time, join_type type, int join_id)
     {
-        FireEtwGCJoin_V2(heap, time, type, GetClrInstanceId(), join_id);
+        FIRE_EVENT(GCJoin_V2, heap, time, type, join_id);
     }
 
     void join (gc_heap* gch, int join_id)
@@ -3028,13 +3028,12 @@ void gc_heap::fire_pevents()
     settings.record (&gc_data_global);
     gc_data_global.print();
 
-    FireEtwGCGlobalHeapHistory_V2(gc_data_global.final_youngest_desired, 
+    FIRE_EVENT(GCGlobalHeapHistory_V2, gc_data_global.final_youngest_desired, 
                                   gc_data_global.num_heaps, 
                                   gc_data_global.condemned_generation, 
                                   gc_data_global.gen0_reduction_count, 
                                   gc_data_global.reason, 
                                   gc_data_global.global_mechanims_p, 
-                                  GetClrInstanceId(),
                                   gc_data_global.pause_mode, 
                                   gc_data_global.mem_pressure);
 
@@ -4677,10 +4676,9 @@ gc_heap::soh_get_segment_to_expand()
         }
 #endif //BACKGROUND_GC
 
-        FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(result), 
-                                  (size_t)(heap_segment_reserved (result) - heap_segment_mem(result)), 
-                                  ETW::GCLog::ETW_GC_INFO::SMALL_OBJECT_HEAP, 
-                                  GetClrInstanceId());
+        FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(result),
+                                  (size_t)(heap_segment_reserved (result) - heap_segment_mem(result)),
+                                  gc_etw_segment_small_object_heap);
     }
 
     get_gc_data_per_heap()->set_mechanism (gc_heap_expand, (result ? expand_new_seg : expand_no_memory));
@@ -4846,7 +4844,7 @@ gc_heap::get_segment (size_t size, BOOL loh_p)
 void release_segment (heap_segment* sg)
 {
     ptrdiff_t delta = 0;
-    FireEtwGCFreeSegment_V1((size_t)heap_segment_mem(sg), GetClrInstanceId());
+    FIRE_EVENT(GCFreeSegment_V1, heap_segment_mem(sg));
     virtual_free (sg, (uint8_t*)heap_segment_reserved (sg)-(uint8_t*)sg);
 }
 
@@ -4867,7 +4865,7 @@ heap_segment* gc_heap::get_segment_for_loh (size_t size
 #endif //MULTIPLE_HEAPS
         res->flags |= heap_segment_flags_loh;
 
-        FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(res), (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)), ETW::GCLog::ETW_GC_INFO::LARGE_OBJECT_HEAP, GetClrInstanceId());
+        FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(res), (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)), gc_etw_segment_large_object_heap);
 
         GCToEEInterface::DiagUpdateGenerationBounds();
 
@@ -7837,7 +7835,7 @@ BOOL gc_heap::insert_ro_segment (heap_segment* seg)
         set_ro_segment_in_range (seg);
     }
 
-    FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(seg), (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg)), ETW::GCLog::ETW_GC_INFO::READ_ONLY_HEAP, GetClrInstanceId());
+    FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(seg), (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg)), gc_etw_segment_read_only_heap);
 
     leave_spin_lock (&gc_heap::gc_lock);
     return TRUE;
@@ -10448,10 +10446,9 @@ gc_heap::init_gc_heap (int  h_number)
     if (!seg)
         return 0;
 
-    FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(seg), 
-                              (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg)), 
-                              ETW::GCLog::ETW_GC_INFO::SMALL_OBJECT_HEAP, 
-                              GetClrInstanceId());
+    FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(seg),
+                              (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg)),
+                              gc_etw_segment_small_object_heap);
     
 #ifdef SEG_MAPPING_TABLE
     seg_mapping_table_add_segment (seg, __this);
@@ -10514,10 +10511,9 @@ gc_heap::init_gc_heap (int  h_number)
         return 0;
     lseg->flags |= heap_segment_flags_loh;
 
-    FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(lseg), 
-                              (size_t)(heap_segment_reserved (lseg) - heap_segment_mem(lseg)), 
-                              ETW::GCLog::ETW_GC_INFO::LARGE_OBJECT_HEAP, 
-                              GetClrInstanceId());
+    FIRE_EVENT(GCCreateSegment_V1, heap_segment_mem(lseg),
+                              (size_t)(heap_segment_reserved (lseg) - heap_segment_mem(lseg)),
+                              gc_etw_segment_large_object_heap);
 
 #ifdef SEG_MAPPING_TABLE
     seg_mapping_table_add_segment (lseg, __this);
@@ -13229,9 +13225,8 @@ int gc_heap::try_allocate_more_space (alloc_context* acontext, size_t size,
         if (etw_allocation_running_amount[etw_allocation_index] > etw_allocation_tick)
         {
 #ifdef FEATURE_REDHAWK
-            FireEtwGCAllocationTick_V1((uint32_t)etw_allocation_running_amount[etw_allocation_index], 
-                                    ((gen_number == 0) ? ETW::GCLog::ETW_GC_INFO::AllocationSmall : ETW::GCLog::ETW_GC_INFO::AllocationLarge), 
-                                    GetClrInstanceId());
+            FIRE_EVENT(GCAllocationTick_V1, (uint32_t)etw_allocation_running_amount[etw_allocation_index],
+                                            (gen_number == 0) ? gc_etw_alloc_soh : gc_etw_alloc_loh);
 #else
             // Unfortunately some of the ETW macros do not check whether the ETW feature is enabled.
             // The ones that do are much less efficient.
@@ -19163,7 +19158,7 @@ void gc_heap::get_memory_info (uint32_t* memory_load,
 void fire_mark_event (int heap_num, int root_type, size_t bytes_marked)
 {
     dprintf (DT_LOG_0, ("-----------[%d]mark %d: %Id", heap_num, root_type, bytes_marked));
-    FireEtwGCMarkWithType (heap_num, GetClrInstanceId(), root_type, bytes_marked);
+    FIRE_EVENT(GCMarkWithType, heap_num, root_type, bytes_marked);
 }
 
 //returns TRUE is an overflow happened.
@@ -26702,7 +26697,7 @@ BOOL gc_heap::prepare_bgc_thread(gc_heap* gh)
     gh->bgc_threads_timeout_cs.Leave();
 
     if(thread_created)
-        FireEtwGCCreateConcurrentThread_V1(GetClrInstanceId());
+        FIRE_EVENT(GCCreateConcurrentThread_V1);
 
     return success;
 }
@@ -27044,7 +27039,7 @@ void gc_heap::bgc_thread_function()
         //gc_heap::disable_preemptive (current_thread, TRUE);
     }
 
-    FireEtwGCTerminateConcurrentThread_V1(GetClrInstanceId());
+    FIRE_EVENT(GCTerminateConcurrentThread_V1);
 
     dprintf (3, ("bgc_thread thread exiting"));
     return;
@@ -35081,7 +35076,7 @@ GCHeap::GarbageCollectGeneration (unsigned int gen, gc_reason reason)
     // We want to get a stack from the user thread that triggered the GC
     // instead of on the GC thread which is the case for Server GC.
     // But we are doing it for Workstation GC as well to be uniform.
-    FireEtwGCTriggered((int) reason, GetClrInstanceId());
+    FIRE_EVENT(GCTriggered, static_cast<uint32_t>(reason));
 
 #ifdef MULTIPLE_HEAPS
     GcCondemnedGeneration = condemned_generation_number;
index e16fccb..6641f0b 100644 (file)
@@ -70,6 +70,29 @@ enum gc_reason
     reason_max
 };
 
+// Types of GCs, emitted by the GCStart ETW event.
+enum gc_etw_type
+{
+   gc_etw_type_ngc = 0,
+   gc_etw_type_bgc = 1,
+   gc_etw_type_fgc = 2
+};
+
+// Types of segments, emitted by the GCCreateSegment ETW event.
+enum gc_etw_segment_type
+{
+    gc_etw_segment_small_object_heap = 0,
+    gc_etw_segment_large_object_heap = 1,
+    gc_etw_segment_read_only_heap = 2
+};
+
+// Types of allocations, emitted by the GCAllocationTick ETW event.
+enum gc_etw_alloc_kind
+{
+    gc_etw_alloc_soh = 0,
+    gc_etw_alloc_loh = 1
+};
+
 /* forward declerations */
 class CObjectHeader;
 class Object;
index c5cc88b..358b40c 100644 (file)
@@ -77,7 +77,6 @@ void GCHeap::UpdatePreGCCounters()
 
 #endif //ENABLE_PERF_COUNTERS
 
-#ifdef FEATURE_EVENT_TRACE
 #ifdef MULTIPLE_HEAPS
         //take the first heap....
     gc_mechanisms *pSettings = &gc_heap::g_heaps[0]->settings;
@@ -85,27 +84,28 @@ void GCHeap::UpdatePreGCCounters()
     gc_mechanisms *pSettings = &gc_heap::settings;
 #endif //MULTIPLE_HEAPS
 
-    ETW::GCLog::ETW_GC_INFO Info;
-
-    Info.GCStart.Count = (uint32_t)pSettings->gc_index;
-    Info.GCStart.Depth = (uint32_t)pSettings->condemned_generation;
-    Info.GCStart.Reason = (ETW::GCLog::ETW_GC_INFO::GC_REASON)((int)(pSettings->reason));
-
-    Info.GCStart.Type = ETW::GCLog::ETW_GC_INFO::GC_NGC;
+    uint32_t count = (uint32_t)pSettings->gc_index;
+    uint32_t depth = (uint32_t)pSettings->condemned_generation;
+    uint32_t reason = (uint32_t)pSettings->reason;
+    gc_etw_type type = gc_etw_type_ngc;
     if (pSettings->concurrent)
     {
-        Info.GCStart.Type = ETW::GCLog::ETW_GC_INFO::GC_BGC;
+        type = gc_etw_type_bgc;
     }
 #ifdef BACKGROUND_GC
-    else if (Info.GCStart.Depth < max_generation)
+    else if (depth < max_generation && pSettings->background_p)
     {
-        if (pSettings->background_p)
-            Info.GCStart.Type = ETW::GCLog::ETW_GC_INFO::GC_FGC;
+        type = gc_etw_type_fgc;
     }
-#endif //BACKGROUND_GC
+#endif // BACKGROUND_GC
 
-    ETW::GCLog::FireGcStartAndGenerationRanges(&Info);
-#endif // FEATURE_EVENT_TRACE
+    FIRE_EVENT(GCStart_V2, count, depth, reason, static_cast<uint32_t>(type));
+    g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved)
+    {
+        uint64_t range = static_cast<uint64_t>(rangeEnd - rangeStart);
+        uint64_t rangeReserved = static_cast<uint64_t>(rangeEndReserved - rangeStart);
+        FIRE_EVENT(GCGenerationRange, generation, rangeStart, range, rangeReserved);
+    }, nullptr);
 }
 
 void GCHeap::UpdatePostGCCounters()
@@ -195,50 +195,34 @@ void GCHeap::UpdatePostGCCounters()
 #endif //ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE
 
 #ifdef FEATURE_EVENT_TRACE
-    ETW::GCLog::ETW_GC_INFO Info;
-
-    Info.GCEnd.Depth = condemned_gen;
-    Info.GCEnd.Count = (uint32_t)pSettings->gc_index;
-    ETW::GCLog::FireGcEndAndGenerationRanges(Info.GCEnd.Count, Info.GCEnd.Depth);
-
-    ETW::GCLog::ETW_GC_INFO HeapInfo;
-    ZeroMemory(&HeapInfo, sizeof(HeapInfo));
-
-    for (int gen_index = 0; gen_index <= (max_generation+1); gen_index++)
+    g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved)
     {
-        HeapInfo.HeapStats.GenInfo[gen_index].GenerationSize = g_GenerationSizes[gen_index];
-        HeapInfo.HeapStats.GenInfo[gen_index].TotalPromotedSize = g_GenerationPromotedSizes[gen_index];
-    }
+        uint64_t range = static_cast<uint64_t>(rangeEnd - rangeStart);
+        uint64_t rangeReserved = static_cast<uint64_t>(rangeEndReserved - rangeStart);
+        FIRE_EVENT(GCGenerationRange, generation, rangeStart, range, rangeReserved);
+    }, nullptr);
+
+    FIRE_EVENT(GCEnd_V1, static_cast<uint32_t>(pSettings->gc_index), condemned_gen);
 
 #ifdef SIMPLE_DPRINTF
     dprintf (2, ("GC#%d: 0: %Id(%Id); 1: %Id(%Id); 2: %Id(%Id); 3: %Id(%Id)", 
-        Info.GCEnd.Count,
-        HeapInfo.HeapStats.GenInfo[0].GenerationSize,
-        HeapInfo.HeapStats.GenInfo[0].TotalPromotedSize,
-        HeapInfo.HeapStats.GenInfo[1].GenerationSize,
-        HeapInfo.HeapStats.GenInfo[1].TotalPromotedSize,
-        HeapInfo.HeapStats.GenInfo[2].GenerationSize,
-        HeapInfo.HeapStats.GenInfo[2].TotalPromotedSize,
-        HeapInfo.HeapStats.GenInfo[3].GenerationSize,
-        HeapInfo.HeapStats.GenInfo[3].TotalPromotedSize));
+        pSettings->gc_index,
+        g_GenerationSizes[0], g_GenerationPromotedSizes[0],
+        g_GenerationSizes[1], g_GenerationPromotedSizes[1],
+        g_GenerationSizes[2], g_GenerationPromotedSizes[2],
+        g_GenerationSizes[3], g_GenerationPromotedSizes[3]));
 #endif //SIMPLE_DPRINTF
 
-    HeapInfo.HeapStats.FinalizationPromotedSize = promoted_finalization_mem;
-    HeapInfo.HeapStats.FinalizationPromotedCount = GetFinalizablePromotedCount();
-    HeapInfo.HeapStats.PinnedObjectCount = (uint32_t)total_num_pinned_objects;
-    HeapInfo.HeapStats.SinkBlockCount =  total_num_sync_blocks;
-    HeapInfo.HeapStats.GCHandleCount =  (uint32_t)total_num_gc_handles;
-
-    FireEtwGCHeapStats_V1(HeapInfo.HeapStats.GenInfo[0].GenerationSize, HeapInfo.HeapStats.GenInfo[0].TotalPromotedSize,
-                    HeapInfo.HeapStats.GenInfo[1].GenerationSize, HeapInfo.HeapStats.GenInfo[1].TotalPromotedSize,
-                    HeapInfo.HeapStats.GenInfo[2].GenerationSize, HeapInfo.HeapStats.GenInfo[2].TotalPromotedSize,
-                    HeapInfo.HeapStats.GenInfo[3].GenerationSize, HeapInfo.HeapStats.GenInfo[3].TotalPromotedSize,
-                    HeapInfo.HeapStats.FinalizationPromotedSize,
-                    HeapInfo.HeapStats.FinalizationPromotedCount,
-                    HeapInfo.HeapStats.PinnedObjectCount,
-                    HeapInfo.HeapStats.SinkBlockCount,
-                    HeapInfo.HeapStats.GCHandleCount, 
-                    GetClrInstanceId());
+    FIRE_EVENT(GCHeapStats_V1,
+        g_GenerationSizes[0], g_GenerationPromotedSizes[0],
+        g_GenerationSizes[1], g_GenerationPromotedSizes[1],
+        g_GenerationSizes[2], g_GenerationPromotedSizes[2],
+        g_GenerationSizes[3], g_GenerationPromotedSizes[3],
+        promoted_finalization_mem,
+        GetFinalizablePromotedCount(),
+        static_cast<uint32_t>(total_num_pinned_objects),
+        total_num_sync_blocks,
+        static_cast<uint32_t>(total_num_gc_handles));
 #endif // FEATURE_EVENT_TRACE
 
 #if defined(ENABLE_PERF_COUNTERS)
@@ -458,70 +442,13 @@ 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)
 {
-    void * typeId = nullptr;
-    const WCHAR * name = nullptr;
-#ifdef FEATURE_REDHAWK
-    typeId = RedhawkGCInterface::GetLastAllocEEType();
-#else
-    InlineSString<MAX_CLASSNAME_LENGTH> strTypeName;
-
-    EX_TRY
-    {
-        TypeHandle th = GCToEEInterface::GetThread()->GetTHAllocContextObj();
-
-        if (th != 0)
-        {
-            th.GetName(strTypeName);
-            name = strTypeName.GetUnicode();
-            typeId = th.GetMethodTable();
-        }
-    }
-    EX_CATCH {}
-    EX_END_CATCH(SwallowAllExceptions)
-#endif
-
-    if (typeId != nullptr)
-    {
-        FireEtwGCAllocationTick_V3((uint32_t)allocation_amount,
-                                   ((gen_number == 0) ? ETW::GCLog::ETW_GC_INFO::AllocationSmall : ETW::GCLog::ETW_GC_INFO::AllocationLarge), 
-                                   GetClrInstanceId(),
-                                   allocation_amount,
-                                   typeId, 
-                                   name,
-                                   heap_number,
-                                   object_address
-                                   );
-    }
+    gc_etw_alloc_kind kind = gen_number == 0 ? gc_etw_alloc_soh : gc_etw_alloc_loh;
+    FIRE_EVENT(GCAllocationTick_V3, static_cast<uint64_t>(allocation_amount), kind, heap_number, object_address);
 }
+
 void gc_heap::fire_etw_pin_object_event (uint8_t* object, uint8_t** ppObject)
 {
-#ifdef FEATURE_REDHAWK
-    UNREFERENCED_PARAMETER(object);
-    UNREFERENCED_PARAMETER(ppObject);
-#else
-    Object* obj = (Object*)object;
-
-    InlineSString<MAX_CLASSNAME_LENGTH> strTypeName; 
-   
-    EX_TRY
-    {
-        FAULT_NOT_FATAL();
-
-        TypeHandle th = obj->GetGCSafeTypeHandleIfPossible();
-        if(th != NULL)
-        {
-            th.GetName(strTypeName);
-        }
-
-        FireEtwPinObjectAtGCTime(ppObject,
-                             object,
-                             obj->GetSize(),
-                             strTypeName.GetUnicode(),
-                             GetClrInstanceId());
-    }
-    EX_CATCH {}
-    EX_END_CATCH(SwallowAllExceptions)
-#endif // FEATURE_REDHAWK
+    FIRE_EVENT(PinObjectAtGCTime, object, ppObject);
 }
 #endif // FEATURE_EVENT_TRACE
 
@@ -600,22 +527,18 @@ void GCHeap::DiagTraceGCSegments()
 
         for (seg = generation_start_segment (h->generation_of (max_generation)); seg != 0; seg = heap_segment_next(seg))
         {
-            ETW::GCLog::ETW_GC_INFO Info;
-            Info.GCCreateSegment.Address = (size_t)heap_segment_mem(seg);
-            Info.GCCreateSegment.Size = (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg));
-            Info.GCCreateSegment.Type = (heap_segment_read_only_p (seg) ? 
-                                         ETW::GCLog::ETW_GC_INFO::READ_ONLY_HEAP :
-                                         ETW::GCLog::ETW_GC_INFO::SMALL_OBJECT_HEAP);
-            FireEtwGCCreateSegment_V1(Info.GCCreateSegment.Address, Info.GCCreateSegment.Size, Info.GCCreateSegment.Type, GetClrInstanceId());
+            uint8_t* address = heap_segment_mem (seg);
+            size_t size = heap_segment_reserved (seg) - heap_segment_mem (seg);
+            gc_etw_segment_type type = heap_segment_read_only_p (seg) ? gc_etw_segment_read_only_heap : gc_etw_segment_small_object_heap;
+            FIRE_EVENT(GCCreateSegment_V1, address, size, static_cast<uint32_t>(type));
         }
 
         // large obj segments
         for (seg = generation_start_segment (h->generation_of (max_generation+1)); seg != 0; seg = heap_segment_next(seg))
         {
-            FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(seg), 
-                                   (size_t)(heap_segment_reserved (seg) - heap_segment_mem(seg)), 
-                                   ETW::GCLog::ETW_GC_INFO::LARGE_OBJECT_HEAP, 
-                                   GetClrInstanceId());
+            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));
         }
     }
 #endif // FEATURE_EVENT_TRACE
@@ -623,9 +546,7 @@ void GCHeap::DiagTraceGCSegments()
 
 void GCHeap::DiagDescrGenerations (gen_walk_fn fn, void *context)
 {
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
     pGenGCHeap->descr_generations_to_profiler(fn, context);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
 }
 
 segment_handle GCHeap::RegisterFrozenSegment(segment_info *pseginfo)
index 974348a..f0f6ff6 100644 (file)
@@ -9,9 +9,25 @@
  #define DYNAMIC_EVENT(name, level, keyword, ...)
 #endif // DYNAMIC_EVENT
 
+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(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)
+KNOWN_EVENT(GCTerminateConcurrentThread_V1, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+KNOWN_EVENT(GCTriggered, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+KNOWN_EVENT(GCMarkWithType, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+KNOWN_EVENT(GCJoin_V2, GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC)
+KNOWN_EVENT(GCGlobalHeapHistory_V2, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+KNOWN_EVENT(GCAllocationTick_V1, GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC)
+KNOWN_EVENT(GCAllocationTick_V3, GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC)
+KNOWN_EVENT(PinObjectAtGCTime, GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC)
+KNOWN_EVENT(GCPerHeapHistory_V3, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC)
+
 KNOWN_EVENT(SetGCHandle, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHandle)
 KNOWN_EVENT(DestroyGCHandle, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHandle)
-KNOWN_EVENT(GCPerHeapHistory_V3, GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 
 KNOWN_EVENT(BGCBegin, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
 KNOWN_EVENT(BGC1stNonConEnd, GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate)
index a153c1d..a79043e 100644 (file)
@@ -26,6 +26,71 @@ public:
         void* payload,
         uint32_t payloadSize) = 0;
     virtual
+    void FireGCStart_V2(uint32_t count, uint32_t depth, uint32_t reason, uint32_t type) = 0;
+
+    virtual
+    void FireGCEnd_V1(uint32_t count, uint32_t depth) = 0;
+
+    virtual
+    void FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength) = 0;
+
+    virtual
+    void FireGCHeapStats_V1(
+        uint64_t generationSize0,
+        uint64_t totalPromotedSize0,
+        uint64_t generationSize1,
+        uint64_t totalPromotedSize1,
+        uint64_t generationSize2,
+        uint64_t totalPromotedSize2,
+        uint64_t generationSize3,
+        uint64_t totalPromotedSize3,
+        uint64_t finalizationPromotedSize,
+        uint64_t finalizationPromotedCount,
+        uint32_t pinnedObjectCount,
+        uint32_t sinkBlockCount,
+        uint32_t gcHandleCount) = 0;
+
+    virtual
+    void FireGCCreateSegment_V1(void* address, size_t size, uint32_t type) = 0;
+
+    virtual
+    void FireGCFreeSegment_V1(void* address) = 0;
+
+    virtual
+    void FireGCCreateConcurrentThread_V1() = 0;
+
+    virtual
+    void FireGCTerminateConcurrentThread_V1() = 0;
+
+    virtual
+    void FireGCTriggered(uint32_t reason) = 0;
+
+    virtual
+    void FireGCMarkWithType(uint32_t heapNum, uint32_t type, uint64_t bytes) = 0;
+
+    virtual
+    void FireGCJoin_V2(uint32_t heap, uint32_t joinTime, uint32_t joinType, uint32_t joinId) = 0;
+
+    virtual
+    void FireGCGlobalHeapHistory_V2(uint64_t finalYoungestDesired,
+        int32_t numHeaps,
+        uint32_t condemnedGeneration,
+        uint32_t gen0reductionCount,
+        uint32_t reason,
+        uint32_t globalMechanisms,
+        uint32_t pauseMode,
+        uint32_t memoryPressure) = 0;
+
+    virtual
+    void FireGCAllocationTick_V1(uint32_t allocationAmount, uint32_t allocationKind) = 0;
+
+    virtual
+    void FireGCAllocationTick_V3(uint64_t allocationAmount, uint32_t allocationKind, uint32_t heapIndex, void* objectAddress) = 0;
+
+    virtual
+    void FirePinObjectAtGCTime(void* object, uint8_t** ppObject) = 0;
+
+    virtual
     void FireGCPerHeapHistory_V3(void *freeListAllocated,
                                  void *freeListRejected,
                                  void *endOfSegAllocated,
index 765249e..1564c94 100644 (file)
@@ -325,14 +325,7 @@ namespace ETW
         static BOOL ShouldTrackMovementForEtw();
         static HRESULT ForceGCForDiagnostics();
         static VOID ForceGC(LONGLONG l64ClientSequenceNumber);
-        static VOID FireGcStartAndGenerationRanges(ETW_GC_INFO * pGcInfo);
-        static VOID FireGcEndAndGenerationRanges(ULONG Count, ULONG Depth);
-        static VOID FireSingleGenerationRangeEvent(
-            void * /* context */,
-            int generation, 
-            BYTE * rangeStart, 
-            BYTE * rangeEnd,
-            BYTE * rangeEndReserved);
+        static VOID FireGcStart(ETW_GC_INFO * pGcInfo);
         static VOID RootReference(
             LPVOID pvHandle,
             Object * pRootedNode,
index 533a3bc..5fb63c9 100644 (file)
@@ -874,15 +874,14 @@ VOID ETW::GCLog::ForceGC(LONGLONG l64ClientSequenceNumber)
 //---------------------------------------------------------------------------------------
 //
 // Helper to fire the GCStart event.  Figures out which version of GCStart to fire, and
-// includes the client sequence number, if available.  Also logs the generation range
-// events.
+// includes the client sequence number, if available.
 //
 // Arguments:
 //      pGcInfo - ETW_GC_INFO containing details from GC about this collection
 //
 
 // static
-VOID ETW::GCLog::FireGcStartAndGenerationRanges(ETW_GC_INFO * pGcInfo)
+VOID ETW::GCLog::FireGcStart(ETW_GC_INFO * pGcInfo)
 {
     LIMITED_METHOD_CONTRACT;
 
@@ -902,81 +901,8 @@ VOID ETW::GCLog::FireGcStartAndGenerationRanges(ETW_GC_INFO * pGcInfo)
         }
 
         FireEtwGCStart_V2(pGcInfo->GCStart.Count, pGcInfo->GCStart.Depth, pGcInfo->GCStart.Reason, pGcInfo->GCStart.Type, GetClrInstanceId(), l64ClientSequenceNumberToLog);
-
-        // Fire an event per range per generation
-        IGCHeap *hp = GCHeapUtilities::GetGCHeap();
-        hp->DiagDescrGenerations(FireSingleGenerationRangeEvent, NULL /* context */);
-    }
-}
-
-
-//---------------------------------------------------------------------------------------
-//
-// Helper to fire the GCEnd event and the generation range events.
-// 
-// Arguments:
-//      Count - (matching Count from corresponding GCStart event0
-//      Depth - (matching Depth from corresponding GCStart event0
-//
-//
-
-// static
-VOID ETW::GCLog::FireGcEndAndGenerationRanges(ULONG Count, ULONG Depth)
-{
-    LIMITED_METHOD_CONTRACT;
-
-    if (ETW_TRACING_CATEGORY_ENABLED(
-        MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, 
-        TRACE_LEVEL_INFORMATION, 
-        CLR_GC_KEYWORD))
-    {
-        // Fire an event per range per generation
-        IGCHeap *hp = GCHeapUtilities::GetGCHeap();
-        hp->DiagDescrGenerations(FireSingleGenerationRangeEvent, NULL /* context */);
-
-        // GCEnd
-        FireEtwGCEnd_V1(Count, Depth, GetClrInstanceId());
     }
 }
-//---------------------------------------------------------------------------------------
-//
-// Callback made by GC when we call GCHeapUtilities::DiagDescrGenerations().  This is
-// called once per range per generation, and results in a single ETW event per range per
-// generation.
-//
-// Arguments:
-//      context - unused
-//      generation - Generation number
-//      rangeStart - Where does this range start?
-//      rangeEnd - How large is the used portion of this range?
-//      rangeEndReserved - How large is the reserved portion of this range?
-//
-
-// static
-VOID ETW::GCLog::FireSingleGenerationRangeEvent(
-    void * /* context */,
-    int generation, 
-    BYTE * rangeStart, 
-    BYTE * rangeEnd,
-    BYTE * rangeEndReserved)
-{
-    CONTRACT_VOID
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-        MODE_ANY; // can be called even on GC threads        
-        PRECONDITION(0 <= generation && generation <= 3);
-        PRECONDITION(CheckPointer(rangeStart));
-        PRECONDITION(CheckPointer(rangeEnd));
-        PRECONDITION(CheckPointer(rangeEndReserved));
-    } 
-    CONTRACT_END;
-
-    FireEtwGCGenerationRange((BYTE) generation, rangeStart, rangeEnd - rangeStart, rangeEndReserved - rangeStart, GetClrInstanceId());
-
-    RETURN;
-}
 
 //---------------------------------------------------------------------------------------
 //
index 3842bab..50bd263 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "common.h"
 #include "gctoclreventsink.h"
+#include "eventtrace.h"
 
 GCToCLREventSink g_gcToClrEventSink;
 
@@ -22,6 +23,188 @@ void GCToCLREventSink::FireDynamicEvent(const char* eventName, void* payload, ui
     FireEtwGCDynamicEvent(wideEventName, payloadSize, (const BYTE*)payload, GetClrInstanceId());
 }
 
+void GCToCLREventSink::FireGCStart_V2(uint32_t count, uint32_t depth, uint32_t reason, uint32_t type)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    ETW::GCLog::ETW_GC_INFO gcStartInfo;
+    gcStartInfo.GCStart.Count = count;
+    gcStartInfo.GCStart.Depth = depth;
+    gcStartInfo.GCStart.Reason = static_cast<ETW::GCLog::ETW_GC_INFO::GC_REASON>(reason);
+    gcStartInfo.GCStart.Type = static_cast<ETW::GCLog::ETW_GC_INFO::GC_TYPE>(type);
+    ETW::GCLog::FireGcStart(&gcStartInfo);
+}
+
+void GCToCLREventSink::FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCGenerationRange(generation, rangeStart, rangeUsedLength, rangeReservedLength, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCEnd_V1(uint32_t count, uint32_t depth)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCEnd_V1(count, depth, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCHeapStats_V1(
+        uint64_t generationSize0,
+        uint64_t totalPromotedSize0,
+        uint64_t generationSize1,
+        uint64_t totalPromotedSize1,
+        uint64_t generationSize2,
+        uint64_t totalPromotedSize2,
+        uint64_t generationSize3,
+        uint64_t totalPromotedSize3,
+        uint64_t finalizationPromotedSize,
+        uint64_t finalizationPromotedCount,
+        uint32_t pinnedObjectCount,
+        uint32_t sinkBlockCount,
+        uint32_t gcHandleCount)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCHeapStats_V1(generationSize0, totalPromotedSize0, generationSize1, totalPromotedSize1,
+                          generationSize2, totalPromotedSize2, generationSize3, totalPromotedSize3,
+                          finalizationPromotedSize, finalizationPromotedCount, pinnedObjectCount,
+                          sinkBlockCount, gcHandleCount, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCCreateSegment_V1(void* address, size_t size, uint32_t type)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCCreateSegment_V1((uint64_t)address, static_cast<uint64_t>(size), type, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCFreeSegment_V1(void* address)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCFreeSegment_V1((uint64_t)address, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCCreateConcurrentThread_V1()
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCCreateConcurrentThread_V1(GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCTerminateConcurrentThread_V1()
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCTerminateConcurrentThread_V1(GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCTriggered(uint32_t reason)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCTriggered(reason, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCMarkWithType(uint32_t heapNum, uint32_t type, uint64_t bytes)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCMarkWithType(heapNum, GetClrInstanceId(), type, bytes);
+}
+
+void GCToCLREventSink::FireGCJoin_V2(uint32_t heap, uint32_t joinTime, uint32_t joinType, uint32_t joinId)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCJoin_V2(heap, joinTime, joinType, GetClrInstanceId(), joinId);
+}
+
+void GCToCLREventSink::FireGCGlobalHeapHistory_V2(uint64_t finalYoungestDesired,
+        int32_t numHeaps,
+        uint32_t condemnedGeneration,
+        uint32_t gen0reductionCount,
+        uint32_t reason,
+        uint32_t globalMechanisms,
+        uint32_t pauseMode,
+        uint32_t memoryPressure)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCGlobalHeapHistory_V2(finalYoungestDesired, numHeaps, condemnedGeneration, gen0reductionCount, reason,
+        globalMechanisms, GetClrInstanceId(), pauseMode, memoryPressure);
+}
+
+void GCToCLREventSink::FireGCAllocationTick_V1(uint32_t allocationAmount, uint32_t allocationKind)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    FireEtwGCAllocationTick_V1(allocationAmount, allocationKind, GetClrInstanceId());
+}
+
+void GCToCLREventSink::FireGCAllocationTick_V3(uint64_t allocationAmount, uint32_t allocationKind, uint32_t heapIndex, void* objectAddress)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    void * typeId = nullptr;
+    const WCHAR * name = nullptr;
+    InlineSString<MAX_CLASSNAME_LENGTH> strTypeName;
+    EX_TRY
+    {
+        TypeHandle th = GetThread()->GetTHAllocContextObj();
+
+        if (th != 0)
+        {
+            th.GetName(strTypeName);
+            name = strTypeName.GetUnicode();
+            typeId = th.GetMethodTable();
+        }
+    }
+    EX_CATCH {}
+    EX_END_CATCH(SwallowAllExceptions)
+
+    if (typeId != nullptr)
+    {
+        FireEtwGCAllocationTick_V3(static_cast<uint32_t>(allocationAmount),
+            allocationKind,
+            GetClrInstanceId(),
+            allocationAmount,
+            typeId,
+            name,
+            heapIndex,
+            objectAddress);
+    }
+}
+
+void GCToCLREventSink::FirePinObjectAtGCTime(void* object, uint8_t** ppObject)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    Object* obj = (Object*)object;
+
+    InlineSString<MAX_CLASSNAME_LENGTH> strTypeName; 
+
+    EX_TRY
+    {
+        FAULT_NOT_FATAL();
+
+        TypeHandle th = obj->GetGCSafeTypeHandleIfPossible();
+        if(th != NULL)
+        {
+            th.GetName(strTypeName);
+        }
+
+        FireEtwPinObjectAtGCTime(ppObject,
+                             object,
+                             obj->GetSize(),
+                             strTypeName.GetUnicode(),
+                             GetClrInstanceId());
+    }
+    EX_CATCH {}
+    EX_END_CATCH(SwallowAllExceptions)
+}
+
 void GCToCLREventSink::FireGCPerHeapHistory_V3(void *freeListAllocated,
                                                void *freeListRejected,
                                                void *endOfSegAllocated,
index ca3a219..e34cac4 100644 (file)
@@ -11,7 +11,40 @@ class GCToCLREventSink : public IGCToCLREventSink
 {
 public:
     void FireDynamicEvent(const char* eventName, void* payload, uint32_t payloadSize);
-
+    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,
+                            uint64_t totalPromotedSize0,
+                            uint64_t generationSize1,
+                            uint64_t totalPromotedSize1,
+                            uint64_t generationSize2,
+                            uint64_t totalPromotedSize2,
+                            uint64_t generationSize3,
+                            uint64_t totalPromotedSize3,
+                            uint64_t finalizationPromotedSize,
+                            uint64_t finalizationPromotedCount,
+                            uint32_t pinnedObjectCount,
+                            uint32_t sinkBlockCount,
+                            uint32_t gcHandleCount);
+    void FireGCCreateSegment_V1(void* address, size_t size, uint32_t type);
+    void FireGCFreeSegment_V1(void* address);
+    void FireGCCreateConcurrentThread_V1();
+    void FireGCTerminateConcurrentThread_V1();
+    void FireGCTriggered(uint32_t reason);
+    void FireGCMarkWithType(uint32_t heapNum, uint32_t type, uint64_t bytes);
+    void FireGCJoin_V2(uint32_t heap, uint32_t joinTime, uint32_t joinType, uint32_t joinId);
+    void FireGCGlobalHeapHistory_V2(uint64_t finalYoungestDesired,
+                                    int32_t numHeaps,
+                                    uint32_t condemnedGeneration,
+                                    uint32_t gen0reductionCount,
+                                    uint32_t reason,
+                                    uint32_t globalMechanisms,
+                                    uint32_t pauseMode,
+                                    uint32_t memoryPressure);
+    void FireGCAllocationTick_V1(uint32_t allocationAmount, uint32_t allocationKind);
+    void FireGCAllocationTick_V3(uint64_t allocationAmount, uint32_t allocationKind, uint32_t heapIndex, void* objectAddress);
+    void FirePinObjectAtGCTime(void* object, uint8_t** ppObject);
     void FireGCPerHeapHistory_V3(void *freeListAllocated,
                                  void *freeListRejected,
                                  void *endOfSegAllocated,