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 cd2ead06327e8677c5598b1fe14f3ab328a819e3..64d5fa435b715f3de6eeb01cff9ad614329c4d4b 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 b5de52feaf1e5735595a9f91c19cf888986a2a69..97be26fc8d82d9c92c8eae1c166a044e1960b0e0 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 ac7acf1ea15434920388635ecbc688ee5c852fc7..739c1b2c024155f233772d77ab706043b25bee7f 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 beadcffc25126fd79607f878665019231ef02f8d..a978fa2c2e3896c9d27661ff83449b8baa30e84f 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 e9ee45111546d16c24e930636fe07ae31eff9cbe..ab1c693219934794c521c87e3ba4c2028e691fb3 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 5d70a5488f55af2f73656aa2687209ecae961697..32cc072d683ce7d72e87f1673978577169b9b8bd 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 316fd8c1edee23b2c03561782c7b778896a3a97b..8a3e80ca4c1cb879e113edb63c4630a1c15158f6 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 97c434755e73ac35a2459e8f6ba381d35abcacb2..90b2fdb6287613af7ad7e3b1ec891afb3cbd05ee 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 43ac5a8502a895eb35fd08a72c9763ca76180b22..31be0883aaefab4f806e41086f7ec53aacf02407 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 70afb5ce20e0beb8a1c1f00da79e9124f568832d..f58ec663808ad41a33d971b67cb1be004298c26a 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 be5476e8c38fbe03b3f4c4cf4b0a4bc97efb16a5..5e80854fa86589af80498044c683a46aa3cbacc2 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();