Chromium Code Reviews| Index: src/LinuxMallocProfiling.cpp |
| diff --git a/src/LinuxMallocProfiling.cpp b/src/LinuxMallocProfiling.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..25782cde7574749ed34c64ec161975d04e87cba6 |
| --- /dev/null |
| +++ b/src/LinuxMallocProfiling.cpp |
| @@ -0,0 +1,92 @@ |
| +//===- subzero/src/LinuxMallocProfiling.cpp - malloc/new tracing ---------===// |
| +// |
| +// The Subzero Code Generator |
| +// |
| +// This file is distributed under the University of Illinois Open Source |
| +// License. See LICENSE.TXT for details. |
| +// |
| +//===----------------------------------------------------------------------===// |
| +/// |
| +/// \file |
| +/// \brief malloc/new/...caller tracing. |
| +/// |
| +//===----------------------------------------------------------------------===// |
| + |
| +#include "LinuxMallocProfiling.h" |
| + |
| +#ifdef ALLOW_LINUX_MALLOC_PROFILE |
|
Jim Stichnoth
2016/03/15 15:36:50
I don't like all the #ifdef here.
I think it woul
sehr
2016/03/17 16:47:14
Done.
|
| +#include <dlfcn.h> |
| +#include <malloc.h> |
| +#include <iostream> |
|
Jim Stichnoth
2016/03/15 15:36:50
LLVM sez iostream is forbidden.
http://llvm.org/d
sehr
2016/03/17 16:47:14
I plumbed through the Ostream that was already use
|
| +#include <unordered_map> |
| + |
| +extern "C" void *__libc_malloc(size_t size); |
| + |
| +namespace { |
| +// The Callers structure allocates memory, which would perturb the tracing. |
| +// InAllocatorFunction is true when we are tracing a new/malloc/... |
| +bool InAllocatorFunction = false; |
| + |
| +// Keep track of the number of times a particular call site address invoked |
| +// an allocator. NOTE: this is not thread safe, so the user must invoke with |
| +// --threads=0 to enable profilin. |
|
John
2016/03/15 15:19:06
profiling
sehr
2016/03/17 16:47:14
Done.
|
| +using MallocMap = std::unordered_map<void*, uint64_t>; |
| +MallocMap *Callers; |
| + |
| +void *internalAllocator(size_t size, void *caller) { |
| + if (Callers != nullptr && !InAllocatorFunction) { |
| + InAllocatorFunction = true; |
| + ++(*Callers)[caller]; |
| + InAllocatorFunction = false; |
| + } |
| + return __libc_malloc(size); |
| +} |
| +} // end of anonymous namespace |
| + |
| +void *operator new (size_t size) { |
|
John
2016/03/15 15:19:06
can you add a comment explaining why this works?
sehr
2016/03/17 16:47:14
Done.
|
| + void *caller = __builtin_return_address(0); |
| + return internalAllocator(size, caller); |
| +} |
| + |
| +void *operator new[] (size_t size) { |
| + void *caller = __builtin_return_address(0); |
| + return internalAllocator(size, caller); |
| +} |
| + |
| +extern "C" void *malloc(size_t size) { |
| + void *caller = __builtin_return_address(0); |
| + return internalAllocator(size, caller); |
| +} |
| +#endif // ALLOW_LINUX_MALLOC_PROFILE |
| + |
| +namespace Ice { |
| + |
| +void LinuxMallocProfiling::start() { |
| +#ifdef ALLOW_LINUX_MALLOC_PROFILE |
| + Callers = new MallocMap(); |
| +#endif // ALLOW_LINUX_MALLOC_PROFILE |
| +} |
| + |
| +void LinuxMallocProfiling::end() { |
| +#ifdef ALLOW_LINUX_MALLOC_PROFILE |
| + if (Callers == nullptr) { |
| + return; |
| + } |
| + for (auto &C : *Callers) { |
|
John
2016/03/15 15:19:06
does
const auto &
work?
sehr
2016/03/17 16:47:14
Yes. Done.
|
| + Dl_info dli; |
| + dladdr(C.first, &dli); |
| + |
| + std::cout << C.second << " "; |
| + if (dli.dli_sname == NULL) { |
| + std::cout << C.first; |
| + } else { |
| + std::cout << dli.dli_sname; |
| + } |
| + std::cout << "\n"; |
| + } |
| + delete Callers; |
| + Callers = nullptr; |
| +#endif // ALLOW_LINUX_MALLOC_PROFILE |
| +} |
| + |
| +} // end of namespace Ice |