SuperPMI: add ability to exclude failing method contexts from replays (dotnet/coreclr...
authorSergey Andreenko <seandree@microsoft.com>
Tue, 3 Jul 2018 00:32:59 +0000 (17:32 -0700)
committerGitHub <noreply@github.com>
Tue, 3 Jul 2018 00:32:59 +0000 (17:32 -0700)
* format spmi

* rename mchFile to mchFileName

* refactor ProcessChildStdOut

* add a stub to exclude methods

Commit migrated from https://github.com/dotnet/coreclr/commit/15a6beb33de6f243d59f6b61ec90cfcb336f45af

src/coreclr/src/ToolBox/superpmi/mcs/verbremovedup.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.h
src/coreclr/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
src/coreclr/src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
src/coreclr/src/ToolBox/superpmi/superpmi/superpmi.cpp

index cd2ead0..64d5fa4 100644 (file)
@@ -11,8 +11,8 @@
 #include "methodcontextiterator.h"
 
 // We use a hash to limit the number of comparisons we need to do.
- //The first level key to our hash map is ILCodeSize and the second
- //level map key is just an index and the value is an existing MC Hash.
+// The first level key to our hash map is ILCodeSize and the second
+// level map key is just an index and the value is an existing MC Hash.
 
 LightWeightMap<int, DenseLightWeightMap<char*>*>* inFile = nullptr;
 
index b5de52f..97be26f 100644 (file)
@@ -2436,7 +2436,7 @@ InfoAccessType MethodContext::repConstructStringLiteral(CORINFO_MODULE_HANDLE mo
     return (InfoAccessType)temp2.B;
 }
 
-void MethodContext::recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert, bool result)
+void MethodContext::recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert, bool result)
 {
     if (ConvertPInvokeCalliToCall == nullptr)
         ConvertPInvokeCalliToCall = new LightWeightMap<DLD, DWORDLONG>();
@@ -2456,7 +2456,7 @@ void MethodContext::dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value)
 {
     printf("ConvertPInvokeCalliToCall key mod-%016llX tok-%08X, value %016llX", key.A, key.B, value);
 }
-bool MethodContext::repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+bool MethodContext::repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert)
 {
     DLD key;
     ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero
@@ -4362,7 +4362,8 @@ void MethodContext::dmpCanInlineTypeCheckWithObjectVTable(DWORDLONG key, DWORD v
 }
 BOOL MethodContext::repCanInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls)
 {
-    AssertCodeMsg(CanInlineTypeCheckWithObjectVTable != nullptr, EXCEPTIONCODE_MC, "No map for CanInlineTypeCheckWithObjectVTable");
+    AssertCodeMsg(CanInlineTypeCheckWithObjectVTable != nullptr, EXCEPTIONCODE_MC,
+                  "No map for CanInlineTypeCheckWithObjectVTable");
     return (BOOL)CanInlineTypeCheckWithObjectVTable->Get((DWORDLONG)cls);
 }
 
index ac7acf1..739c1b2 100644 (file)
@@ -805,9 +805,9 @@ public:
     void dmpConstructStringLiteral(DLD key, DLD value);
     InfoAccessType repConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue);
 
-    void recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert, bool result);
+    void recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert, bool result);
     void dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value);
-    bool repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert);
+    bool repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert);
 
     void recEmptyStringLiteral(void** ppValue, InfoAccessType result);
     void dmpEmptyStringLiteral(DWORD key, DLD value);
