mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
Make pointer tracking array facility fail gracefully when it is full (#411)
This commit is contained in:
parent
f9cb0115e1
commit
02306bf80e
@ -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"(
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user