Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
spmi: exclude methods using a file with saved md5 hashes. (#18769)
Browse files Browse the repository at this point in the history
* read md5, linear search for each method.

* rewrite with HANDLE

* fix linux

* do not waste time dumping md5 if no methods exluded
  • Loading branch information
Sergey Andreenko authored Jul 28, 2018
1 parent 6510cdc commit 6227652
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 5 deletions.
107 changes: 107 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ MethodContextReader::MethodContextReader(
{
GetFileSizeEx(this->fileHandle, (PLARGE_INTEGER) & this->fileSize);
}

ReadExcludedMethods(mchFileName);
}

MethodContextReader::~MethodContextReader()
Expand All @@ -130,6 +132,8 @@ MethodContextReader::~MethodContextReader()
}

CloseHandle(this->mutex);

CleanExcludedMethods();
}

bool MethodContextReader::AcquireLock()
Expand Down Expand Up @@ -477,3 +481,106 @@ MethodContextBuffer MethodContextReader::GetSpecificMethodContext(unsigned int m
return MethodContextBuffer(-4);
}
}

// Read the file with excluded methods hashes and save them.
void MethodContextReader::ReadExcludedMethods(std::string mchFileName)
{
excludedMethodsList = nullptr;

size_t suffix_offset = mchFileName.find_last_of('.');
if (suffix_offset == std::string::npos)
{
LogError("Failed to get file extension from %s", mchFileName.c_str());
return;
}
std::string suffix = mchFileName.substr(suffix_offset);
std::string excludeFileName = MethodContextReader::CheckForPairedFile(mchFileName, suffix.c_str(), ".exc");

if (excludeFileName.empty())
{
return;
}
HANDLE excludeFileHandle = OpenFile(excludeFileName.c_str());
if (excludeFileHandle != INVALID_HANDLE_VALUE)
{
__int64 excludeFileSizeLong;
GetFileSizeEx(excludeFileHandle, (PLARGE_INTEGER)&excludeFileSizeLong);
unsigned excludeFileSize = (unsigned)excludeFileSizeLong;

char* buffer = new char[excludeFileSize + 1];
DWORD bytesRead;
bool success = (ReadFile(excludeFileHandle, buffer, excludeFileSize, &bytesRead, NULL) == TRUE);
CloseHandle(excludeFileHandle);

if (!success || excludeFileSize != bytesRead)
{
LogError("Failed to read the exclude file.");
delete[] buffer;
return;
}

buffer[excludeFileSize] = 0;

int counter = 0;

char* curr = buffer;
while (*curr != 0)
{
while (isspace(*curr))
{
curr++;
}

std::string hash;
while (*curr != 0 && !isspace(*curr))
{
hash += *curr;
curr++;
}

if (hash.length() == MD5_HASH_BUFFER_SIZE - 1)
{
StringList* node = new StringList();
node->hash = hash;
node->next = excludedMethodsList;
excludedMethodsList = node;
counter++;
}
else
{
LogInfo("The exclude file contains wrong values: %s.", hash.c_str());
}
}
delete[] buffer;
LogInfo("Exclude file %s contains %d methods.", excludeFileName.c_str(), counter);
}
}

// Free memory used for excluded methods.
void MethodContextReader::CleanExcludedMethods()
{
while (excludedMethodsList != nullptr)
{
StringList* next = excludedMethodsList->next;
delete excludedMethodsList;
excludedMethodsList = next;
}
}

// Return should this method context be excluded from the replay or not.
bool MethodContextReader::IsMethodExcluded(MethodContext* mc)
{
if (excludedMethodsList != nullptr)
{
char md5HashBuf[MD5_HASH_BUFFER_SIZE] = {0};
mc->dumpMethodMD5HashToBuffer(md5HashBuf, MD5_HASH_BUFFER_SIZE);
for (StringList* node = excludedMethodsList; node != nullptr; node = node->next)
{
if (strcmp(node->hash.c_str(), md5HashBuf) == 0)
{
return true;
}
}
}
return false;
}
16 changes: 11 additions & 5 deletions src/ToolBox/superpmi/superpmi-shared/methodcontextreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ class MethodContextReader
int Offset;
int Increment;

struct StringList
{
StringList* next;
std::string hash;
};
StringList* excludedMethodsList;

// Binary search to get this method number from the index
// Returns -1 for not found, or -2 for not indexed
__int64 GetOffset(unsigned int methodNumber);
Expand Down Expand Up @@ -114,6 +121,9 @@ class MethodContextReader
// Do we have a valid index?
bool hasIndex();

void ReadExcludedMethods(std::string mchFileName);
void CleanExcludedMethods();

public:
MethodContextReader(const char* inputFileName,
const int* indexes = nullptr,
Expand All @@ -137,11 +147,7 @@ class MethodContextReader
}

// 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;
}
bool IsMethodExcluded(MethodContext* mc);
};
#pragma pack(pop)

Expand Down
13 changes: 13 additions & 0 deletions src/inc/clr_std/string
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ public:
return (*this);
}

basic_string<T>& operator+=(value_type _Ch)
{
size_type oldsize = size(); // doesn't include null terminator
m_string[oldsize] = _Ch; // Replace the null terminator with the new symbol.
m_string.push_back(T()); // Return the replaced terminator again.
return (*this);
}

~basic_string()
{
// vector destructor does all the work
Expand All @@ -157,6 +165,11 @@ public:
return m_string.size() - 1; // Don't report the null terminator.
}

size_t length() const
{
return size();
}

T& operator[](size_t iIndex)
{
assert(iIndex < size() + 1); // allow looking at the null terminator
Expand Down

0 comments on commit 6227652

Please sign in to comment.