Skip to content

Commit

Permalink
[BOLT][Instrumentation] Add dumping function to instrumentation hash …
Browse files Browse the repository at this point in the history
…tables

Since there are no other means to debug the instrumentation library
other than using stdout, having a function to print hash table entries
is very useful.

Reviewed By: rafauler, Amir
Differential Revision: https://reviews.llvm.org/D153771
  • Loading branch information
treapster committed Jun 29, 2023
1 parent f6682ad commit 47934c1
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 10 deletions.
25 changes: 15 additions & 10 deletions bolt/runtime/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@ uint64_t __sigprocmask(int how, const void *set, void *oldset) {
return ret;
}

uint64_t __getpid() {
uint64_t ret;
#if defined(__APPLE__)
#define GETPID_SYSCALL 20
#else
#define GETPID_SYSCALL 39
#endif
__asm__ __volatile__("movq $" STRINGIFY(GETPID_SYSCALL) ", %%rax\n"
"syscall\n"
: "=a"(ret)
:
: "cc", "rcx", "r11", "memory");
return ret;
}

uint64_t __exit(uint64_t code) {
#if defined(__APPLE__)
#define EXIT_SYSCALL 0x2000001
Expand Down Expand Up @@ -509,16 +524,6 @@ int __mprotect(void *addr, size_t len, int prot) {
return ret;
}

uint64_t __getpid() {
uint64_t ret;
__asm__ __volatile__("movq $39, %%rax\n"
"syscall\n"
: "=a"(ret)
:
: "cc", "rcx", "r11", "memory");
return ret;
}

uint64_t __getppid() {
uint64_t ret;
__asm__ __volatile__("movq $110, %%rax\n"
Expand Down
42 changes: 42 additions & 0 deletions bolt/runtime/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,37 @@ extern "C" bool __bolt_instr_conservative;
struct SimpleHashTableEntryBase {
uint64_t Key;
uint64_t Val;
void dump(const char *Msg = nullptr) {
// TODO: make some sort of formatting function
// Currently we have to do it the ugly way because
// we want every message to be printed atomically via a single call to
// __write. If we use reportNumber() and others nultiple times, we'll get
// garbage in mulithreaded environment
char Buf[BufSize];
char *Ptr = Buf;
Ptr = intToStr(Ptr, __getpid(), 10);
*Ptr++ = ':';
*Ptr++ = ' ';
if (Msg)
Ptr = strCopy(Ptr, Msg, strLen(Msg));
*Ptr++ = '0';
*Ptr++ = 'x';
Ptr = intToStr(Ptr, (uint64_t)this, 16);
*Ptr++ = ':';
*Ptr++ = ' ';
Ptr = strCopy(Ptr, "MapEntry(0x", sizeof("MapEntry(0x") - 1);
Ptr = intToStr(Ptr, Key, 16);
*Ptr++ = ',';
*Ptr++ = ' ';
*Ptr++ = '0';
*Ptr++ = 'x';
Ptr = intToStr(Ptr, Val, 16);
*Ptr++ = ')';
*Ptr++ = '\n';
assert(Ptr - Buf < BufSize, "Buffer overflow!");
// print everything all at once for atomicity
__write(2, Buf, Ptr - Buf);
}
};

/// This hash table implementation starts by allocating a table of size
Expand Down Expand Up @@ -341,24 +372,28 @@ class SimpleHashTable {
TableRoot = new (Alloc, 0) MapEntry[InitialSize];
MapEntry &Entry = TableRoot[Key % InitialSize];
Entry.Key = Key;
// DEBUG(Entry.dump("Created root entry: "));
return Entry;
}

MapEntry &getEntry(MapEntry *Entries, uint64_t Key, uint64_t Selector,
BumpPtrAllocator &Alloc, int CurLevel) {
// DEBUG(reportNumber("getEntry called, level ", CurLevel, 10));
const uint32_t NumEntries = CurLevel == 0 ? InitialSize : IncSize;
uint64_t Remainder = Selector / NumEntries;
Selector = Selector % NumEntries;
MapEntry &Entry = Entries[Selector];

// A hit
if (Entry.Key == Key) {
// DEBUG(Entry.dump("Hit: "));
return Entry;
}

// Vacant - add new entry
if (Entry.Key == VacantMarker) {
Entry.Key = Key;
// DEBUG(Entry.dump("Adding new entry: "));
return Entry;
}

Expand All @@ -370,7 +405,12 @@ class SimpleHashTable {
}

// Conflict - create the next level
// DEBUG(Entry.dump("Creating new level: "));

MapEntry *NextLevelTbl = new (Alloc, 0) MapEntry[IncSize];
// DEBUG(
// reportNumber("Newly allocated level: 0x", uint64_t(NextLevelTbl),
// 16));
uint64_t CurEntrySelector = Entry.Key / InitialSize;
for (int I = 0; I < CurLevel; ++I)
CurEntrySelector /= IncSize;
Expand All @@ -380,6 +420,8 @@ class SimpleHashTable {
assert((NextLevelTbl[CurEntrySelector].Key & ~FollowUpTableMarker) !=
uint64_t(Entries),
"circular reference created!\n");
// DEBUG(NextLevelTbl[CurEntrySelector].dump("New level entry: "));
// DEBUG(Entry.dump("Updated old entry: "));
return getEntry(NextLevelTbl, Key, Remainder, Alloc, CurLevel + 1);
}

Expand Down

0 comments on commit 47934c1

Please sign in to comment.