#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;
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>();
{
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
}
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);
}
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);
{
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;
}
}
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);
{
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)
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);
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);
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);
}
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);
int* loaded,
int* jitted,
int* failed,
+ int* excluded,
int* diffs,
bool* usageError)
{
}
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
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;
}
// 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
int errorCount = 0;
int missingCount = 0;
int index = 0;
+ int excludedCount = 0;
st1.Start();
NearDiffer nearDiffer(o.targetArchitecture, o.useCoreDisTools);
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)
{
// 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();