Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3780,24 +3780,24 @@ ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
Dereference(g_gcDacGlobals->finalize_queue).EnumMem();

// Enumerate the entire generation table, which has variable size
size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 2);
DacEnumMemoryRegion(dac_cast<TADDR>(g_gcDacGlobals->generation_table), gen_table_size);
EnumGenerationTable(dac_cast<TADDR>(g_gcDacGlobals->generation_table));

if (g_gcDacGlobals->generation_table.IsValid())
{
// enumerating the generations from max (which is normally gen2) to max+1 gives you
// the segment list for all the normal segements plus the large heap segment (max+1)
// this is the convention in the GC so it is repeated here
for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++)
ULONG first = IsRegion() ? 0 : (*g_gcDacGlobals->max_gen);
// enumerating the first to max + 2 gives you
// the segment list for all the normal segments plus the pinned heap segment (max + 2)
// this is the convention in the GC so it is repeated here
for (ULONG i = first; i <= *g_gcDacGlobals->max_gen + 2; i++)
{
dac_generation gen = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
__DPtr<dac_heap_segment> seg = dac_cast<TADDR>(gen.start_segment);
while (seg)
{
dac_generation gen = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
__DPtr<dac_heap_segment> seg = dac_cast<TADDR>(gen.start_segment);
while (seg)
{
DacEnumMemoryRegion(dac_cast<TADDR>(seg), sizeof(dac_heap_segment));
seg = seg->next;
}
DacEnumMemoryRegion(dac_cast<TADDR>(seg), sizeof(dac_heap_segment));
seg = seg->next;
}
}
}
}

Expand Down
79 changes: 75 additions & 4 deletions src/coreclr/debug/daccess/request_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ HeapTableIndex(DPTR(unused_gc_heap**) heaps, size_t index)
result.field_name = field_name; \
}

// if (field_offset != -1)
// p_field.EnumMem();
#define ENUM(field_name, field_type) \
LOAD_BASE(field_name, field_type) \
if (field_name##_offset != -1) \
{ \
p_##field_name.EnumMem(); \
}

// if (field_offset != -1)
// result.field = DPTR(field_type)field_name
#define LOAD_DPTR(field_name, field_type) \
Expand All @@ -87,6 +96,13 @@ HeapTableIndex(DPTR(unused_gc_heap**) heaps, size_t index)
} \
}

