Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure ServerGCHeapDetails is up to date #56056

Merged
merged 4 commits into from
Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2807,7 +2807,7 @@ ClrDataAccess::GetGCHeapStaticData(struct DacpGcHeapDetails *detailsData)
detailsData->background_saved_highest_address = (CLRDATA_ADDRESS)*g_gcDacGlobals->background_saved_highest_address;

// get bounds for the different generations
for (unsigned int i=0; i < *g_gcDacGlobals->max_gen + 2; i++)
for (unsigned int i=0; i < DAC_NUMBERGENERATIONS; i++)
{
DPTR(dac_generation) generation = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS) dac_cast<TADDR>(generation->start_segment);
Expand All @@ -2821,7 +2821,7 @@ ClrDataAccess::GetGCHeapStaticData(struct DacpGcHeapDetails *detailsData)
{
DPTR(dac_finalize_queue) fq = Dereference(g_gcDacGlobals->finalize_queue);
DPTR(uint8_t*) fillPointersTable = dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
for (unsigned int i = 0; i<(*g_gcDacGlobals->max_gen + 2 + dac_finalize_queue::ExtraSegCount); i++)
for (unsigned int i = 0; i < DAC_NUMBERGENERATIONS + 3; i++)
noahfalk marked this conversation as resolved.
Show resolved Hide resolved
{
detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*));
}
Expand Down
57 changes: 27 additions & 30 deletions src/coreclr/debug/daccess/request_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ DPTR(T) Dereference(DPTR(T*) ptr)
// Indexes into the global heap table, returning a TADDR to the requested
// heap instance.
inline TADDR
HeapTableIndex(DPTR(dac_gc_heap**) heaps, size_t index)
HeapTableIndex(DPTR(opaque_gc_heap**) heaps, size_t index)
{
DPTR(dac_gc_heap*) heap_table = Dereference(heaps);
DPTR(dac_gc_heap*) ptr = TableIndex(heap_table, index, sizeof(dac_gc_heap*));
DPTR(opaque_gc_heap*) heap_table = Dereference(heaps);
DPTR(opaque_gc_heap*) ptr = TableIndex(heap_table, index, sizeof(void*));
return Dereference(ptr).GetAddr();
}

Expand All @@ -53,15 +53,17 @@ GenerationTableIndex(DPTR(dac_generation) base, size_t index)
// field_offset = g_gcDacGlobals->gc_heap_field_offsets
// p_field_offset = field_offset[field_index]
// p_field = heap + p_field_offset
#define LOAD_BASE(field_name, field_index, field_type) \
// field_index++
#define LOAD_BASE(field_name, field_type) \
DPTR(int) p_##field_name##_offset = TableIndex(field_offsets, field_index, sizeof(int)); \
int field_name##_offset = *p_##field_name##_offset; \
DPTR(field_type) p_##field_name = heap + field_name##_offset;
DPTR(field_type) p_##field_name = heap + field_name##_offset; \
field_index++;

