summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-05-24 22:06:37 -0400
committerStephen Toub <stoub@microsoft.com>2019-05-28 06:05:33 -0400
commit25878db0c11bfb8d52088c75ccfcc13e4c8383f2 (patch)
treea735a52f25d8fe5cfdc7db2164416f28aa89ea0c /src/ToolBox
parent66134f6e3646f22ac551fb5d720033d26d4cbf8d (diff)
downloadcoreclr-25878db0c11bfb8d52088c75ccfcc13e4c8383f2.tar.gz
coreclr-25878db0c11bfb8d52088c75ccfcc13e4c8383f2.tar.bz2
coreclr-25878db0c11bfb8d52088c75ccfcc13e4c8383f2.zip
Improve performance of !dumpasync SOS command
A significant majority of the time spent in dumpasync was in getting the type name of each object in order to compare it to "AsyncStateMachineBox". This switches to comparing by module and mdTypeDef. On an ~1GB dump, the time to execute !dumpasync dropped from 43 to 11 seconds on my machine.
Diffstat (limited to 'src/ToolBox')
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp29
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp26
-rw-r--r--src/ToolBox/SOS/Strike/util.h2
3 files changed, 46 insertions, 11 deletions
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp
index 3e4f1668fa..ed9b4cf71a 100644
--- a/src/ToolBox/SOS/Strike/strike.cpp
+++ b/src/ToolBox/SOS/Strike/strike.cpp
@@ -4431,6 +4431,24 @@ void ExtOutStateMachineFields(AsyncRecord& ar)
}
}
+void FindStateMachineTypes(DWORD_PTR* corelibModule, mdTypeDef* stateMachineBox, mdTypeDef* debugStateMachineBox)
+{
+ int numModule;
+ ArrayHolder<DWORD_PTR> moduleList = ModuleFromName(const_cast<LPSTR>("System.Private.CoreLib.dll"), &numModule);
+ if (moduleList != NULL && numModule == 1)
+ {
+ *corelibModule = moduleList[0];
+ GetInfoFromName(*corelibModule, "System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1", stateMachineBox);
+ GetInfoFromName(*corelibModule, "System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+DebugFinalizableAsyncStateMachineBox`1", debugStateMachineBox);
+ }
+ else
+ {
+ *corelibModule = 0;
+ *stateMachineBox = 0;
+ *debugStateMachineBox = 0;
+ }
+}
+
DECLARE_API(DumpAsync)
{
INIT_API();
@@ -4494,6 +4512,11 @@ DECLARE_API(DumpAsync)
DisplayInvalidStructuresMessage();
}
+ // Find the state machine types
+ DWORD_PTR corelibModule;
+ mdTypeDef stateMachineBoxMd, debugStateMachineBoxMd;
+ FindStateMachineTypes(&corelibModule, &stateMachineBoxMd, &debugStateMachineBoxMd);
+
// Walk each heap object looking for async state machine objects. As we're targeting .NET Core 2.1+, all such objects
// will be Task or Task-derived types.
std::map<CLRDATA_ADDRESS, AsyncRecord> asyncRecords;
@@ -4519,8 +4542,10 @@ DECLARE_API(DumpAsync)
{
// Otherwise, we only care about AsyncStateMachineBox`1 as well as the DebugFinalizableAsyncStateMachineBox`1
// that's used when certain ETW events are set.
- if (_wcsncmp(itr->GetTypeName(), W("System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1"), 79) != 0 &&
- _wcsncmp(itr->GetTypeName(), W("System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+DebugFinalizableAsyncStateMachineBox`1"), 95) != 0)
+ DacpMethodTableData mtdata;
+ if (mtdata.Request(g_sos, TO_TADDR(itr->GetMT())) != S_OK ||
+ mtdata.Module != corelibModule ||
+ (mtdata.cl != stateMachineBoxMd && mtdata.cl != debugStateMachineBoxMd))
{
continue;
}
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp
index 9ff51d45f6..880c5656a4 100644
--- a/src/ToolBox/SOS/Strike/util.cpp
+++ b/src/ToolBox/SOS/Strike/util.cpp
@@ -2839,8 +2839,12 @@ Failure:
* Find the EE data given a name. *
* *
\**********************************************************************/
-void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
+void GetInfoFromName(DWORD_PTR ModulePtr, const char* name, mdTypeDef* retMdTypeDef)
{
+ DWORD_PTR ignoredModuleInfoRet = NULL;
+ if (retMdTypeDef)
+ *retMdTypeDef = 0;
+
ToRelease<IMetaDataImport> pImport = MDImportForModule (ModulePtr);
if (pImport == 0)
return;
@@ -2865,13 +2869,13 @@ void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
BOOL fStatus = FALSE;
while (ModuleDefinition->EnumMethodDefinitionByName(&h, &pMeth) == S_OK)
{
- if (fStatus)
+ if (fStatus && !retMdTypeDef)
ExtOut("-----------------------\n");
mdTypeDef token;
if (pMeth->GetTokenAndScope(&token, NULL) == S_OK)
{
- GetInfoFromModule(ModulePtr, token);
+ GetInfoFromModule(ModulePtr, token, retMdTypeDef ? &ignoredModuleInfoRet : NULL);
fStatus = TRUE;
}
pMeth->Release();
@@ -2900,7 +2904,10 @@ void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
// @todo: Handle Nested classes correctly.
if (SUCCEEDED (pImport->FindTypeDefByName (pName, tkEnclose, &cl)))
{
- GetInfoFromModule(ModulePtr, cl);
+ if (retMdTypeDef)
+ *retMdTypeDef = cl;
+
+ GetInfoFromModule(ModulePtr, cl, retMdTypeDef ? &ignoredModuleInfoRet : NULL);
return;
}
@@ -2917,6 +2924,9 @@ void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
// @todo: Handle Nested classes correctly.
if (SUCCEEDED(pImport->FindTypeDefByName (pName, tkEnclose, &cl)))
{
+ if (retMdTypeDef)
+ *retMdTypeDef = cl;
+
mdMethodDef token;
ULONG cTokens;
HCORENUM henum = NULL;
@@ -2927,8 +2937,8 @@ void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
&token, 1, &cTokens))
&& cTokens == 1)
{
- ExtOut("Member (mdToken token) of\n");
- GetInfoFromModule(ModulePtr, cl);
+ if (!retMdTypeDef) ExtOut("Member (mdToken token) of\n");
+ GetInfoFromModule(ModulePtr, cl, retMdTypeDef ? &ignoredModuleInfoRet : NULL);
return;
}
@@ -2938,8 +2948,8 @@ void GetInfoFromName(DWORD_PTR ModulePtr, const char* name)
&token, 1, &cTokens))
&& cTokens == 1)
{
- ExtOut("Field (mdToken token) of\n");
- GetInfoFromModule(ModulePtr, cl);
+ if (!retMdTypeDef) ExtOut("Field (mdToken token) of\n");
+ GetInfoFromModule(ModulePtr, cl, retMdTypeDef ? &ignoredModuleInfoRet : NULL);
return;
}
}
diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h
index 43036633e3..55c822e150 100644
--- a/src/ToolBox/SOS/Strike/util.h
+++ b/src/ToolBox/SOS/Strike/util.h
@@ -1862,7 +1862,7 @@ BOOL TryGetMethodDescriptorForDelegate(CLRDATA_ADDRESS delegateAddr, CLRDATA_ADD
* ArrayHolder class.
*/
DWORD_PTR *ModuleFromName(__in_opt LPSTR name, int *numModules);
-void GetInfoFromName(DWORD_PTR ModuleAddr, const char* name);
+void GetInfoFromName(DWORD_PTR ModuleAddr, const char* name, mdTypeDef* retMdTypeDef=NULL);
void GetInfoFromModule (DWORD_PTR ModuleAddr, ULONG token, DWORD_PTR *ret=NULL);