HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapDetails *detailsData) { if (!heapAddr) { // PREfix. return E_INVALIDARG; } SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(heapAddr)); int i; detailsData->heapAddr = heapAddr; detailsData->lowest_address = PTR_CDADDR(g_lowest_address); detailsData->highest_address = PTR_CDADDR(g_highest_address); detailsData->card_table = PTR_CDADDR(g_card_table); detailsData->alloc_allocated = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->alloc_allocated; detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->ephemeral_heap_segment; for (i=0;i<NUMBERGENERATIONS;i++) { detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].start_segment; detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_start; detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_ptr; detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_limit; } TADDR pFillPointerArray = TO_TADDR(pHeap->finalize_queue) + offsetof(SVR::CFinalize,m_FillPointers); for(i=0;i<(NUMBERGENERATIONS+SVR::CFinalize::ExtraSegCount);i++) { ULONG32 returned = sizeof(size_t); size_t pValue; m_target->ReadVirtual(pFillPointerArray+(i*sizeof(size_t)), (PBYTE)&pValue, sizeof(size_t),&returned); if (returned != sizeof(size_t)) { return E_FAIL; } detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pValue; } return S_OK; }
HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapDetails *detailsData) { if (!heapAddr) { // PREfix. return E_INVALIDARG; } DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr)); int i; //get global information first detailsData->heapAddr = heapAddr; detailsData->lowest_address = PTR_CDADDR(g_lowest_address); detailsData->highest_address = PTR_CDADDR(g_highest_address); detailsData->card_table = PTR_CDADDR(g_card_table); // now get information specific to this heap (server mode gives us several heaps; we're getting // information about only one of them. detailsData->alloc_allocated = (CLRDATA_ADDRESS)pHeap->alloc_allocated; detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeap->ephemeral_heap_segment); // get bounds for the different generations for (i=0; i<NUMBERGENERATIONS; i++) { DPTR(dac_generation) generation = ServerGenerationTableIndex(pHeap, i); detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(generation->start_segment); detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR)generation->allocation_start; DPTR(gc_alloc_context) alloc_context = dac_cast<TADDR>(generation) + offsetof(dac_generation, allocation_context); detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_ptr; detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_limit; } DPTR(dac_finalize_queue) fq = pHeap->finalize_queue; DPTR(uint8_t*) pFillPointerArray= dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers); for(i=0; i<(NUMBERGENERATIONS+dac_finalize_queue::ExtraSegCount); i++) { detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pFillPointerArray[i]; } return S_OK; }