Track malloc size with a header for SHOW_MEMORY
This commit is contained in:
@@ -2819,6 +2819,7 @@ void removeKey(Node *n) {
|
|||||||
|
|
||||||
struct __attribute__((visibility("default"))) PeakPrinter {
|
struct __attribute__((visibility("default"))) PeakPrinter {
|
||||||
~PeakPrinter() {
|
~PeakPrinter() {
|
||||||
|
printf("malloc bytes: %g\n", double(mallocBytes));
|
||||||
printf("Peak malloc bytes: %g\n", double(peakMallocBytes));
|
printf("Peak malloc bytes: %g\n", double(peakMallocBytes));
|
||||||
printf("Node bytes: %g\n", double(nodeBytes));
|
printf("Node bytes: %g\n", double(nodeBytes));
|
||||||
printf("Peak node bytes: %g\n", double(peakNodeBytes));
|
printf("Peak node bytes: %g\n", double(peakNodeBytes));
|
||||||
|
@@ -102,7 +102,7 @@ ConflictSet::ConflictSet(int64_t oldestVersion)
|
|||||||
ConflictSet::~ConflictSet() {
|
ConflictSet::~ConflictSet() {
|
||||||
if (impl) {
|
if (impl) {
|
||||||
impl->~Impl();
|
impl->~Impl();
|
||||||
free(impl);
|
safe_free(impl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +142,6 @@ ConflictSet_create(int64_t oldestVersion) {
|
|||||||
__attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) {
|
__attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) {
|
||||||
using Impl = ConflictSet::Impl;
|
using Impl = ConflictSet::Impl;
|
||||||
((Impl *)cs)->~Impl();
|
((Impl *)cs)->~Impl();
|
||||||
free(cs);
|
safe_free(cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
Internal.h
46
Internal.h
@@ -41,45 +41,47 @@ operator<=>(const std::span<const uint8_t> &lhs,
|
|||||||
// GCOVR_EXCL_START
|
// GCOVR_EXCL_START
|
||||||
|
|
||||||
#if SHOW_MEMORY
|
#if SHOW_MEMORY
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <malloc/malloc.h>
|
|
||||||
#else
|
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
inline int64_t mallocBytes = 0;
|
inline int64_t mallocBytes = 0;
|
||||||
inline int64_t peakMallocBytes = 0;
|
inline int64_t peakMallocBytes = 0;
|
||||||
|
constexpr auto kIntMallocHeaderSize = 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// malloc that aborts on OOM and thus always returns a non-null pointer
|
// malloc that aborts on OOM and thus always returns a non-null pointer. Must be
|
||||||
|
// paired with `safe_free`.
|
||||||
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
||||||
|
#if SHOW_MEMORY
|
||||||
|
mallocBytes += s;
|
||||||
|
if (mallocBytes > peakMallocBytes) {
|
||||||
|
peakMallocBytes = mallocBytes;
|
||||||
|
}
|
||||||
|
void *p = malloc(s + kIntMallocHeaderSize);
|
||||||
|
if (p == nullptr) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
memcpy(p, &s, sizeof(s));
|
||||||
|
return (char *)p + kIntMallocHeaderSize;
|
||||||
|
#else
|
||||||
void *p = malloc(s);
|
void *p = malloc(s);
|
||||||
if (p == nullptr) {
|
if (p == nullptr) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#if SHOW_MEMORY
|
|
||||||
#ifdef __APPLE__
|
|
||||||
mallocBytes += s;
|
|
||||||
#else
|
|
||||||
mallocBytes += malloc_usable_size(p);
|
|
||||||
#endif
|
|
||||||
if (mallocBytes > peakMallocBytes) {
|
|
||||||
peakMallocBytes = mallocBytes;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return p;
|
return p;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be paired with `safe_malloc`.
|
||||||
|
//
|
||||||
// There's nothing safer about this than free. Only called safe_free for
|
// There's nothing safer about this than free. Only called safe_free for
|
||||||
// symmetry with safe_malloc.
|
// symmetry with safe_malloc.
|
||||||
__attribute__((always_inline)) inline void safe_free(void *p) {
|
__attribute__((always_inline)) inline void safe_free(void *p) {
|
||||||
#if SHOW_MEMORY
|
#if SHOW_MEMORY
|
||||||
#ifdef __APPLE__
|
size_t s;
|
||||||
mallocBytes -= malloc_size(p);
|
memcpy(&s, (char *)p - kIntMallocHeaderSize, sizeof(s));
|
||||||
|
mallocBytes -= s;
|
||||||
|
free((char *)p - kIntMallocHeaderSize);
|
||||||
#else
|
#else
|
||||||
mallocBytes -= malloc_usable_size(p);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
free(p);
|
free(p);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== BEGIN ARENA IMPL ====================
|
// ==================== BEGIN ARENA IMPL ====================
|
||||||
@@ -164,7 +166,7 @@ inline Arena::Arena(int initialSize) : impl(nullptr) {
|
|||||||
inline void onDestroy(Arena::ArenaImpl *impl) {
|
inline void onDestroy(Arena::ArenaImpl *impl) {
|
||||||
while (impl) {
|
while (impl) {
|
||||||
auto *prev = impl->prev;
|
auto *prev = impl->prev;
|
||||||
free(impl);
|
safe_free(impl);
|
||||||
impl = prev;
|
impl = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -149,7 +149,7 @@ private:
|
|||||||
setMaxVersion(level, v);
|
setMaxVersion(level, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() { free(this); }
|
void destroy() { safe_free(this); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getNodeSize() const {
|
int getNodeSize() const {
|
||||||
@@ -655,7 +655,7 @@ ConflictSet::ConflictSet(int64_t oldestVersion)
|
|||||||
ConflictSet::~ConflictSet() {
|
ConflictSet::~ConflictSet() {
|
||||||
if (impl) {
|
if (impl) {
|
||||||
impl->~Impl();
|
impl->~Impl();
|
||||||
free(impl);
|
safe_free(impl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user