summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ToolBox/SOS/Strike/eeheap.cpp43
-rw-r--r--src/ToolBox/SOS/Strike/gcroot.cpp13
-rw-r--r--src/ToolBox/SOS/Strike/sos.cpp137
-rw-r--r--src/ToolBox/SOS/Strike/sos.h2
-rw-r--r--src/ToolBox/SOS/Strike/util.h10
-rw-r--r--src/debug/daccess/daccess.cpp4
-rw-r--r--src/debug/daccess/dacimpl.h6
-rw-r--r--src/debug/daccess/request.cpp27
-rw-r--r--src/inc/dacprivate.h20
-rw-r--r--src/inc/sospriv.idl10
-rw-r--r--src/pal/prebuilt/idl/sospriv_i.cpp4
-rw-r--r--src/pal/prebuilt/inc/sospriv.h80
12 files changed, 303 insertions, 53 deletions
diff --git a/src/ToolBox/SOS/Strike/eeheap.cpp b/src/ToolBox/SOS/Strike/eeheap.cpp
index 5a5680fcfb..c28c9641f5 100644
--- a/src/ToolBox/SOS/Strike/eeheap.cpp
+++ b/src/ToolBox/SOS/Strike/eeheap.cpp
@@ -868,8 +868,7 @@ DWORD GetNumComponents(TADDR obj)
return Value;
}
-BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
- DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers)
+static MethodTableInfo* GetMethodTableInfo(DWORD_PTR dwAddrMethTable)
{
// Remove lower bits in case we are in mark phase
dwAddrMethTable = dwAddrMethTable & ~3;
@@ -880,12 +879,34 @@ BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
// from the target
DacpMethodTableData dmtd;
// see code:ClrDataAccess::RequestMethodTableData for details
- if (dmtd.Request(g_sos,dwAddrMethTable) != S_OK)
- return FALSE;
+ if (dmtd.Request(g_sos, dwAddrMethTable) != S_OK)
+ return NULL;
+
info->BaseSize = dmtd.BaseSize;
info->ComponentSize = dmtd.ComponentSize;
info->bContainsPointers = dmtd.bContainsPointers;
+
+ // The following request doesn't work on older runtimes. For those, the
+ // objects would just look like non-collectible, which is acceptable.
+ DacpMethodTableCollectibleData dmtcd;
+ if (SUCCEEDED(dmtcd.Request(g_sos, dwAddrMethTable)))
+ {
+ info->bCollectible = dmtcd.bCollectible;
+ info->LoaderAllocatorObjectHandle = TO_TADDR(dmtcd.LoaderAllocatorObjectHandle);
+ }
+ }
+
+ return info;
+}
+
+BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
+ DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers)
+{
+ MethodTableInfo* info = GetMethodTableInfo(dwAddrMethTable);
+ if (info == NULL)
+ {
+ return FALSE;
}
bContainsPointers = info->bContainsPointers;
@@ -911,6 +932,20 @@ BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
return TRUE;
}
+BOOL GetCollectibleDataEfficient(DWORD_PTR dwAddrMethTable, BOOL& bCollectible, TADDR& loaderAllocatorObjectHandle)
+{
+ MethodTableInfo* info = GetMethodTableInfo(dwAddrMethTable);
+ if (info == NULL)
+ {
+ return FALSE;
+ }
+
+ bCollectible = info->bCollectible;
+ loaderAllocatorObjectHandle = info->LoaderAllocatorObjectHandle;
+
+ return TRUE;
+}
+
// This function expects stat to be valid, and ready to get statistics.
void GatherOneHeapFinalization(DacpGcHeapDetails& heapDetails, HeapStat *stat, BOOL bAllReady, BOOL bShort)
{
diff --git a/src/ToolBox/SOS/Strike/gcroot.cpp b/src/ToolBox/SOS/Strike/gcroot.cpp
index e4262208e4..cd13719094 100644
--- a/src/ToolBox/SOS/Strike/gcroot.cpp
+++ b/src/ToolBox/SOS/Strike/gcroot.cpp
@@ -1009,7 +1009,7 @@ GCRootImpl::RootNode *GCRootImpl::GetGCRefs(RootNode *path, RootNode *node)
// Only calculate the size if we need it.
size_t objSize = 0;
- if (mSize || node->MTInfo->ContainsPointers)
+ if (mSize || node->MTInfo->ContainsPointers || node->MTInfo->Collectible)
{
objSize = GetSizeOfObject(obj, node->MTInfo);
@@ -1027,7 +1027,7 @@ GCRootImpl::RootNode *GCRootImpl::GetGCRefs(RootNode *path, RootNode *node)
}
// Early out: If the object doesn't contain any pointers, return.
- if (!node->MTInfo->ContainsPointers)
+ if (!node->MTInfo->ContainsPointers && !node->MTInfo->Collectible)
return NULL;
// Make sure we have the object's data in the cache.
@@ -1139,6 +1139,15 @@ GCRootImpl::MTInfo *GCRootImpl::GetMTInfo(TADDR mt)
curr->ComponentSize = (size_t)dmtd.ComponentSize;
curr->ContainsPointers = dmtd.bContainsPointers ? true : false;
+ // The following request doesn't work on older runtimes. For those, the
+ // objects would just look like non-collectible, which is acceptable.
+ DacpMethodTableCollectibleData dmtcd;
+ if (SUCCEEDED(dmtcd.Request(g_sos, mt)))
+ {
+ curr->Collectible = dmtcd.bCollectible ? true : false;
+ curr->LoaderAllocatorObjectHandle = TO_TADDR(dmtcd.LoaderAllocatorObjectHandle);
+ }
+
// If this method table contains pointers, fill out and cache the GCDesc.
if (curr->ContainsPointers)
{
diff --git a/src/ToolBox/SOS/Strike/sos.cpp b/src/ToolBox/SOS/Strike/sos.cpp
index 64ee4b9a0c..5ff77a905a 100644
--- a/src/ToolBox/SOS/Strike/sos.cpp
+++ b/src/ToolBox/SOS/Strike/sos.cpp
@@ -180,6 +180,15 @@ namespace sos
info->BaseSize = mMTData->BaseSize;
info->ComponentSize = mMTData->ComponentSize;
info->bContainsPointers = mMTData->bContainsPointers;
+
+ // The following request doesn't work on older runtimes. For those, the
+ // objects would just look like non-collectible, which is acceptable.
+ DacpMethodTableCollectibleData mtcd;
+ if (SUCCEEDED(mtcd.Request(g_sos, GetMT())))
+ {
+ info->bCollectible = mtcd.bCollectible;
+ info->LoaderAllocatorObjectHandle = TO_TADDR(mtcd.LoaderAllocatorObjectHandle);
+ }
}
if (mSize == (size_t)~0)
@@ -380,14 +389,14 @@ namespace sos
RefIterator::RefIterator(TADDR obj, LinearReadCache *cache)
- : mCache(cache), mGCDesc(0), mArrayOfVC(false), mDone(false), mBuffer(0), mCurrSeries(0),
+ : mCache(cache), mGCDesc(0), mArrayOfVC(false), mDone(false), mBuffer(0), mCurrSeries(0), mLoaderAllocatorObjectHandle(0),
i(0), mCount(0), mCurr(0), mStop(0), mObject(obj), mObjSize(0)
{
Init();
}
RefIterator::RefIterator(TADDR obj, CGCDesc *desc, bool arrayOfVC, LinearReadCache *cache)
- : mCache(cache), mGCDesc(desc), mArrayOfVC(arrayOfVC), mDone(false), mBuffer(0), mCurrSeries(0),
+ : mCache(cache), mGCDesc(desc), mArrayOfVC(arrayOfVC), mDone(false), mBuffer(0), mCurrSeries(0), mLoaderAllocatorObjectHandle(0),
i(0), mCount(0), mCurr(0), mStop(0), mObject(obj), mObjSize(0)
{
Init();
@@ -403,6 +412,13 @@ namespace sos
{
if (mDone)
Throw<Exception>("Attempt to move past the end of the iterator.");
+
+ if (mCurr == mLoaderAllocatorObjectHandle)
+ {
+ // The mLoaderAllocatorObjectHandle is always the last reference returned
+ mDone = true;
+ return *this;
+ }
if (!mArrayOfVC)
{
@@ -440,6 +456,14 @@ namespace sos
mDone = true;
}
+ if (mDone && mLoaderAllocatorObjectHandle != NULL)
+ {
+ // The iteration over all regular object references is done, but there is one more
+ // reference for collectible types - the LoaderAllocator for GC
+ mCurr = mLoaderAllocatorObjectHandle;
+ mDone = false;
+ }
+
return *this;
}
@@ -457,66 +481,89 @@ namespace sos
{
TADDR mt = ReadPointer(mObject);
BOOL bContainsPointers = FALSE;
-
+ BOOL bCollectible = FALSE;
+ TADDR loaderAllocatorObjectHandle;
+
if (!GetSizeEfficient(mObject, mt, FALSE, mObjSize, bContainsPointers))
Throw<DataRead>("Failed to get size of object.");
-
- if (!bContainsPointers)
+
+ if (!GetCollectibleDataEfficient(mt, bCollectible, loaderAllocatorObjectHandle))
+ Throw<DataRead>("Failed to get collectible info of object.");
+
+ if (!bContainsPointers && !bCollectible)
{
mDone = true;
return;
}
-
- if (!mGCDesc)
+
+ if (bContainsPointers)
{
- int entries = 0;
-
- if (FAILED(MOVE(entries, mt-sizeof(TADDR))))
- Throw<DataRead>("Failed to request number of entries.");
-
- // array of vc?
- if (entries < 0)
+ if (!mGCDesc)
{
- entries = -entries;
- mArrayOfVC = true;
+ int entries = 0;
+
+ if (FAILED(MOVE(entries, mt-sizeof(TADDR))))
+ Throw<DataRead>("Failed to request number of entries.");
+
+ // array of vc?
+ if (entries < 0)
+ {
+ entries = -entries;
+ mArrayOfVC = true;
+ }
+ else
+ {
+ mArrayOfVC = false;
+ }
+
+ size_t slots = 1 + entries * sizeof(CGCDescSeries)/sizeof(TADDR);
+
+ ArrayHolder<TADDR> buffer = new TADDR[slots];
+
+ ULONG fetched = 0;
+ CLRDATA_ADDRESS address = TO_CDADDR(mt - slots*sizeof(TADDR));
+ if (FAILED(g_ExtData->ReadVirtual(address, buffer, (ULONG)(slots*sizeof(TADDR)), &fetched)))
+ Throw<DataRead>("Failed to request GCDesc.");
+
+ mBuffer = buffer.Detach();
+ mGCDesc = (CGCDesc*)(mBuffer + slots);
+ }
+
+ mCurrSeries = mGCDesc->GetHighestSeries();
+
+ if (!mArrayOfVC)
+ {
+ mCurr = mObject + mCurrSeries->GetSeriesOffset();
+ mStop = mCurr + mCurrSeries->GetSeriesSize() + mObjSize;
}
else
{
- mArrayOfVC = false;
+ i = 0;
+ mCurr = mObject + mCurrSeries->startoffset;
+ mStop = mCurr + mCurrSeries->val_serie[i].nptrs * sizeof(TADDR);
+ mCount = (int)mGCDesc->GetNumSeries();
}
-
- size_t slots = 1 + entries * sizeof(CGCDescSeries)/sizeof(TADDR);
-
- ArrayHolder<TADDR> buffer = new TADDR[slots];
-
- ULONG fetched = 0;
- CLRDATA_ADDRESS address = TO_CDADDR(mt - slots*sizeof(TADDR));
- if (FAILED(g_ExtData->ReadVirtual(address, buffer, (ULONG)(slots*sizeof(TADDR)), &fetched)))
- Throw<DataRead>("Failed to request GCDesc.");
-
- mBuffer = buffer.Detach();
- mGCDesc = (CGCDesc*)(mBuffer + slots);
+
+ if (mCurr == mStop)
+ operator++();
+ else if (mCurr >= mObject + mObjSize - plug_skew)
+ mDone = true;
}
-
- mCurrSeries = mGCDesc->GetHighestSeries();
-
- if (!mArrayOfVC)
+ else
{
- mCurr = mObject + mCurrSeries->GetSeriesOffset();
- mStop = mCurr + mCurrSeries->GetSeriesSize() + mObjSize;
+ mDone = true;
}
- else
+
+ if (bCollectible)
{
- i = 0;
- mCurr = mObject + mCurrSeries->startoffset;
- mStop = mCurr + mCurrSeries->val_serie[i].nptrs * sizeof(TADDR);
- mCount = (int)mGCDesc->GetNumSeries();
+ mLoaderAllocatorObjectHandle = loaderAllocatorObjectHandle;
+ if (mDone)
+ {
+ // There are no object references, but there is still a reference for
+ // collectible types - the LoaderAllocator for GC
+ mCurr = mLoaderAllocatorObjectHandle;
+ }
}
-
- if (mCurr == mStop)
- operator++();
- else if (mCurr >= mObject + mObjSize - plug_skew)
- mDone = true;
}
diff --git a/src/ToolBox/SOS/Strike/sos.h b/src/ToolBox/SOS/Strike/sos.h
index 3778235964..ff5b53a9c7 100644
--- a/src/ToolBox/SOS/Strike/sos.h
+++ b/src/ToolBox/SOS/Strike/sos.h
@@ -501,6 +501,8 @@ namespace sos
TADDR *mBuffer;
CGCDescSeries *mCurrSeries;
+ TADDR mLoaderAllocatorObjectHandle;
+
int i, mCount;
TADDR mCurr, mStop, mObject;
diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h
index 78516546ac..ebad2e49ff 100644
--- a/src/ToolBox/SOS/Strike/util.h
+++ b/src/ToolBox/SOS/Strike/util.h
@@ -1660,9 +1660,11 @@ struct MethodTableInfo
DWORD BaseSize; // Caching BaseSize and ComponentSize for a MethodTable
DWORD ComponentSize; // here has HUGE perf benefits in heap traversals.
BOOL bContainsPointers;
+ BOOL bCollectible;
DWORD_PTR* GCInfoBuffer; // Start of memory of GC info
CGCDesc* GCInfo; // Just past GC info (which is how it is stored)
bool ArrayOfVC;
+ TADDR LoaderAllocatorObjectHandle;
};
class MethodTableCache
@@ -1680,9 +1682,11 @@ protected:
info.BaseSize = 0;
info.ComponentSize = 0;
info.bContainsPointers = false;
+ info.bCollectible = false;
info.GCInfo = NULL;
info.ArrayOfVC = false;
info.GCInfoBuffer = NULL;
+ info.LoaderAllocatorObjectHandle = NULL;
}
};
Node *head;
@@ -1948,6 +1952,8 @@ size_t NextOSPageAddress (size_t addr);
BOOL GetSizeEfficient(DWORD_PTR dwAddrCurrObj,
DWORD_PTR dwAddrMethTable, BOOL bLarge, size_t& s, BOOL& bContainsPointers);
+BOOL GetCollectibleDataEfficient(DWORD_PTR dwAddrMethTable, BOOL& bCollectible, TADDR& loaderAllocatorObjectHandle);
+
// ObjSize now uses the methodtable cache for its work too.
size_t ObjectSize (DWORD_PTR obj, BOOL fIsLargeObject=FALSE);
size_t ObjectSize(DWORD_PTR obj, DWORD_PTR mt, BOOL fIsValueClass, BOOL fIsLargeObject=FALSE);
@@ -2856,8 +2862,10 @@ private:
TADDR *Buffer;
CGCDesc *GCDesc;
+ TADDR LoaderAllocatorObjectHandle;
bool ArrayOfVC;
bool ContainsPointers;
+ bool Collectible;
size_t BaseSize;
size_t ComponentSize;
@@ -2874,7 +2882,7 @@ private:
MTInfo()
: MethodTable(0), TypeName(0), Buffer(0), GCDesc(0),
- ArrayOfVC(false), ContainsPointers(false), BaseSize(0), ComponentSize(0)
+ ArrayOfVC(false), ContainsPointers(false), Collectible(false), BaseSize(0), ComponentSize(0)
{
}
diff --git a/src/debug/daccess/daccess.cpp b/src/debug/daccess/daccess.cpp
index 1ce452bc2d..e7bef87c0c 100644
--- a/src/debug/daccess/daccess.cpp
+++ b/src/debug/daccess/daccess.cpp
@@ -3278,6 +3278,10 @@ ClrDataAccess::QueryInterface(THIS_
{
ifaceRet = static_cast<ISOSDacInterface5*>(this);
}
+ else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface6)))
+ {
+ ifaceRet = static_cast<ISOSDacInterface6*>(this);
+ }
else
{
*iface = NULL;
diff --git a/src/debug/daccess/dacimpl.h b/src/debug/daccess/dacimpl.h
index 6147de3dde..e05575c141 100644
--- a/src/debug/daccess/dacimpl.h
+++ b/src/debug/daccess/dacimpl.h
@@ -862,7 +862,8 @@ class ClrDataAccess
public ISOSDacInterface2,
public ISOSDacInterface3,
public ISOSDacInterface4,
- public ISOSDacInterface5
+ public ISOSDacInterface5,
+ public ISOSDacInterface6
{
public:
ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
@@ -1208,6 +1209,9 @@ public:
// ISOSDacInterface5
virtual HRESULT STDMETHODCALLTYPE GetTieredVersions(CLRDATA_ADDRESS methodDesc, int rejitId, struct DacpTieredVersionData *nativeCodeAddrs, int cNativeCodeAddrs, int *pcNativeCodeAddrs);
+ // ISOSDacInterface6
+ virtual HRESULT STDMETHODCALLTYPE GetMethodTableCollectibleData(CLRDATA_ADDRESS mt, struct DacpMethodTableCollectibleData *data);
+
//
// ClrDataAccess.
//
diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp
index 12864e7b0d..3a497b1a32 100644
--- a/src/debug/daccess/request.cpp
+++ b/src/debug/daccess/request.cpp
@@ -1955,6 +1955,33 @@ ClrDataAccess::GetMethodTableFieldData(CLRDATA_ADDRESS mt, struct DacpMethodTabl
}
HRESULT
+ClrDataAccess::GetMethodTableCollectibleData(CLRDATA_ADDRESS mt, struct DacpMethodTableCollectibleData *data)
+{
+ if (mt == 0 || data == NULL)
+ return E_INVALIDARG;
+
+ SOSDacEnter();
+
+ MethodTable* pMT = PTR_MethodTable(TO_TADDR(mt));
+ BOOL bIsFree = FALSE;
+ if (!pMT || !DacValidateMethodTable(pMT, bIsFree))
+ {
+ hr = E_INVALIDARG;
+ }
+ else
+ {
+ data->bCollectible = pMT->Collectible();
+ if (data->bCollectible)
+ {
+ data->LoaderAllocatorObjectHandle = pMT->GetLoaderAllocatorObjectHandle();
+ }
+ }
+
+ SOSDacLeave();
+ return hr;
+}
+
+HRESULT
ClrDataAccess::GetMethodTableTransparencyData(CLRDATA_ADDRESS mt, struct DacpMethodTableTransparencyData *pTransparencyData)
{
if (mt == 0 || pTransparencyData == NULL)
diff --git a/src/inc/dacprivate.h b/src/inc/dacprivate.h
index 2f7482680d..47e79a131f 100644
--- a/src/inc/dacprivate.h
+++ b/src/inc/dacprivate.h
@@ -177,6 +177,25 @@ struct MSLAYOUT DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
}
};
+struct MSLAYOUT DacpMethodTableCollectibleData : ZeroInit<DacpMethodTableCollectibleData>
+{
+ CLRDATA_ADDRESS LoaderAllocatorObjectHandle;
+ BOOL bCollectible;
+
+ HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
+ {
+ HRESULT hr;
+ ISOSDacInterface6 *pSOS6 = NULL;
+ if (SUCCEEDED(hr = sos->QueryInterface(__uuidof(ISOSDacInterface6), (void**)&pSOS6)))
+ {
+ hr = pSOS6->GetMethodTableCollectibleData(addr, this);
+ pSOS6->Release();
+ }
+
+ return hr;
+ }
+};
+
struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
{
BOOL bHasCriticalTransparentInfo;
@@ -1043,5 +1062,6 @@ static_assert(sizeof(DacpGetModuleAddress) == 0x8, "Dacp structs cannot be modif
static_assert(sizeof(DacpFrameData) == 0x8, "Dacp structs cannot be modified due to backwards compatibility.");
static_assert(sizeof(DacpJitCodeHeapInfo) == 0x18, "Dacp structs cannot be modified due to backwards compatibility.");
static_assert(sizeof(DacpExceptionObjectData) == 0x38, "Dacp structs cannot be modified due to backwards compatibility.");
+static_assert(sizeof(DacpMethodTableCollectibleData) == 0x10, "Dacp structs cannot be modified due to backwards compatibility.");
#endif // _DACPRIVATE_H_
diff --git a/src/inc/sospriv.idl b/src/inc/sospriv.idl
index 5b718210d7..589642675f 100644
--- a/src/inc/sospriv.idl
+++ b/src/inc/sospriv.idl
@@ -367,3 +367,13 @@ interface ISOSDacInterface5 : IUnknown
{
HRESULT GetTieredVersions(CLRDATA_ADDRESS methodDesc, int rejitId, struct DacpTieredVersionData *nativeCodeAddrs, int cNativeCodeAddrs, int *pcNativeCodeAddrs);
};
+
+[
+ object,
+ local,
+ uuid(11206399-4B66-4EDB-98EA-85654E59AD45)
+]
+interface ISOSDacInterface6 : IUnknown
+{
+ HRESULT GetMethodTableFieldData(CLRDATA_ADDRESS mt, struct DacpMethodTableFieldData *data);
+};
diff --git a/src/pal/prebuilt/idl/sospriv_i.cpp b/src/pal/prebuilt/idl/sospriv_i.cpp
index 7c0cd69bba..290b9b75d0 100644
--- a/src/pal/prebuilt/idl/sospriv_i.cpp
+++ b/src/pal/prebuilt/idl/sospriv_i.cpp
@@ -91,6 +91,10 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface4,0x74B9D34C,0xA612,0x4B07,0x93,0xDD,0
MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface5,0x127d6abe,0x6c86,0x4e48,0x8e,0x7b,0x22,0x07,0x81,0xc5,0x81,0x01);
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface6,0x11206399,0x4b66,0x4edb,0x98,0xea,0x85,0x65,0x4e,0x59,0xad,0x45);
+
+
#undef MIDL_DEFINE_GUID
#ifdef __cplusplus
diff --git a/src/pal/prebuilt/inc/sospriv.h b/src/pal/prebuilt/inc/sospriv.h
index 3b810cc9b6..8896720792 100644
--- a/src/pal/prebuilt/inc/sospriv.h
+++ b/src/pal/prebuilt/inc/sospriv.h
@@ -2272,6 +2272,86 @@ EXTERN_C const IID IID_ISOSDacInterface5;
#endif /* __ISOSDacInterface5_INTERFACE_DEFINED__ */
+
+#ifndef __ISOSDacInterface6_INTERFACE_DEFINED__
+#define __ISOSDacInterface6_INTERFACE_DEFINED__
+
+ /* interface ISOSDacInterface6 */
+ /* [uuid][local][object] */
+
+
+ EXTERN_C const IID IID_ISOSDacInterface6;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("11206399-4B66-4EDB-98EA-85654E59AD45")
+ ISOSDacInterface6 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetMethodTableCollectibleData(
+ CLRDATA_ADDRESS mt,
+ struct DacpMethodTableCollectibleData *data) = 0;
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ISOSDacInterface6Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT(STDMETHODCALLTYPE *QueryInterface)(
+ ISOSDacInterface5 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG(STDMETHODCALLTYPE *AddRef)(
+ ISOSDacInterface5 * This);
+
+ ULONG(STDMETHODCALLTYPE *Release)(
+ ISOSDacInterface5 * This);
+
+ HRESULT(STDMETHODCALLTYPE *GetMethodTableCollectibleData)(
+ CLRDATA_ADDRESS mt,
+ struct DacpMethodTableCollectibleData *data);
+
+ END_INTERFACE
+ } ISOSDacInterface6Vtbl;
+
+ interface ISOSDacInterface6
+ {
+ CONST_VTBL struct ISOSDacInterface6Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISOSDacInterface6_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ISOSDacInterface6_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ISOSDacInterface6_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ISOSDacInterface6_GetMethodTableCollectibleData(This,mt,data) \
+ ( (This)->lpVtbl -> GetMethodTableCollectibleData(This,mt,data) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ISOSDacInterface6_INTERFACE_DEFINED__ */
+
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */