Index: src/LinuxMallocProfiling.cpp |
diff --git a/src/LinuxMallocProfiling.cpp b/src/LinuxMallocProfiling.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ce02644b541b5aa521aa41defe7cd09d7983f496 |
--- /dev/null |
+++ b/src/LinuxMallocProfiling.cpp |
@@ -0,0 +1,83 @@ |
+//===- 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" |
+ |
+#include <malloc.h> |
Jim Stichnoth
2016/03/12 00:12:58
alphabetize these.
sehr
2016/03/15 00:36:45
Done.
|
+#include <dlfcn.h> |
+#include <iostream> |
+#include <map> |
+ |
+extern "C" void *__libc_malloc(size_t size); |
+ |
+namespace { |
+std::map<void*, uint64_t> *Callers; |
Jim Stichnoth
2016/03/12 00:12:58
Use std::unordered_map<>, no?
Also, please use a
Jim Stichnoth
2016/03/12 00:36:15
Probably should add a note somewhere that this is
sehr
2016/03/15 00:36:45
Added here and a warning comes out if a build incl
sehr
2016/03/15 00:36:45
Done.
|
+// The Callers structure allocates memory, which would perturb the tracing. |
+// InAllocatorFunction is true when we are tracing a new/malloc/... |
+bool InAllocatorFunction = false; |
+ |
+void *InternalAllocator(size_t size, void *caller) { |
Jim Stichnoth
2016/03/12 00:12:58
LLVM coding style would be:
void *internalAllocat
sehr
2016/03/15 00:36:45
Done.
|
+ if (Callers != nullptr && !InAllocatorFunction) { |
+ InAllocatorFunction = true; |
+ auto SetI = Callers->find(caller); |
Jim Stichnoth
2016/03/12 00:12:58
Can't you just simply:
++(*Callers)[caller];
?
sehr
2016/03/15 00:36:45
Done.
|
+ if (SetI == Callers->end()) { |
+ (*Callers)[caller] = 1; |
+ } else { |
+ (*Callers)[caller]++; |
+ } |
+ InAllocatorFunction = false; |
+ } |
+ return __libc_malloc(size); |
+} |
+} // end anonymous namespace |
Jim Stichnoth
2016/03/12 00:12:58
end of anonymous namespace
sehr
2016/03/15 00:36:45
Done.
|
+ |
+void *operator new (size_t size) { |
+ 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); |
+} |
+ |
+namespace Ice { |
+ |
+void LinuxMallocProfiling::Start() { |
+ Callers = new std::map<void*, uint64_t>(); |
+} |
+ |
+void LinuxMallocProfiling::End() { |
+ for (auto C : *Callers) { |
Karl
2016/03/11 23:25:11
Should you use?
for (auto &C : *Callers) {
sehr
2016/03/15 00:36:45
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 << std::endl; |
Jim Stichnoth
2016/03/12 00:12:58
I believe LLVM coding style says use "\n" instead
sehr
2016/03/15 00:36:45
Done.
|
+ } |
+ delete Callers; |
Jim Stichnoth
2016/03/12 00:12:58
Our code base favors unique_ptr<> over explicit de
sehr
2016/03/15 00:36:45
The Callers map needs to be accessible to non-memb
|
+ Callers = nullptr; |
+} |
+ |
+} // end namespace Ice |
Jim Stichnoth
2016/03/12 00:12:58
end of namespace Ice
sehr
2016/03/15 00:36:45
Done.
|