#define ENUM_ARRAY(field_name, field_type, array_length) \
LOAD_BASE(field_name, field_type) \
if (field_name##_offset != -1) \
{ \
DacEnumMemoryRegion(p_##field_name.GetAddr(), sizeof(field_type) * array_length); \
}

inline bool IsRegion()
{
return (g_gcDacGlobals->minor_version_number & 1) != 0;
Expand Down Expand Up @@ -121,6 +137,26 @@ LoadGcHeapData(TADDR heap)
return result;
}

inline void EnumGcHeap(TADDR heap)
{
DPTR(int) field_offsets = g_gcDacGlobals->gc_heap_field_offsets;
int field_index = 0;

#define BASE heap
#define ALL_FIELDS
#define DEFINE_FIELD(field_name, field_type) ENUM(field_name, field_type)
#define DEFINE_DPTR_FIELD(field_name, field_type) ENUM(field_name, field_type)
#define DEFINE_ARRAY_FIELD(field_name, field_type, array_length) ENUM_ARRAY(field_name, field_type, array_length)

#include "../../gc/dac_gcheap_fields.h"

#undef DEFINE_ARRAY_FIELD
#undef DEFINE_DPTR_FIELD
#undef DEFINE_FIELD
#undef ALL_FIELDS
#undef BASE
}

// Load an instance of dac_generation for the generation pointed by generation.
// Fields that does not exist in the current generation instance is zero initialized.
// Return the dac_generation object.
Expand Down Expand Up @@ -148,27 +184,62 @@ LoadGeneration(TADDR generation)
return result;
}

inline void EnumGeneration(TADDR generation)
{
DPTR(int) field_offsets = g_gcDacGlobals->generation_field_offsets;
int field_index = 0;

#define BASE generation
#define ALL_FIELDS
#define DEFINE_FIELD(field_name, field_type) ENUM(field_name, field_type)
#define DEFINE_DPTR_FIELD(field_name, field_type) ENUM(field_name, field_type)
#define DEFINE_ARRAY_FIELD(field_name, field_type, array_length) ENUM_ARRAY(field_name, field_type, array_length)

#include "../../gc/dac_generation_fields.h"

#undef DEFINE_ARRAY_FIELD
#undef DEFINE_DPTR_FIELD
#undef DEFINE_FIELD
#undef ALL_FIELDS
#undef BASE
}

// Indexes into a given generation table, returning a dac_generation
inline dac_generation
GenerationTableIndex(DPTR(unused_generation) base, size_t index)
{
return LoadGeneration(TableIndex(base, index, g_gcDacGlobals->generation_size).GetAddr());
}

// Indexes into a heap's generation table, given the heap instance
// and the desired index. Returns a dac_generation
inline dac_generation
ServerGenerationTableIndex(TADDR heap, size_t index)
inline TADDR ServerGenerationTableAddress(TADDR heap)
{
DPTR(int) field_offsets = g_gcDacGlobals->gc_heap_field_offsets;
int field_index = GENERATION_TABLE_FIELD_INDEX;
#define BASE heap
LOAD_BASE (generation_table, unused_generation);
#undef BASE
assert (generation_table_offset != -1);
return p_generation_table.GetAddr();
}

// Indexes into a heap's generation table, given the heap instance
// and the desired index. Returns a dac_generation
inline dac_generation
ServerGenerationTableIndex(TADDR heap, size_t index)
{
DPTR(unused_generation) p_generation_table = ServerGenerationTableAddress(heap);
return LoadGeneration(TableIndex(p_generation_table, index, g_gcDacGlobals->generation_size).GetAddr());
}

inline void EnumGenerationTable(TADDR generation_table)
{
DPTR(unused_generation) p_generation_table = generation_table;
for (unsigned int i = 0; i < *g_gcDacGlobals->max_gen + 2; i++)
{
EnumGeneration(TableIndex(p_generation_table, i, g_gcDacGlobals->generation_size).GetAddr());
}
}

#undef LOAD_ARRAY
#undef LOAD_DPTR
#undef LOAD
Expand Down
18 changes: 8 additions & 10 deletions src/coreclr/debug/daccess/request_svr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,21 +252,19 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)

for (int i = 0; i < heaps; i++)
{
TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
dac_gc_heap heap = LoadGcHeapData(heapAddress);
dac_gc_heap* pHeap = &heap;

size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 2);
DacEnumMemoryRegion(dac_cast<TADDR>(pHeap), sizeof(dac_gc_heap));
EnumGcHeap(heapAddress);
TADDR generationTable = ServerGenerationTableAddress(heapAddress);
EnumGenerationTable(generationTable);
DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(dac_finalize_queue));

TADDR taddrTable = dac_cast<TADDR>(pHeap) + offsetof(dac_gc_heap, generation_table);
DacEnumMemoryRegion(taddrTable, gen_table_size);

// enumerating the generations from max (which is normally gen2) to max+1 gives you
// the segment list for all the normal segements plus the large heap segment (max+1)
ULONG first = IsRegion() ? 0 : (*g_gcDacGlobals->max_gen);
// enumerating the first to max + 2 gives you
// the segment list for all the normal segments plus the pinned heap segment (max + 2)
// this is the convention in the GC so it is repeated here
for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++)
for (ULONG i = first; i <= *g_gcDacGlobals->max_gen + 2; i++)
{
dac_generation generation = ServerGenerationTableIndex(heapAddress, i);
DPTR(dac_heap_segment) seg = generation.start_segment;
Expand Down