Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Dac changes for pinned object heap
  • Loading branch information
davmason committed Jun 13, 2020
commit 29f1087f2dcb9a116039a06d8e568b60b122bc89
4 changes: 4 additions & 0 deletions src/coreclr/src/debug/daccess/daccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3290,6 +3290,10 @@ ClrDataAccess::QueryInterface(THIS_
{
ifaceRet = static_cast<ISOSDacInterface7*>(this);
}
else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface8)))
{
ifaceRet = static_cast<ISOSDacInterface8*>(this);
}
else
{
*iface = NULL;
Expand Down
10 changes: 9 additions & 1 deletion src/coreclr/src/debug/daccess/dacimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,8 @@ class ClrDataAccess
public ISOSDacInterface4,
public ISOSDacInterface5,
public ISOSDacInterface6,
public ISOSDacInterface7
public ISOSDacInterface7,
public ISOSDacInterface8
{
public:
ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
Expand Down Expand Up @@ -1195,6 +1196,13 @@ class ClrDataAccess
virtual HRESULT STDMETHODCALLTYPE GetProfilerModifiedILInformation(CLRDATA_ADDRESS methodDesc, struct DacpProfilerILData *pILData);
virtual HRESULT STDMETHODCALLTYPE GetMethodsWithProfilerModifiedIL(CLRDATA_ADDRESS mod, CLRDATA_ADDRESS *methodDescs, int cMethodDescs, int *pcMethodDescs);

// ISOSDacInterface8
virtual HRESULT STDMETHODCALLTYPE GetGenerationTable(unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded);
virtual HRESULT STDMETHODCALLTYPE GetFinalizationFillPointers(unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded);

virtual HRESULT STDMETHODCALLTYPE GetGenerationTableSvr(CLRDATA_ADDRESS heapAddr, unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded);
virtual HRESULT STDMETHODCALLTYPE GetFinalizationFillPointersSvr(CLRDATA_ADDRESS heapAddr, unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded);

//
// ClrDataAccess.
//
Expand Down
162 changes: 162 additions & 0 deletions src/coreclr/src/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4500,3 +4500,165 @@ HRESULT ClrDataAccess::GetMethodsWithProfilerModifiedIL(CLRDATA_ADDRESS mod, CLR

return hr;
}

HRESULT ClrDataAccess::GetGenerationTable(unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsigned int *pNeeded [](start = 113, length = 21)

is the only purpose of this arg is for verification on the sos side?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's so you can request the number of generations and dynamically allocated an array of the right size

unsigned int count;
if (SUCCEEDED(pSos->GetGenerationTable(0, NULL, &count)
{
    DacpGenerationData *pGenerationData = new DacpGenerationData[count];
    pSos->GetGenerationTable(count, pGenerationData, NULL);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I didn't know it was going to be called this way. makes sense. thanks!

{
if (cGenerations > 0 && pGenerationData == NULL)
{
return E_INVALIDARG;
}

SOSDacEnter();

HRESULT hr = S_OK;
unsigned int numGenerationTableEntries = NUMBERGENERATIONS + 1;
if (pNeeded != NULL)
{
*pNeeded = numGenerationTableEntries;
}

if (cGenerations < numGenerationTableEntries)
{
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
else
{
for (unsigned int i=0; i < numGenerationTableEntries; i++)
{
DPTR(dac_generation) generation = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
pGenerationData[i].start_segment = (CLRDATA_ADDRESS) dac_cast<TADDR>(generation->start_segment);

pGenerationData[i].allocation_start = (CLRDATA_ADDRESS) generation->allocation_start;

DPTR(gc_alloc_context) alloc_context = dac_cast<TADDR>(generation) + offsetof(dac_generation, allocation_context);
pGenerationData[i].allocContextPtr = (CLRDATA_ADDRESS)alloc_context->alloc_ptr;
pGenerationData[i].allocContextLimit = (CLRDATA_ADDRESS)alloc_context->alloc_limit;
}
}

SOSDacLeave();
return hr;
}

HRESULT ClrDataAccess::GetFinalizationFillPointers(unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded)
{
if (cFillPointers > 0 && pFinalizationFillPointers == NULL)
{
return E_INVALIDARG;
}

SOSDacEnter();

HRESULT hr = S_OK;
unsigned int numFillPointers = NUMBERGENERATIONS + 1 + dac_finalize_queue::ExtraSegCount;
if (pNeeded != NULL)
{
*pNeeded = numFillPointers;
}

if (cFillPointers < numFillPointers)
{
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
else
{
if (g_gcDacGlobals->finalize_queue.IsValid())
{
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 < numFillPointers; i++)
{
pFinalizationFillPointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*));
}
}
}

SOSDacLeave();
return hr;
}

HRESULT ClrDataAccess::GetGenerationTableSvr(CLRDATA_ADDRESS heapAddr, unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded)
{
if (heapAddr == NULL || (cGenerations > 0 && pGenerationData == NULL))
{
return E_INVALIDARG;
}

SOSDacEnter();

HRESULT hr = S_OK;
#ifdef FEATURE_SVR_GC
// NUMBERGENERATIONS is hardcoded to the previous number of generations, doesn't account for POH
unsigned int numGenerationTableEntries = NUMBERGENERATIONS + 1;
if (pNeeded != NULL)
{
*pNeeded = numGenerationTableEntries;
}

if (cGenerations < numGenerationTableEntries)
{
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
else
{
DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));

for (unsigned int i = 0; i < numGenerationTableEntries; ++i)
{
DPTR(dac_generation) generation = ServerGenerationTableIndex(pHeap, i);
pGenerationData[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(generation->start_segment);
pGenerationData[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);
pGenerationData[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_ptr;
pGenerationData[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_limit;
}

}
#else
hr = E_NOTIMPL;
#endif

SOSDacLeave();
return hr;
}

HRESULT ClrDataAccess::GetFinalizationFillPointersSvr(CLRDATA_ADDRESS heapAddr, unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded)
{
if (heapAddr == NULL || (cFillPointers > 0 && pFinalizationFillPointers == NULL))
{
return E_INVALIDARG;
}

SOSDacEnter();

HRESULT hr = S_OK;
#ifdef FEATURE_SVR_GC
// NUMBERGENERATIONS is hardcoded to the previous number of generations, doesn't account for POH
unsigned int numFillPointers = NUMBERGENERATIONS + 1 + dac_finalize_queue::ExtraSegCount;
if (pNeeded != NULL)
{
*pNeeded = numFillPointers;
}

if (cFillPointers < numFillPointers)
{
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
else
{
DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));

DPTR(dac_finalize_queue) fq = pHeap->finalize_queue;
DPTR(uint8_t*) pFillPointerArray= dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
for(unsigned int i = 0; i < numFillPointers; ++i)
{
pFinalizationFillPointers[i] = (CLRDATA_ADDRESS) pFillPointerArray[i];
}
}
#else
hr = E_NOTIMPL;
#endif

SOSDacLeave();
return hr;
}
16 changes: 16 additions & 0 deletions src/coreclr/src/inc/sospriv.idl
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,19 @@ interface ISOSDacInterface7 : IUnknown
HRESULT GetProfilerModifiedILInformation(CLRDATA_ADDRESS methodDesc, struct DacpProfilerILData *pILData);
HRESULT GetMethodsWithProfilerModifiedIL(CLRDATA_ADDRESS mod, CLRDATA_ADDRESS *methodDescs, int cMethodDescs, int *pcMethodDescs);
};

[
object,
local,
uuid(c12f35a9-e55c-4520-a894-b3dc5165dfce)
]
interface ISOSDacInterface8 : IUnknown
{
// WKS
HRESULT GetGenerationTable(unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded);
HRESULT GetFinalizationFillPointers(unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded);

// SVR
HRESULT GetGenerationTableSvr(CLRDATA_ADDRESS heapAddr, unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded);
HRESULT GetFinalizationFillPointersSvr(CLRDATA_ADDRESS heapAddr, unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded);
}
3 changes: 3 additions & 0 deletions src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface6,0x11206399,0x4B66,0x4EDB,0x98,0xEA,0

MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface7,0xc1020dde,0xfe98,0x4536,0xa5,0x3b,0xf3,0x5a,0x74,0xc3,0x27,0xeb);


MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface8,0xc12f35a9,0xe55c,0x4520,0xa8,0x94,0xb3,0xdc,0x51,0x65,0xdf,0xce);

#undef MIDL_DEFINE_GUID

#ifdef __cplusplus
Expand Down
Loading