Make pointer tracking array facility fail gracefully when it is full (#411)

This commit is contained in:
Jon Haslam 2023-11-15 16:13:54 +00:00 committed by GitHub
parent f9cb0115e1
commit 02306bf80e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 7 deletions

View File

@ -327,6 +327,8 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
uintptr_t& writtenSize = data[dataSegOffset++]; uintptr_t& writtenSize = data[dataSegOffset++];
writtenSize = 0; writtenSize = 0;
uintptr_t& timeTakenNs = data[dataSegOffset++]; uintptr_t& timeTakenNs = data[dataSegOffset++];
size_t& pointersSize = data[dataSegOffset++];
size_t& pointersCapacity = data[dataSegOffset++];
dataSegOffset *= sizeof(uintptr_t); dataSegOffset *= sizeof(uintptr_t);
JLOG("%1% @"); JLOG("%1% @");
@ -336,6 +338,8 @@ void FuncGen::DefineTopLevelGetSizeRef(std::string& testCode,
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset); OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
writtenSize = dataSegOffset; writtenSize = dataSegOffset;
dataBase += dataSegOffset; dataBase += dataSegOffset;
pointersSize = pointers.size();
pointersCapacity = pointers.capacity();
)"; )";
if (features[Feature::JitTiming]) { if (features[Feature::JitTiming]) {
func += R"( func += R"(
@ -419,6 +423,8 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
uintptr_t& writtenSize = data[dataSegOffset++]; uintptr_t& writtenSize = data[dataSegOffset++];
writtenSize = 0; writtenSize = 0;
uintptr_t& timeTakenNs = data[dataSegOffset++]; uintptr_t& timeTakenNs = data[dataSegOffset++];
size_t& pointersSize = data[dataSegOffset++];
size_t& pointersCapacity = data[dataSegOffset++];
dataSegOffset *= sizeof(uintptr_t); dataSegOffset *= sizeof(uintptr_t);
@ -427,6 +433,8 @@ void FuncGen::DefineTopLevelGetSizeSmartPtr(std::string& testCode,
OIInternal::StoreData((uintptr_t)123456789, dataSegOffset); OIInternal::StoreData((uintptr_t)123456789, dataSegOffset);
writtenSize = dataSegOffset; writtenSize = dataSegOffset;
dataBase += dataSegOffset; dataBase += dataSegOffset;
pointersSize = pointers.size();
pointersCapacity = pointers.capacity();
)"; )";
if (features[Feature::JitTiming]) { if (features[Feature::JitTiming]) {
func += R"( func += R"(

View File

@ -2746,6 +2746,14 @@ bool OIDebugger::decodeTargetData(const DataHeader& dataHeader,
LOG(INFO) << "JIT Timing: " << dataHeader.timeTakenNs << "ns"; LOG(INFO) << "JIT Timing: " << dataHeader.timeTakenNs << "ns";
} }
VLOG(1) << "Pointer tracking stats: " << dataHeader.pointersCapacity << "/"
<< dataHeader.pointersSize;
if (dataHeader.pointersCapacity == dataHeader.pointersSize) {
VLOG(1) << "Pointer tracking array is exhausted! Results may be"
" partial.";
}
/* /*
* Currently we use MAX_INT to indicate two things: * Currently we use MAX_INT to indicate two things:
* - a single MAX_INT indicates the end of results for the current object * - a single MAX_INT indicates the end of results for the current object

View File

@ -276,6 +276,8 @@ class OIDebugger {
uintptr_t cookie; uintptr_t cookie;
uintptr_t size; uintptr_t size;
uintptr_t timeTakenNs; uintptr_t timeTakenNs;
size_t pointersSize;
size_t pointersCapacity;
/* /*
* Flexible Array Member are not standard in C++, but this is * Flexible Array Member are not standard in C++, but this is

View File

@ -44,9 +44,12 @@ class {
private: private:
// 1 MiB of pointers // 1 MiB of pointers
std::array<uintptr_t, (1 << 20) / sizeof(uintptr_t)> data; std::array<uintptr_t, (1 << 20) / sizeof(uintptr_t)> data;
size_t numEntries;
// twang_mix64 hash function, taken from Folly where it is used /*
// as the default hash function for 64-bit integers * twang_mix64 hash function, taken from Folly where it is used as the
* default hash function for 64-bit integers.
*/
constexpr static uint64_t twang_mix64(uint64_t key) noexcept { constexpr static uint64_t twang_mix64(uint64_t key) noexcept {
key = (~key) + (key << 21); // key *= (1 << 21) - 1; key -= 1; key = (~key) + (key << 21); // key *= (1 << 21) - 1; key -= 1;
key = key ^ (key >> 24); key = key ^ (key >> 24);
@ -61,26 +64,46 @@ class {
public: public:
void initialize() noexcept { void initialize() noexcept {
data.fill(0); data.fill(0);
numEntries = 0;
} }
// Adds the pointer to the set. /*
// Returns `true` if the value was newly added, * Adds the pointer to the set.
// or `false` if the value was already present. * Returns `true` if the value was newly added. `false` may be returned if
* the value was already present, a null pointer was passed or if there are
* no entries left in the array.
*/
bool add(uintptr_t pointer) noexcept { bool add(uintptr_t pointer) noexcept {
__builtin_assume(pointer > 0); if (pointer == 0) {
return false;
}
uint64_t index = twang_mix64(pointer) % data.size(); uint64_t index = twang_mix64(pointer) % data.size();
while (true) { while (true) {
uintptr_t entry = data[index]; uintptr_t entry = data[index];
if (entry == 0) { if (entry == 0) {
data[index] = pointer; data[index] = pointer;
++numEntries;
return true; return true;
} }
if (entry == pointer) {
if (entry == pointer || numEntries >= data.size()) {
return false; return false;
} }
index = (index + 1) % data.size(); index = (index + 1) % data.size();
} }
} }
size_t size(void) {
return numEntries;
}
size_t capacity(void) {
return data.size();
}
bool add(const auto* p) { bool add(const auto* p) {
return add((uintptr_t)p); return add((uintptr_t)p);
} }