index beadcff..a978fa2 100644 (file)
@@ -83,26 +83,26 @@ MethodContextReader::MethodContextReader(
 {
     this->mutex = CreateMutexA(NULL, FALSE, nullptr);
 
-    std::string tocFileName, mchFile;
+    std::string tocFileName, mchFileName;
 
     // First, check to see if they passed an MCH file (look for a paired MCT file)
     tocFileName = MethodContextReader::CheckForPairedFile(inputFileName, ".mch", ".mct");
     if (!tocFileName.empty())
     {
-        mchFile = inputFileName;
+        mchFileName = inputFileName;
     }
     else
     {
         // Okay, it wasn't an MCH file, let's check to see if it was an MCT file
         // so check for a paired MCH file instead
-        mchFile = MethodContextReader::CheckForPairedFile(inputFileName, ".mct", ".mch");
-        if (!mchFile.empty())
+        mchFileName = MethodContextReader::CheckForPairedFile(inputFileName, ".mct", ".mch");
+        if (!mchFileName.empty())
         {
             tocFileName = inputFileName;
         }
         else
         {
-            mchFile = inputFileName;
+            mchFileName = inputFileName;
         }
     }
 
@@ -110,8 +110,8 @@ MethodContextReader::MethodContextReader(
         this->tocFile.LoadToc(tocFileName.c_str());
 
     // we'll get here even if we don't have a valid index file
-    this->fileHandle = OpenFile(mchFile.c_str(), (this->hasTOC() && this->hasIndex()) ? FILE_ATTRIBUTE_NORMAL
-                                                                                      : FILE_FLAG_SEQUENTIAL_SCAN);
+    this->fileHandle = OpenFile(mchFileName.c_str(), (this->hasTOC() && this->hasIndex()) ? FILE_ATTRIBUTE_NORMAL
+                                                                                          : FILE_FLAG_SEQUENTIAL_SCAN);
     if (this->fileHandle != INVALID_HANDLE_VALUE)
     {
         GetFileSizeEx(this->fileHandle, (PLARGE_INTEGER) & this->fileSize);
index e9ee451..ab1c693 100644 (file)
@@ -135,6 +135,13 @@ public:
     {
         return curMCIndex;
     }
+
+    // Return should this method context be excluded from the replay or not.
+    bool IsMethodExcluded(MethodContext* mc)
+    {
+        // Right now it is just a stub.
+        return false;
+    }
 };
 #pragma pack(pop)
 
index 5d70a54..32cc072 100644 (file)
@@ -1825,7 +1825,7 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
     return temp;
 }
 
-bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert)
 {
     mc->cr->AddCall("convertPInvokeCalliToCall");
     bool result = original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
index 316fd8c..8a3e80c 100644 (file)
@@ -1412,7 +1412,7 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
     return original_ICorJitInfo->constructStringLiteral(module, metaTok, ppValue);
 }
 
-bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert)
 {
     mcs->AddCall("convertPInvokeCalliToCall");
     return original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
index 97c4347..90b2fdb 100644 (file)
@@ -1266,7 +1266,7 @@ InfoAccessType interceptor_ICJI::constructStringLiteral(CORINFO_MODULE_HANDLE mo
     return original_ICorJitInfo->constructStringLiteral(module, metaTok, ppValue);
 }
 
-bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+bool interceptor_ICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert)
 {
     return original_ICorJitInfo->convertPInvokeCalliToCall(pResolvedToken, fMustConvert);
 }
index 43ac5a8..31be088 100644 (file)
@@ -1580,7 +1580,7 @@ void* MyICJI::getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTail
     return jitInstance->mc->repGetTailCallCopyArgsThunk(pSig, flags);
 }
 
-bool MyICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert)
+bool MyICJI::convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert)
 {
     jitInstance->mc->cr->AddCall("convertPInvokeCalliToCall");
     return jitInstance->mc->repConvertPInvokeCalliToCall(pResolvedToken, fMustConvert);
index 70afb5c..f58ec66 100644 (file)
@@ -195,6 +195,7 @@ void ProcessChildStdOut(const CommandLine::Options& o,
                         int*                        loaded,
                         int*                        jitted,
                         int*                        failed,
+                        int*                        excluded,
                         int*                        diffs,
                         bool*                       usageError)
 {
@@ -238,44 +239,42 @@ void ProcessChildStdOut(const CommandLine::Options& o,
         }
         else if (strncmp(buff, g_AllFormatStringFixedPrefix, strlen(g_AllFormatStringFixedPrefix)) == 0)
         {
+            int childLoaded = 0, childJitted = 0, childFailed = 0, childExcluded = 0;
             if (o.applyDiff)
             {
-                int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
-                int converted = sscanf_s(buff, g_AsmDiffsSummaryFormatString, &temp1, &temp2, &temp3, &temp4);
-                if (converted != 4)
+                int childDiffs = 0;
+                int converted  = sscanf_s(buff, g_AsmDiffsSummaryFormatString, &childLoaded, &childJitted, &childFailed,
+                                         &childExcluded, &childDiffs);
+                if (converted != 5)
                 {
                     LogError("Couldn't parse status message: \"%s\"", buff);
+                    continue;
                 }
-                else
-                {
-                    *loaded += temp1;
-                    *jitted += temp2;
-                    *failed += temp3;
-                    *diffs += temp4;
-                }
+                *diffs += childDiffs;
             }
             else
             {
-                int temp1 = 0, temp2 = 0, temp3 = 0;
-                int converted = sscanf_s(buff, g_SummaryFormatString, &temp1, &temp2, &temp3);
-                if (converted != 3)
+                int converted =
+                    sscanf_s(buff, g_SummaryFormatString, &childLoaded, &childJitted, &childFailed, &childExcluded);
+                if (converted != 4)
                 {
                     LogError("Couldn't parse status message: \"%s\"", buff);
+                    continue;
                 }
-                else
-                {
-                    *loaded += temp1;
-                    *jitted += temp2;
-                    *failed += temp3;
-                    *diffs = -1;
-                }
+                *diffs = -1;
             }
+            *loaded += childLoaded;
+            *jitted += childJitted;
+            *failed += childFailed;
+            *excluded += childExcluded;
         }
     }
 
 Cleanup:
     if (fp != NULL)
+    {
         fclose(fp);
+    }
 }
 
 #ifndef FEATURE_PAL // TODO-Porting: handle Ctrl-C signals gracefully on Unix
