| Index: base/allocator/allocator_extension.cc
|
| diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc
|
| index 17682f85d4950acd837f268056afa3ae49fc43c2..a8dbdb236f356dbc6dd6442575f0a6be8d15e3a8 100644
|
| --- a/base/allocator/allocator_extension.cc
|
| +++ b/base/allocator/allocator_extension.cc
|
| @@ -9,6 +9,7 @@
|
| #if defined(USE_TCMALLOC)
|
| #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
|
| #include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
|
| +#include "third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h"
|
| #endif
|
|
|
| namespace base {
|
| @@ -34,5 +35,56 @@ bool IsHeapProfilerRunning() {
|
| return false;
|
| }
|
|
|
| +AllocHookFunc SetSingleAllocHook(AllocHookFunc func) {
|
| +#if defined(USE_TCMALLOC)
|
| + return MallocHook::SetNewHook(func);
|
| +#endif
|
| + return nullptr;
|
| +}
|
| +
|
| +FreeHookFunc SetSingleFreeHook(FreeHookFunc func) {
|
| +#if defined(USE_TCMALLOC)
|
| + return MallocHook::SetDeleteHook(func);
|
| +#endif
|
| + return nullptr;
|
| +}
|
| +
|
| +AllocHookFunc GetSingleAllocHook() {
|
| +#if defined(USE_TCMALLOC)
|
| + // Due to the way things are implemented in tcmalloc's
|
| + // gperftools/malloc_hook.h, MallocHook::GetNewHook() cannot be called.
|
| + // Instead, overwrite the stored callback with nullptr and get the stored
|
| + // callback as a return value from SetNewHook(). Then write it back as the
|
| + // stored value. Same goes for GetSingleFreeHook().
|
| + //
|
| + // This implementation should not have too much overhead as long as
|
| + // MallocHook's deprecated hook registration functions are trivial.
|
| + AllocHookFunc existing_hook = MallocHook::SetNewHook(nullptr);
|
| + MallocHook::SetNewHook(existing_hook);
|
| + return existing_hook;
|
| +#endif
|
| + return nullptr;
|
| +}
|
| +
|
| +FreeHookFunc GetSingleFreeHook() {
|
| +#if defined(USE_TCMALLOC)
|
| + FreeHookFunc existing_hook = MallocHook::SetDeleteHook(nullptr);
|
| + MallocHook::SetDeleteHook(existing_hook);
|
| + return existing_hook;
|
| +#endif
|
| + return nullptr;
|
| +}
|
| +
|
| +int GetCallStack(void** stack, int max_stack_size, int /* skip_count */) {
|
| +#if defined(USE_TCMALLOC)
|
| + // |skip_count| is not used by the following function. Instead, the number of
|
| + // frames to skip is determined internally.
|
| + // See MallocHook_GetCallerStackTrace() in
|
| + // third_party/tcmalloc/chromium/src/malloc_hook.cc.
|
| + return MallocHook::GetCallerStackTrace(stack, max_stack_size, 0);
|
| +#endif
|
| + return 0;
|
| +}
|
| +
|
| } // namespace allocator
|
| } // namespace base
|
|
|