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;
}
+ }
}
}
}
// 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) \
LOAD_BASE(field_name, field_type*) \
} \
}
+#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;
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.
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;
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
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;