Valgrind annotations for new free list
This commit is contained in:
@@ -700,8 +700,6 @@ constexpr int64_t kMaxFreeListBytes = 1 << 20;
|
|||||||
// doesn't meet the capacity constraints, it's freed and a new node is allocated
|
// doesn't meet the capacity constraints, it's freed and a new node is allocated
|
||||||
// with the minimum capacity. The hope is that "unfit" nodes don't get stuck in
|
// with the minimum capacity. The hope is that "unfit" nodes don't get stuck in
|
||||||
// the free list.
|
// the free list.
|
||||||
//
|
|
||||||
// TODO valgrind annotations
|
|
||||||
template <class T> struct NodeAllocator {
|
template <class T> struct NodeAllocator {
|
||||||
|
|
||||||
static_assert(std::derived_from<T, Node>);
|
static_assert(std::derived_from<T, Node>);
|
||||||
@@ -738,6 +736,7 @@ template <class T> struct NodeAllocator {
|
|||||||
p->parent = freeList;
|
p->parent = freeList;
|
||||||
freeList = p;
|
freeList = p;
|
||||||
freeListSize += sizeof(T) + p->partialKeyCapacity;
|
freeListSize += sizeof(T) + p->partialKeyCapacity;
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(p, sizeof(T) + p->partialKeyCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deferRelease(T *p, Node *forwardTo) {
|
void deferRelease(T *p, Node *forwardTo) {
|
||||||
@@ -759,6 +758,13 @@ template <class T> struct NodeAllocator {
|
|||||||
void releaseDeferred() {
|
void releaseDeferred() {
|
||||||
if (deferredList != nullptr) {
|
if (deferredList != nullptr) {
|
||||||
deferredListFront->parent = freeList;
|
deferredListFront->parent = freeList;
|
||||||
|
#ifndef NVALGRIND
|
||||||
|
for (auto *iter = deferredList; iter != freeList;) {
|
||||||
|
auto *tmp = iter;
|
||||||
|
iter = (T *)iter->parent;
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(tmp, sizeof(T) + tmp->partialKeyCapacity);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
freeList = std::exchange(deferredList, nullptr);
|
freeList = std::exchange(deferredList, nullptr);
|
||||||
}
|
}
|
||||||
for (T *n = std::exchange(deferredListOverflow, nullptr); n != nullptr;) {
|
for (T *n = std::exchange(deferredListOverflow, nullptr); n != nullptr;) {
|
||||||
@@ -779,6 +785,7 @@ template <class T> struct NodeAllocator {
|
|||||||
assert(deferredList == nullptr);
|
assert(deferredList == nullptr);
|
||||||
assert(deferredListOverflow == nullptr);
|
assert(deferredListOverflow == nullptr);
|
||||||
for (T *iter = freeList; iter != nullptr;) {
|
for (T *iter = freeList; iter != nullptr;) {
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(iter, sizeof(T));
|
||||||
auto *tmp = iter;
|
auto *tmp = iter;
|
||||||
iter = (T *)iter->parent;
|
iter = (T *)iter->parent;
|
||||||
removeNode(tmp);
|
removeNode(tmp);
|
||||||
@@ -796,6 +803,7 @@ private:
|
|||||||
|
|
||||||
T *allocate_helper(int minCapacity, int maxCapacity) {
|
T *allocate_helper(int minCapacity, int maxCapacity) {
|
||||||
if (freeList != nullptr) {
|
if (freeList != nullptr) {
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(freeList, sizeof(T));
|
||||||
freeListSize -= sizeof(T) + freeList->partialKeyCapacity;
|
freeListSize -= sizeof(T) + freeList->partialKeyCapacity;
|
||||||
assume(freeList->partialKeyCapacity >= 0);
|
assume(freeList->partialKeyCapacity >= 0);
|
||||||
assume(minCapacity >= 0);
|
assume(minCapacity >= 0);
|
||||||
@@ -804,6 +812,11 @@ private:
|
|||||||
freeList->partialKeyCapacity <= maxCapacity) {
|
freeList->partialKeyCapacity <= maxCapacity) {
|
||||||
auto *result = freeList;
|
auto *result = freeList;
|
||||||
freeList = (T *)freeList->parent;
|
freeList = (T *)freeList->parent;
|
||||||
|
VALGRIND_MAKE_MEM_UNDEFINED(result,
|
||||||
|
sizeof(T) + result->partialKeyCapacity);
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(&result->partialKeyCapacity,
|
||||||
|
sizeof(result->partialKeyCapacity));
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(&result->type, sizeof(result->type));
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
auto *p = freeList;
|
auto *p = freeList;
|
||||||
|
Reference in New Issue
Block a user