Optimize eeheap presentation for regions (#3462)
authorAndrew Au <andrewau@microsoft.com>
Mon, 24 Oct 2022 21:41:52 +0000 (14:41 -0700)
committerGitHub <noreply@github.com>
Mon, 24 Oct 2022 21:41:52 +0000 (14:41 -0700)
src/SOS/SOS.UnitTests/Scripts/GCPOH.script
src/SOS/SOS.UnitTests/Scripts/GCTests.script
src/SOS/Strike/eeheap.cpp

index fb0e5138c1483107e7ed7e344a0ba96bf61ae4b4..3d6855a155c96d6115b8882ddc509e4a4e3f4f34 100644 (file)
@@ -61,13 +61,10 @@ VERIFY:\s+Jit code heap:\s+
 VERIFY:\s+LoaderCodeHeap:\s+<HEXVAL>.*bytes\.\s+
 VERIFY:\s+Total LoaderHeap size:\s+Size:\s+0x<HEXVAL>\s+\(<DECVAL>|lu\)\s+bytes\.\s+
 VERIFY:\s+Number of GC Heaps:\s+<DECVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
 VERIFY:\s+segment\s+begin\s+allocated\s+committed\s+allocated\s+size\s+committed\s+size\s+
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+<HEXVAL>\s+<HEXVAL>\s+0x<HEXVAL>\(<DECVAL>\)\s+0x<HEXVAL>\(<DECVAL>\)\s+
-VERIFY:\s+Large object heap starts at 0x<HEXVAL>\s+
-VERIFY:\s+Pinned object heap starts at 0x<HEXVAL>\s+
+VERIFY:\s+Large object heap.*
+VERIFY:\s+Pinned object heap.*
 
 # Continue to the next DebugBreak
 CONTINUE
index 69e71fb60009c8b1e1a2001ceb55a4854e49a34f..72a2d5c9bd521fac7981519cf35c17dd291f93cb 100644 (file)
@@ -97,12 +97,9 @@ VERIFY:\s+Jit code heap:\s+
 VERIFY:\s+LoaderCodeHeap:\s+<HEXVAL>.*bytes\.\s+
 VERIFY:\s+Total LoaderHeap size:\s+Size:\s+0x<HEXVAL>\s+\(<DECVAL>|lu\)\s+bytes\.\s+
 VERIFY:\s+Number of GC Heaps:\s+<DECVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
-VERIFY:\s+generation\s+<DECVAL>\s+starts\s+at\s+0x<HEXVAL>\s+
 VERIFY:\s+segment\s+begin\s+allocated\s+committed\s+allocated\s+size\s+committed\s+size\s+
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+<HEXVAL>\s+<HEXVAL>\s+0x<HEXVAL>\(<DECVAL>\)\s+0x<HEXVAL>\(<DECVAL>\)\s+
-VERIFY:\s+Large object heap starts at 0x<HEXVAL>\s+
+VERIFY:\s+Large object heap.*
 
 # Continue to the next DebugBreak
 CONTINUE
index 2eb5d993195f977bdf73f16de4783e731ccd1ae1..2a31011cbf8651d72fb6b09db8b07759e39a59b5 100644 (file)
@@ -484,13 +484,27 @@ void GCPrintSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_si
 {
     DWORD_PTR dwAddrSeg;
     DacpHeapSegmentData segment;
+    const size_t heap_segment_flags_readonly = 1;
+    UINT max_generation = GetMaxGeneration();
 
     if (heap.has_regions)
     {
-        for (UINT n = 0; n <= GetMaxGeneration(); n++)
+        const size_t regions_committed_adjustment = 0x20;
+
+        for (UINT n = 0; n <= max_generation + 1; n++)
         {
-            ExtOut("generation %d:\n", n);
-            dwAddrSeg = (DWORD_PTR)heap.generation_table[n].start_segment;
+            bool showing_frozen = (n == max_generation + 1);
+            if (showing_frozen)
+            {
+                ExtOut("Frozen object heap\n");
+                ExtOut("%" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s\n", "segment", "begin", "allocated", "committed", "allocated size", "committed size");
+                dwAddrSeg = (DWORD_PTR)heap.generation_table[max_generation].start_segment;
+            }
+            else
+            {
+                ExtOut("generation %d:\n", n);
+                dwAddrSeg = (DWORD_PTR)heap.generation_table[n].start_segment;
+            }
             while (dwAddrSeg != 0)
             {
                 if (IsInterrupt())
@@ -500,71 +514,90 @@ void GCPrintSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_si
                     ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
                     return;
                 }
+                
+                CLRDATA_ADDRESS allocated = segment.highAllocMark - segment.mem;
+                CLRDATA_ADDRESS committed = segment.committed - segment.mem + regions_committed_adjustment;
+                bool frozen = segment.flags & heap_segment_flags_readonly;
+                
+                if (frozen != showing_frozen)
+                {
+                    dwAddrSeg = (DWORD_PTR)segment.next;
+                    continue;
+                }
                 ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
                     SOS_PTR(dwAddrSeg),
                     SOS_PTR(segment.mem), SOS_PTR(segment.highAllocMark), SOS_PTR(segment.committed),
-                    (ULONG_PTR)(segment.highAllocMark - segment.mem),
-                    (ULONG_PTR)(segment.highAllocMark - segment.mem),
-                    (ULONG_PTR)(segment.committed - segment.mem),
-                    (ULONG_PTR)(segment.committed - segment.mem));
-                total_allocated_size += (DWORD_PTR)(segment.highAllocMark - segment.mem);
-                total_committed_size += (DWORD_PTR)(segment.committed - segment.mem);
+                    (ULONG_PTR)allocated,
+                    (ULONG_PTR)allocated,
+                    (ULONG_PTR)committed,
+                    (ULONG_PTR)committed);
+                total_allocated_size += (DWORD_PTR)allocated;
+                total_committed_size += (DWORD_PTR)committed;
                 dwAddrSeg = (DWORD_PTR)segment.next;
             }
         }
     }
     else
     {
-        dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration()].start_segment;
-        total_allocated_size = 0;
-        total_committed_size = 0;
-
-        while (dwAddrSeg != (DWORD_PTR)heap.generation_table[0].start_segment)
+        for (UINT n = 0; n < 2; n++)
         {
-            if (IsInterrupt())
-                return;
-            if (segment.Request(g_sos, dwAddrSeg, heap.original_heap_details) != S_OK)
+            dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration()].start_segment;
+            bool showing_frozen = (n == 1);
+            if (showing_frozen)
             {
-                ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
-                return;
+                ExtOut("Frozen object heap\n");
+                ExtOut("%" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s\n", "segment", "begin", "allocated", "committed", "allocated size", "committed size");
             }
-            ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
-                    SOS_PTR(dwAddrSeg),
-                    SOS_PTR(segment.mem), SOS_PTR(segment.allocated), SOS_PTR(segment.committed),
-                    (ULONG_PTR)(segment.allocated - segment.mem),
-                    (ULONG_PTR)(segment.allocated - segment.mem),
-                    (ULONG_PTR)(segment.committed - segment.mem),
-                    (ULONG_PTR)(segment.committed - segment.mem));
-            total_allocated_size += (DWORD_PTR) (segment.allocated - segment.mem);
-            total_committed_size += (DWORD_PTR) (segment.committed - segment.mem);
-            dwAddrSeg = (DWORD_PTR)segment.next;
-        }
+            while (true)
+            {
+                if (IsInterrupt())
+                    return;
 
-        if (segment.Request(g_sos, dwAddrSeg, heap.original_heap_details) != S_OK)
-        {
-            ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
-            return;
-        }
+                if (segment.Request(g_sos, dwAddrSeg, heap.original_heap_details) != S_OK)
+                {
+                    ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
+                    return;
+                }
 
-        DWORD_PTR end = (DWORD_PTR)heap.alloc_allocated;
-        ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
-                SOS_PTR(dwAddrSeg),
-                SOS_PTR(segment.mem), SOS_PTR(end), SOS_PTR(segment.committed),
-                (ULONG_PTR)(end - (DWORD_PTR)segment.mem),
-                (ULONG_PTR)(end - (DWORD_PTR)segment.mem),
-                (ULONG_PTR)(segment.committed - (DWORD_PTR)segment.mem),
-                (ULONG_PTR)(segment.committed - (DWORD_PTR)segment.mem));
+                CLRDATA_ADDRESS allocated = segment.highAllocMark - segment.mem;
+                CLRDATA_ADDRESS committed = segment.committed - segment.mem;
+                bool frozen = segment.flags & heap_segment_flags_readonly;
+
+                if (frozen != showing_frozen)
+                {
+                    if (dwAddrSeg == (DWORD_PTR)heap.generation_table[0].start_segment)
+                    {
+                        break;
+                    }
+                    dwAddrSeg = (DWORD_PTR)segment.next;
+                    continue;
+                }
 
