From 7ce58b29d323d6da838330661a80c67b7871734b Mon Sep 17 00:00:00 2001 From: "dmikurube@chromium.org" Date: Wed, 26 Sep 2012 05:17:25 +0000 Subject: Type profiler by intercepting 'new' and 'delete' expressions. It stores mapping between object's starting addresses and their allocated types when a build option 'clang_type_profiler=1' is specified. It enables information like "an object at 0x37f3c88 is an instance of std::string." Nothing is changed when the option is not specified. It depends on a modified version of the LLVM/Clang compiler introduced at deps/third_party/llvm-allocated-type. BUG=123758 TEST=build with clang_type_profiler=1 and run type_profiler_unittests and type_profiler_map_unittests manually. Review URL: https://chromiumcodereview.appspot.com/10411047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158752 0039d316-1c4b-4281-b951-d872f2087c98 --- .../chromium/src/gperftools/type_profiler_map.h | 20 ++++ .../tcmalloc/chromium/src/type_profiler_map.cc | 112 +++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h create mode 100644 third_party/tcmalloc/chromium/src/type_profiler_map.cc (limited to 'third_party/tcmalloc') diff --git a/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h b/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h new file mode 100644 index 0000000..1236258 --- /dev/null +++ b/third_party/tcmalloc/chromium/src/gperftools/type_profiler_map.h @@ -0,0 +1,20 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TYPE_PROFILER_MAP_H_ +#define TYPE_PROFILER_MAP_H_ + +#if defined(TYPE_PROFILING) + +#include + +// PERFTOOLS_DLL_DECL is unnecessary, as it is Windows specific. + +void InsertType(void* address, size_t size, const std::type_info& type); +void EraseType(void* address); +const std::type_info* LookupType(const void* address); + +#endif // defined(TYPE_PROFILING) + +#endif // TYPE_PROFILER_MAP_H_ diff --git a/third_party/tcmalloc/chromium/src/type_profiler_map.cc b/third_party/tcmalloc/chromium/src/type_profiler_map.cc new file mode 100644 index 0000000..a2f21f8 --- /dev/null +++ b/third_party/tcmalloc/chromium/src/type_profiler_map.cc @@ -0,0 +1,112 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(TYPE_PROFILING) + +#include + +#include +#include +#include + +#include + +#include "addressmap-inl.h" +#include "base/logging.h" +#include "base/low_level_alloc.h" +#include "base/spinlock.h" +#include "tcmalloc_guard.h" + +namespace { + +const TCMallocGuard tcmalloc_initializer; + +//---------------------------------------------------------------------- +// A struct to store size and type_info of an object +//---------------------------------------------------------------------- + +struct ObjectInfo { + public: + ObjectInfo(): size(0), type(NULL) {} + ObjectInfo(size_t size_arg, const std::type_info* type_arg) + : size(size_arg), + type(type_arg) { + } + + size_t size; + const std::type_info* type; +}; + +//---------------------------------------------------------------------- +// Locking +//---------------------------------------------------------------------- + +SpinLock g_type_profiler_lock(SpinLock::LINKER_INITIALIZED); + +//---------------------------------------------------------------------- +// Simple allocator for type_info map's internal memory +//---------------------------------------------------------------------- + +LowLevelAlloc::Arena* g_type_profiler_map_memory = NULL; + +void* TypeProfilerMalloc(size_t bytes) { + return LowLevelAlloc::AllocWithArena(bytes, g_type_profiler_map_memory); +} + +void TypeProfilerFree(void* p) { + LowLevelAlloc::Free(p); +} + +//---------------------------------------------------------------------- +// Profiling control/state data +//---------------------------------------------------------------------- + +AddressMap* g_type_profiler_map = NULL; + +//---------------------------------------------------------------------- +// Manage type_info map +//---------------------------------------------------------------------- + +void InitializeTypeProfilerMemory() { + if (g_type_profiler_map_memory != NULL) { + RAW_DCHECK(g_type_profiler_map != NULL, "TypeProfilerMap is NULL"); + return; + } + + g_type_profiler_map_memory = + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena()); + + g_type_profiler_map = + new(TypeProfilerMalloc(sizeof(*g_type_profiler_map))) + AddressMap(TypeProfilerMalloc, TypeProfilerFree); +} + +} // namespace + +void InsertType(void* address, size_t size, const std::type_info& type) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + g_type_profiler_map->Insert(address, ObjectInfo(size, &type)); +} + +void EraseType(void* address) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + ObjectInfo obj; + g_type_profiler_map->FindAndRemove(address, &obj); +} + +const std::type_info* LookupType(const void* address) { + SpinLockHolder lock(&g_type_profiler_lock); + InitializeTypeProfilerMemory(); + + const ObjectInfo* found = g_type_profiler_map->Find(address); + if (found == NULL) + return NULL; + return found->type; +} + +#endif // defined(TYPE_PROFILING) -- cgit v1.1