Skip to content

Commit

Permalink
Merge branch 'master' into xcnt-false-dep
Browse files Browse the repository at this point in the history
Commit migrated from dotnet/coreclr@58afb7f
  • Loading branch information
pentp authored Sep 6, 2018
2 parents 359be6d + 3d977cf commit c3e48c4
Show file tree
Hide file tree
Showing 162 changed files with 15,318 additions and 3,418 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_IlasmSwitches Condition="'$(DebugType)' == 'Impl'">$(_IlasmSwitches) -DEBUG=IMPL</_IlasmSwitches>
<_IlasmSwitches Condition="'$(DebugType)' == 'PdbOnly'">$(_IlasmSwitches) -DEBUG=OPT</_IlasmSwitches>
<_IlasmSwitches Condition="'$(Optimize)' == 'True'">$(_IlasmSwitches) -OPTIMIZE</_IlasmSwitches>
<_IlasmSwitches Condition="'$(IlasmResourceFile)' != ''">$(_IlasmSwitches) -RESOURCES=$(IlasmResourceFile)</_IlasmSwitches>
</PropertyGroup>

<!-- Having to copy these binaries is really inefficient. https://github.com/dotnet/coreclr/issues/18892 tracks making the ilasm tool self-contained -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ public override bool Equals(object obj)
#endregion

#region Public Members
public Type AttributeType { get { return Constructor.DeclaringType; } }
public virtual Type AttributeType { get { return Constructor.DeclaringType; } }

public virtual ConstructorInfo Constructor { get { return m_ctor; } }

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/ToolBox/SOS/Strike/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,5 @@ target_link_libraries(sos ${SOS_LIBRARY})
install_clr(sos)

if(NOT WIN32)
install(FILES sosdocsunix.txt DESTINATION .)
_install(FILES sosdocsunix.txt DESTINATION .)
endif(NOT WIN32)
43 changes: 39 additions & 4 deletions src/coreclr/src/ToolBox/SOS/Strike/eeheap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)
{
Expand Down
13 changes: 11 additions & 2 deletions src/coreclr/src/ToolBox/SOS/Strike/gcroot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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.
Expand Down Expand Up @@ -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)
{
Expand Down
137 changes: 92 additions & 45 deletions src/coreclr/src/ToolBox/SOS/Strike/sos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}


Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/ToolBox/SOS/Strike/sos.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@ namespace sos
TADDR *mBuffer;
CGCDescSeries *mCurrSeries;

TADDR mLoaderAllocatorObjectHandle;

int i, mCount;

TADDR mCurr, mStop, mObject;
Expand Down
10 changes: 9 additions & 1 deletion src/coreclr/src/ToolBox/SOS/Strike/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -1680,9 +1682,11 @@ class MethodTableCache
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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -2856,8 +2862,10 @@ class GCRootImpl
TADDR *Buffer;
CGCDesc *GCDesc;

TADDR LoaderAllocatorObjectHandle;
bool ArrayOfVC;
bool ContainsPointers;
bool Collectible;
size_t BaseSize;
size_t ComponentSize;

Expand All @@ -2874,7 +2882,7 @@ class GCRootImpl

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)
{
}

Expand Down
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 @@ -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;
Expand Down
Loading

0 comments on commit c3e48c4

Please sign in to comment.