-        total_allocated_size += end - (DWORD_PTR)segment.mem;
-        total_committed_size += (DWORD_PTR)(segment.committed - segment.mem);
+                ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
+                        SOS_PTR(dwAddrSeg),
+                        SOS_PTR(segment.mem), SOS_PTR(segment.allocated), SOS_PTR(segment.committed),
+                        (ULONG_PTR)allocated,
+                        (ULONG_PTR)allocated,
+                        (ULONG_PTR)committed,
+                        (ULONG_PTR)committed);
+                total_allocated_size += (DWORD_PTR)allocated;
+                total_committed_size += (DWORD_PTR)committed;
+                if (dwAddrSeg == (DWORD_PTR)heap.generation_table[0].start_segment)
+                {
+                    break;
+                }
+                dwAddrSeg = (DWORD_PTR)segment.next;
+            }
+        }
     }
 }
 
-void GCPrintLargeHeapSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_size, DWORD_PTR &total_committed_size)
+void GCPrintUohHeapSegmentInfo(const GCHeapDetails &heap, UINT generation, DWORD_PTR &total_allocated_size, DWORD_PTR &total_committed_size)
 {
     DWORD_PTR dwAddrSeg;
     DacpHeapSegmentData segment;
-    dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration()+1].start_segment;
+    dwAddrSeg = (DWORD_PTR)heap.generation_table[generation].start_segment;
+    const size_t regions_committed_adjustment = 0x20;
 
     // total_size = 0;
     while (dwAddrSeg != NULL)
@@ -576,67 +609,60 @@ void GCPrintLargeHeapSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_all
             ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
             return;
         }
-        ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
-                SOS_PTR(dwAddrSeg),
-                SOS_PTR(segment.mem),
-                SOS_PTR(segment.allocated),
-                SOS_PTR(segment.committed),
-                (ULONG_PTR)(segment.allocated - segment.mem),
-                (ULONG_PTR)(segment.allocated - segment.mem),
-                (ULONG_PTR)(segment.committed - segment.mem),
-                (ULONG_PTR)(segment.committed - segment.mem));
-        total_allocated_size += (DWORD_PTR) (segment.allocated - segment.mem);
-        total_committed_size += (DWORD_PTR) (segment.committed - segment.mem);
-        dwAddrSeg = (DWORD_PTR)segment.next;
-    }
-}
-
-void GCPrintPinnedHeapSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_size, DWORD_PTR& total_committed_size)
-{
-    DWORD_PTR dwAddrSeg;
-    DacpHeapSegmentData segment;
-    dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration() + 2].start_segment;
-
-    while (dwAddrSeg != NULL)
-    {
-        if (IsInterrupt())
-            return;
-        if (segment.Request(g_sos, dwAddrSeg, heap.original_heap_details) != S_OK)
+        CLRDATA_ADDRESS allocated = segment.allocated - segment.mem;
+        CLRDATA_ADDRESS committed = segment.committed - segment.mem;
+        if (heap.has_regions)
         {
-            ExtOut("Error requesting heap segment %p\n", SOS_PTR(dwAddrSeg));
-            return;
+            committed += regions_committed_adjustment;
         }
         ExtOut("%p  %p  %p  %p  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE"d)  0x%" POINTERSIZE_TYPE "x(%" POINTERSIZE_TYPE "d)\n",
                 SOS_PTR(dwAddrSeg),
                 SOS_PTR(segment.mem),
                 SOS_PTR(segment.allocated),
                 SOS_PTR(segment.committed),
-                (ULONG_PTR)(segment.allocated - segment.mem),
-                (ULONG_PTR)(segment.allocated - segment.mem),
-                (ULONG_PTR)(segment.committed - segment.mem),
-                (ULONG_PTR)(segment.committed - segment.mem));
-        total_allocated_size += (DWORD_PTR) (segment.allocated - segment.mem);
-        total_committed_size += (DWORD_PTR) (segment.committed - segment.mem);
+                (ULONG_PTR)allocated,
+                (ULONG_PTR)allocated,
+                (ULONG_PTR)committed,
+                (ULONG_PTR)committed);
+        total_allocated_size += (DWORD_PTR)allocated;
+        total_committed_size += (DWORD_PTR)committed;
         dwAddrSeg = (DWORD_PTR)segment.next;
     }
 }
 
 void GCHeapInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_size, DWORD_PTR &total_committed_size)
 {
-    GCPrintGenerationInfo(heap);
+    if (!heap.has_regions)
+    {
+        GCPrintGenerationInfo(heap);
+    }
+    ExtOut("Small object heap\n");
     ExtOut("%" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s\n", "segment", "begin", "allocated", "committed", "allocated size", "committed size");
     GCPrintSegmentInfo(heap, total_allocated_size, total_committed_size);
 
-    ExtOut("Large object heap starts at 0x%p\n",
-                  SOS_PTR(heap.generation_table[GetMaxGeneration() + 1].allocation_start));
+    if (heap.has_regions)
+    {
+        ExtOut("Large object heap\n");
+    }
+    else
+    {
+        ExtOut("Large object heap starts at 0x%p\n", SOS_PTR(heap.generation_table[GetMaxGeneration() + 1].allocation_start));
+    }
     ExtOut("%" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s\n", "segment", "begin", "allocated", "committed", "allocated size", "committed size");
-    GCPrintLargeHeapSegmentInfo(heap, total_allocated_size, total_committed_size);
+    GCPrintUohHeapSegmentInfo(heap, GetMaxGeneration() + 1, total_allocated_size, total_committed_size);
 
     if (heap.has_poh)
     {
-        ExtOut("Pinned object heap starts at 0x%p\n",
-                      SOS_PTR(heap.generation_table[GetMaxGeneration() + 2].allocation_start));
-        GCPrintPinnedHeapSegmentInfo(heap, total_allocated_size, total_committed_size);
+        if (heap.has_regions)
+        {
+            ExtOut("Pinned object heap\n");
+        }
+        else
+        {
+            ExtOut("Pinned object heap starts at 0x%p\n", SOS_PTR(heap.generation_table[GetMaxGeneration() + 2].allocation_start));
+        }
+        ExtOut("%" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s  %" POINTERSIZE "s\n", "segment", "begin", "allocated", "committed", "allocated size", "committed size");
+        GCPrintUohHeapSegmentInfo(heap, GetMaxGeneration() + 2, total_allocated_size, total_committed_size);
     }
 }