-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of a rootbench memory tracing library.
It implements a C library which records information about the memory allocations. The library is loaded using the LD_PRELOAD mechanism (and DYLD_INSERT_LIBRARIES for osx). GoogleBenchmark displays the memory allocation results are only in the json format. For instance: DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=./lib/Instrumentation/libRBInstrumentation.dylib ./root/interpreter/InterpreterLookupHelperBenchmarks --benchma rk_format=json: ... { "name": "BM_LookupHelper_Leak", "run_name": "BM_LookupHelper_Leak", "run_type": "iteration", "repetitions": 0, "repetition_index": 0, "threads": 1, "iterations": 1, "real_time": 1.3199219449888916e+09, "cpu_time": 8.0450300000000000e+08, "time_unit": "ns", "allocs_per_iter": 6.0000000000000000e+00, "max_bytes_used": 3368 }
- Loading branch information
1 parent
3aa236a
commit f21c2b5
Showing
11 changed files
with
255 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/// \file Memory.h | ||
/// | ||
/// The file contains interfaces of the C memory instrumentation library. | ||
/// | ||
/// \author Vassil Vassilev <[email protected]> | ||
/// | ||
/// \date Oct, 2020 | ||
/// | ||
|
||
#ifndef RB_MEMORY_H | ||
#define RB_MEMORY_H | ||
|
||
#include <stddef.h> | ||
|
||
struct malloc_stats { | ||
size_t num_malloc_calls; | ||
size_t max_bytes_used; | ||
}; | ||
|
||
void reset_malloc_stats(); | ||
const struct malloc_stats get_current_malloc_stats(); | ||
|
||
|
||
#endif // RB_MEMORY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/// \file MemoryManager.h | ||
/// | ||
/// The file contains the implementation of benchmark memory tracking. | ||
/// | ||
/// \author Vassil Vassilev <[email protected]> | ||
/// | ||
/// \date Oct, 2020 | ||
/// | ||
|
||
#ifndef RB_MEMORY_MANAGER_H | ||
#define RB_MEMORY_MANAGER_H | ||
|
||
#include "benchmark/benchmark.h" | ||
|
||
|
||
namespace RB { | ||
/// Records number of allocations per iteration and the maximum bites used | ||
/// for a benchmark. | ||
struct MemoryManager : public benchmark::MemoryManager { | ||
size_t cur_num_allocs = 0; | ||
size_t cur_max_bytes_used = 0; | ||
void Start() override; | ||
void Stop(Result* result) override; | ||
}; | ||
} // end RB | ||
|
||
namespace { | ||
static auto mm = std::unique_ptr<RB::MemoryManager>(new RB::MemoryManager()); | ||
static struct InstrumentationRegistrer { | ||
InstrumentationRegistrer() { | ||
benchmark::RegisterMemoryManager(mm.get()); | ||
} | ||
~InstrumentationRegistrer() { | ||
benchmark::RegisterMemoryManager(nullptr); | ||
} | ||
} __mem_mgr_register; | ||
} | ||
|
||
|
||
#endif // RB_MEMORY_MANAGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
#---Add the support libraries. | ||
add_subdirectory(Instrumentation) | ||
add_subdirectory(Support) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
RB_ADD_C_LIBRARY(RBInstrumentation SHARED | ||
Memory.c | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/// \file Memory.c | ||
/// | ||
/// The file contains code of the C memory instrumentation library. | ||
/// | ||
/// \author Vassil Vassilev <[email protected]> | ||
/// | ||
/// \date Oct, 2020 | ||
/// | ||
|
||
|
||
#include "rootbench/Instrumentation/Memory.h" | ||
|
||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <dlfcn.h> | ||
#undef _GNU_SOURCE | ||
|
||
static void* (*real_malloc)(size_t) = NULL; | ||
|
||
static void mtrace_init(void) { | ||
real_malloc = dlsym(RTLD_NEXT, "malloc"); | ||
if (!real_malloc) { | ||
fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); | ||
} | ||
} | ||
|
||
static struct malloc_stats cur_malloc_stats; | ||
void reset_malloc_stats() { | ||
cur_malloc_stats.num_malloc_calls = 0; | ||
cur_malloc_stats.max_bytes_used = 0; | ||
} | ||
|
||
const struct malloc_stats get_current_malloc_stats() { | ||
return cur_malloc_stats; | ||
} | ||
|
||
void *malloc(size_t size) { | ||
if(!real_malloc) | ||
mtrace_init(); | ||
|
||
void *p = NULL; | ||
p = real_malloc(size); | ||
cur_malloc_stats.num_malloc_calls++; | ||
cur_malloc_stats.max_bytes_used += size; | ||
|
||
return p; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
RB_ADD_LIBRARY(RBSupport | ||
ErrorHandling.cxx | ||
) | ||
MemoryManager.cxx | ||
) | ||
target_include_directories(RBSupport PUBLIC | ||
${PROJECT_BINARY_DIR}/include | ||
${PROJECT_SOURCE_DIR}/include | ||
${GBENCHMARK_INCLUDE_DIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/// \file MemoryManager.h | ||
/// | ||
/// The file contains interfaces for benchmark memory tracking. | ||
/// | ||
/// \author Vassil Vassilev <[email protected]> | ||
/// | ||
/// \date Oct, 2020 | ||
/// | ||
|
||
#include <rootbench/Support/MemoryManager.h> | ||
|
||
#include <rootbench/RBConfig.h> | ||
|
||
extern "C" { | ||
#include <rootbench/Instrumentation/Memory.h> | ||
} | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
// FIXME: Remove the need of DYLD_FORCE_FLAT_NAMESPACE by using interposing. | ||
static void EnsureFlatNamespaceOSX() { | ||
#ifdef __APPLE__ | ||
RB::Ensure(std::getenv("DYLD_FORCE_FLAT_NAMESPACE"), | ||
"DYLD_FORCE_FLAT_NAMESPACE not set."); | ||
#endif // __APPLE__ | ||
} | ||
|
||
namespace RB { | ||
void MemoryManager::Start() { | ||
Ensure(IsLdPreloadEnabled(), std::string(GetPreloadEnvVar()) + " not set."); | ||
EnsureFlatNamespaceOSX(); | ||
cur_num_allocs = 0; | ||
cur_max_bytes_used = 0; | ||
reset_malloc_stats(); | ||
} | ||
|
||
void MemoryManager::Stop(Result* result) { | ||
Ensure(IsLdPreloadEnabled(), std::string(GetPreloadEnvVar()) + " not set."); | ||
EnsureFlatNamespaceOSX(); | ||
const malloc_stats& stats = get_current_malloc_stats(); | ||
result->num_allocs = stats.num_malloc_calls; | ||
result->max_bytes_used = stats.max_bytes_used; | ||
} | ||
} // end RB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#include <TInterpreter.h> | ||
|
||
#include <rootbench/Support/MemoryManager.h> | ||
|
||
#include <benchmark/benchmark.h> | ||
|
||
|
||
static void BM_LookupHelper_Leak(benchmark::State &state) { | ||
gInterpreter->Declare(R"CODE( | ||
#ifndef BM_LookupHelper_Leak_Guard | ||
#define BM_LookupHelper_Leak_Guard | ||
template <class T, class U> class __gmp_expr; | ||
typedef struct{ } __mpz_struct; | ||
typedef __gmp_expr<__mpz_struct[1],__mpz_struct[1]> mpz_class; | ||
#endif // BM_LookupHelper_Leak_Guard | ||
)CODE"); | ||
|
||
for (auto _ : state) | ||
gInterpreter->ClassInfo_IsEnum("std::vector<mpz_class>::value_type"); | ||
} | ||
|
||
|
||
BENCHMARK(BM_LookupHelper_Leak); | ||
BENCHMARK_MAIN(); |