// if (field_offset != -1)
// result.field = *p_field
#define LOAD(field_name, field_index, field_type) \
LOAD_BASE(field_name, field_index, field_type) \
#define LOAD(field_name, field_type) \
LOAD_BASE(field_name, field_type) \
if (field_name##_offset != -1) \
{ \
field_type field_name = *p_##field_name; \
Expand All @@ -70,8 +72,8 @@ GenerationTableIndex(DPTR(dac_generation) base, size_t index)

// if (field_offset != -1)
// result.field = DPTR(field_type)field_name
#define LOAD_DPTR(field_name, field_index, field_type) \
LOAD_BASE(field_name, field_index, field_type*) \
#define LOAD_DPTR(field_name, field_type) \
LOAD_BASE(field_name, field_type*) \
if (field_name##_offset != -1) \
{ \
field_type* field_name = *p_##field_name; \
Expand All @@ -82,8 +84,8 @@ GenerationTableIndex(DPTR(dac_generation) base, size_t index)
// for i from 0 to array_length - 1
// result.field[i] = *p_field
// p_field = p_field + 1
#define LOAD_ARRAY(field_name, field_index, field_type, array_length) \
LOAD_BASE(field_name, field_index, field_type) \
#define LOAD_ARRAY(field_name, field_type, array_length) \
LOAD_BASE(field_name, field_type) \
if (field_name##_offset != -1) \
{ \
for (int i = 0; i < array_length; i++) \
Expand All @@ -99,7 +101,8 @@ inline DPTR(dac_generation)
ServerGenerationTableIndex(TADDR heap, size_t index)
{
DPTR(int) field_offsets = g_gcDacGlobals->gc_heap_field_offsets;
LOAD_BASE (generation_table, 18, dac_generation);
int field_index = GENERATION_TABLE_FIELD_INDEX;
LOAD_BASE (generation_table, dac_generation);
assert (generation_table_offset != -1);
return TableIndex(p_generation_table, index, g_gcDacGlobals->generation_size);
}
Expand All @@ -114,25 +117,19 @@ LoadGcHeapData(TADDR heap)
memset(&result, 0, sizeof(dac_gc_heap));

DPTR(int) field_offsets = g_gcDacGlobals->gc_heap_field_offsets;
int field_index = 0;

LOAD (alloc_allocated, 0, uint8_t*);
LOAD_DPTR (ephemeral_heap_segment, 1, dac_heap_segment);
LOAD_DPTR (finalize_queue, 2, dac_finalize_queue);
LOAD (oom_info, 3, oom_history);
LOAD_ARRAY(interesting_data_per_heap, 4, size_t, NUM_GC_DATA_POINTS);
LOAD_ARRAY(compact_reasons_per_heap, 5, size_t, MAX_COMPACT_REASONS_COUNT);
LOAD_ARRAY(expand_mechanisms_per_heap, 6, size_t, MAX_EXPAND_MECHANISMS_COUNT);
LOAD_ARRAY(interesting_mechanism_bits_per_heap,7, size_t, MAX_GC_MECHANISM_BITS_COUNT);
LOAD (internal_root_array, 8, uint8_t*);
LOAD (internal_root_array_index, 9, size_t);
LOAD (heap_analyze_success, 10, BOOL);
LOAD (card_table, 11, uint32_t*);
LOAD (mark_array, 12, uint32_t*);
LOAD (next_sweep_obj, 13, uint8_t*);
LOAD (background_saved_lowest_address, 14, uint8_t*);
LOAD (background_saved_highest_address, 15, uint8_t*);
LOAD_DPTR (saved_sweep_ephemeral_seg, 16, dac_heap_segment);
LOAD (saved_sweep_ephemeral_start, 17, uint8_t*);
#define ALL_FIELDS
#define DEFINE_FIELD(field_name, field_type) LOAD(field_name, field_type)
#define DEFINE_DPTR_FIELD(field_name, field_type) LOAD_DPTR(field_name, field_type)
#define DEFINE_ARRAY_FIELD(field_name, field_type, array_length) LOAD_ARRAY(field_name, field_type, array_length);

#include "../../gc/gc_typefields.h"

#undef DEFINE_ARRAY_FIELD
#undef DEFINE_DPTR_FIELD
#undef DEFINE_FIELD
#undef ALL_FIELDS

return result;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/debug/daccess/request_svr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapDetails *
detailsData->background_saved_highest_address = (CLRDATA_ADDRESS)pHeap->background_saved_highest_address;

// get bounds for the different generations
for (unsigned int i=0; i < *g_gcDacGlobals->max_gen + 2; i++)
for (unsigned int i=0; i < DAC_NUMBERGENERATIONS; i++)
{
DPTR(dac_generation) generation = ServerGenerationTableIndex(heapAddress, i);
detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(generation->start_segment);
Expand All @@ -161,7 +161,7 @@ ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapDetails *
if (fq.IsValid())
{
DPTR(uint8_t*) fillPointersTable = dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
for (unsigned int i = 0; i<(*g_gcDacGlobals->max_gen + 2 + dac_finalize_queue::ExtraSegCount); i++)
for (unsigned int i = 0; i < DAC_NUMBERGENERATIONS + 3; i++)
{
detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*));
}
Expand Down
54 changes: 18 additions & 36 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45571,41 +45571,23 @@ void PopulateDacVars(GcDacVars *gcDacVars)
#ifndef DACCESS_COMPILE

#ifdef MULTIPLE_HEAPS
static int gc_heap_field_offsets[] = {
offsetof(gc_heap, alloc_allocated), // 0
offsetof(gc_heap, ephemeral_heap_segment), // 1
offsetof(gc_heap, finalize_queue), // 2
offsetof(gc_heap, oom_info), // 3
offsetof(gc_heap, interesting_data_per_heap), // 4
offsetof(gc_heap, compact_reasons_per_heap), // 5
offsetof(gc_heap, expand_mechanisms_per_heap), // 6
offsetof(gc_heap, interesting_mechanism_bits_per_heap), // 7
offsetof(gc_heap, internal_root_array), // 8
offsetof(gc_heap, internal_root_array_index), // 9
offsetof(gc_heap, heap_analyze_success), // 10
offsetof(gc_heap, card_table), // 11
#ifdef BACKGROUND_GC
offsetof(gc_heap, mark_array), // 12
offsetof(gc_heap, next_sweep_obj), // 13
offsetof(gc_heap, background_saved_lowest_address), // 14
offsetof(gc_heap, background_saved_highest_address), // 15
#ifndef USE_REGIONS
offsetof(gc_heap, saved_sweep_ephemeral_seg), // 16
offsetof(gc_heap, saved_sweep_ephemeral_start), // 17
#else
-1, // 16
-1, // 17
#endif //!USE_REGIONS
#else
-1, // 12
-1, // 13
-1, // 14
-1, // 15
-1, // 16
-1, // 17
#endif //BACKGROUND_GC
offsetof(gc_heap, generation_table) // 18
};
static int gc_heap_field_offsets[] = {

#define DEFINE_FIELD(field_name, field_type) offsetof(gc_heap, field_name),
#define DEFINE_DPTR_FIELD(field_name, field_type) offsetof(gc_heap, field_name),
#define DEFINE_ARRAY_FIELD(field_name, field_type, array_length) offsetof(gc_heap, field_name),
#define DEFINE_MISSING_FIELD -1,

#include "gc_typefields.h"

#undef DEFINE_MISSING_FIELD
#undef DEFINE_ARRAY_FIELD
#undef DEFINE_DPTR_FIELD
#undef DEFINE_FIELD

offsetof(gc_heap, generation_table)
};
static_assert(sizeof(gc_heap_field_offsets) == (GENERATION_TABLE_FIELD_INDEX + 1) * sizeof(int), "GENERATION_TABLE_INDEX mismatch");
#endif //MULTIPLE_HEAPS

assert(gcDacVars != nullptr);
Expand Down Expand Up @@ -45653,7 +45635,7 @@ static int gc_heap_field_offsets[] = {
#endif // HEAP_ANALYZE
#else
gcDacVars->n_heaps = &gc_heap::n_heaps;
gcDacVars->g_heaps = reinterpret_cast<dac_gc_heap***>(&gc_heap::g_heaps);
gcDacVars->g_heaps = reinterpret_cast<opaque_gc_heap***>(&gc_heap::g_heaps);
gcDacVars->gc_heap_field_offsets = reinterpret_cast<int**>(&gc_heap_field_offsets);
#endif // MULTIPLE_HEAPS
#else
Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/gc/gc_typefields.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
DEFINE_FIELD (alloc_allocated, uint8_t*)
DEFINE_DPTR_FIELD (ephemeral_heap_segment, dac_heap_segment)
DEFINE_DPTR_FIELD (finalize_queue, dac_finalize_queue)
DEFINE_FIELD (oom_info, oom_history)
DEFINE_ARRAY_FIELD (interesting_data_per_heap, size_t, NUM_GC_DATA_POINTS)
DEFINE_ARRAY_FIELD (compact_reasons_per_heap, size_t, MAX_COMPACT_REASONS_COUNT)
DEFINE_ARRAY_FIELD (expand_mechanisms_per_heap, size_t, MAX_EXPAND_MECHANISMS_COUNT)
DEFINE_ARRAY_FIELD (interesting_mechanism_bits_per_heap,size_t, MAX_GC_MECHANISM_BITS_COUNT)
DEFINE_FIELD (internal_root_array, uint8_t*)
DEFINE_FIELD (internal_root_array_index, size_t)
DEFINE_FIELD (heap_analyze_success, BOOL)
DEFINE_FIELD (card_table, uint32_t*)
#if defined(ALL_FIELDS) || defined(BACKGROUND_GC)
DEFINE_FIELD (mark_array, uint32_t*)
DEFINE_FIELD (next_sweep_obj, uint8_t*)
DEFINE_FIELD (background_saved_lowest_address, uint8_t*)
DEFINE_FIELD (background_saved_highest_address, uint8_t*)
#if defined(ALL_FIELDS) || !defined(USE_REGIONS)
DEFINE_DPTR_FIELD (saved_sweep_ephemeral_seg, dac_heap_segment)
DEFINE_FIELD (saved_sweep_ephemeral_start, uint8_t*)
#else
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
#endif
#else
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
DEFINE_MISSING_FIELD
#endif
35 changes: 17 additions & 18 deletions src/coreclr/gc/gcinterface.dac.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,24 +136,17 @@ struct oom_history
// GC heap (of which there are multiple, with server GC).
class dac_gc_heap {
public:
uint8_t* alloc_allocated;
DPTR(dac_heap_segment) ephemeral_heap_segment;
DPTR(dac_finalize_queue) finalize_queue;
oom_history oom_info;
size_t interesting_data_per_heap[NUM_GC_DATA_POINTS];
size_t compact_reasons_per_heap[MAX_COMPACT_REASONS_COUNT];
size_t expand_mechanisms_per_heap[MAX_EXPAND_MECHANISMS_COUNT];
size_t interesting_mechanism_bits_per_heap[MAX_GC_MECHANISM_BITS_COUNT];
uint8_t* internal_root_array;
size_t internal_root_array_index;
BOOL heap_analyze_success;
uint32_t* card_table;
uint32_t* mark_array;
uint8_t* next_sweep_obj;
uint8_t* background_saved_lowest_address;
uint8_t* background_saved_highest_address;
DPTR(dac_heap_segment) saved_sweep_ephemeral_seg;
uint8_t* saved_sweep_ephemeral_start;
#define ALL_FIELDS
#define DEFINE_FIELD(field_name, field_type) field_type field_name;
#define DEFINE_DPTR_FIELD(field_name, field_type) DPTR(field_type) field_name;
#define DEFINE_ARRAY_FIELD(field_name, field_type, array_length) field_type field_name[array_length];

#include "gc_typefields.h"

#undef DEFINE_ARRAY_FIELD
#undef DEFINE_DPTR_FIELD
#undef DEFINE_FIELD
#undef ALL_FIELDS

// The generation table must always be last, because the size of this array
// (stored inline in the gc_heap class) can vary.
Expand All @@ -169,6 +162,12 @@ class dac_gc_heap {
dac_generation generation_table[1];
};

#define GENERATION_TABLE_FIELD_INDEX 18

struct opaque_gc_heap
{
uint8_t unused;
};

// The DAC links against six symbols that build as part of the VM DACCESS_COMPILE
// build. These symbols are considered to be GC-private functions, but the DAC needs
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/gc/gcinterface.dacvars.def
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ GC_DAC_PTR_VAR (uint8_t*, internal_root_array)
GC_DAC_VAR (size_t, internal_root_array_index)
GC_DAC_VAR (BOOL, heap_analyze_success)
GC_DAC_VAR (int, n_heaps)
GC_DAC_PTR_VAR (dac_gc_heap*, g_heaps)
GC_DAC_PTR_VAR (opaque_gc_heap*, g_heaps)
GC_DAC_VAR (int32_t, gc_structures_invalid_cnt)
GC_DAC_ARRAY_VAR (size_t, interesting_data_per_heap)
GC_DAC_ARRAY_VAR (size_t, compact_reasons_per_heap)
Expand Down