@@ -604,14 +603,14 @@ int doParallelSuperPMI(CommandLine::Options& o)
 
         bool usageError = false; // variable to flag if we hit a usage error in SuperPMI
 
-        int loaded = 0, jitted = 0, failed = 0, diffs = 0;
+        int loaded = 0, jitted = 0, failed = 0, excluded = 0, diffs = 0;
 
         // Read the stderr files and log them as errors
         // Read the stdout files and parse them for counts and log any MISSING or ISSUE errors
         for (int i = 0; i < o.workerCount; i++)
         {
             ProcessChildStdErr(arrStdErrorPath[i]);
-            ProcessChildStdOut(o, arrStdOutputPath[i], &loaded, &jitted, &failed, &diffs, &usageError);
+            ProcessChildStdOut(o, arrStdOutputPath[i], &loaded, &jitted, &failed, &excluded, &diffs, &usageError);
             if (usageError)
                 break;
         }
index be5476e..5e80854 100644 (file)
@@ -26,8 +26,8 @@ extern int doParallelSuperPMI(CommandLine::Options& o);
 // There must be a single, fixed prefix common to all strings, to ease the determination of when
 // to parse the string fully.
 const char* const g_AllFormatStringFixedPrefix  = "Loaded ";
-const char* const g_SummaryFormatString         = "Loaded %d  Jitted %d  FailedCompile %d";
-const char* const g_AsmDiffsSummaryFormatString = "Loaded %d  Jitted %d  FailedCompile %d  Diffs %d";
+const char* const g_SummaryFormatString         = "Loaded %d  Jitted %d  FailedCompile %d Excluded %d";
+const char* const g_AsmDiffsSummaryFormatString = "Loaded %d  Jitted %d  FailedCompile %d Excluded %d Diffs %d";
 
 //#define SuperPMI_ChewMemory 0x7FFFFFFF //Amount of address space to consume on startup
 
@@ -238,6 +238,7 @@ int __cdecl main(int argc, char* argv[])
     int errorCount        = 0;
     int missingCount      = 0;
     int index             = 0;
+    int excludedCount     = 0;
 
     st1.Start();
     NearDiffer nearDiffer(o.targetArchitecture, o.useCoreDisTools);
@@ -284,7 +285,17 @@ int __cdecl main(int argc, char* argv[])
 
         loadedCount++;
         if (!MethodContext::Initialize(loadedCount, mcb.buff, mcb.size, &mc))
+        {
             return (int)SpmiResult::GeneralFailure;
+        }
+
+        if (reader->IsMethodExcluded(mc))
+        {
+            excludedCount++;
+            LogInfo("main method %d of size %d with was excluded from the compilation.",
+                    reader->GetMethodContextIndex(), mc->methodSize);
+            continue;
+        }
 
         if (jit == nullptr)
         {
@@ -552,12 +563,12 @@ int __cdecl main(int argc, char* argv[])
     // NOTE: these output status strings are parsed by parallelsuperpmi.cpp::ProcessChildStdOut().
     if (o.applyDiff)
     {
-        LogInfo(g_AsmDiffsSummaryFormatString, loadedCount, jittedCount, failToReplayCount,
+        LogInfo(g_AsmDiffsSummaryFormatString, loadedCount, jittedCount, failToReplayCount, excludedCount,
                 jittedCount - failToReplayCount - matchCount);
     }
     else
     {
-        LogInfo(g_SummaryFormatString, loadedCount, jittedCount, failToReplayCount);
+        LogInfo(g_SummaryFormatString, loadedCount, jittedCount, failToReplayCount, excludedCount);
     }
 
     st2.Stop();