1 // Copyright 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #if defined(TYPE_PROFILING) 6 7 #include <config.h> 8 9 #include <new> 10 #include <stddef.h> 11 #include <typeinfo> 12 13 #include <gperftools/type_profiler_map.h> 14 15 #include "addressmap-inl.h" 16 #include "base/logging.h" 17 #include "base/low_level_alloc.h" 18 #include "base/spinlock.h" 19 #include "tcmalloc_guard.h" 20 21 namespace { 22 23 const TCMallocGuard tcmalloc_initializer; 24 25 //---------------------------------------------------------------------- 26 // A struct to store size and type_info of an object 27 //---------------------------------------------------------------------- 28 29 struct ObjectInfo { 30 public: 31 ObjectInfo(): size(0), type(NULL) {} 32 ObjectInfo(size_t size_arg, const std::type_info* type_arg) 33 : size(size_arg), 34 type(type_arg) { 35 } 36 37 size_t size; 38 const std::type_info* type; 39 }; 40 41 //---------------------------------------------------------------------- 42 // Locking 43 //---------------------------------------------------------------------- 44 45 SpinLock g_type_profiler_lock(SpinLock::LINKER_INITIALIZED); 46 47 //---------------------------------------------------------------------- 48 // Simple allocator for type_info map's internal memory 49 //---------------------------------------------------------------------- 50 51 LowLevelAlloc::Arena* g_type_profiler_map_memory = NULL; 52 53 void* TypeProfilerMalloc(size_t bytes) { 54 return LowLevelAlloc::AllocWithArena(bytes, g_type_profiler_map_memory); 55 } 56 57 void TypeProfilerFree(void* p) { 58 LowLevelAlloc::Free(p); 59 } 60 61 //---------------------------------------------------------------------- 62 // Profiling control/state data 63 //---------------------------------------------------------------------- 64 65 AddressMap<ObjectInfo>* g_type_profiler_map = NULL; 66 67 //---------------------------------------------------------------------- 68 // Manage type_info map 69 //---------------------------------------------------------------------- 70 71 void InitializeTypeProfilerMemory() { 72 if (g_type_profiler_map_memory != NULL) { 73 RAW_DCHECK(g_type_profiler_map != NULL, "TypeProfilerMap is NULL"); 74 return; 75 } 76 77 g_type_profiler_map_memory = 78 LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena()); 79 80 g_type_profiler_map = 81 new(TypeProfilerMalloc(sizeof(*g_type_profiler_map))) 82 AddressMap<ObjectInfo>(TypeProfilerMalloc, TypeProfilerFree); 83 } 84 85 } // namespace 86 87 void InsertType(void* address, size_t size, const std::type_info& type) { 88 SpinLockHolder lock(&g_type_profiler_lock); 89 InitializeTypeProfilerMemory(); 90 91 g_type_profiler_map->Insert(address, ObjectInfo(size, &type)); 92 } 93 94 void EraseType(void* address) { 95 SpinLockHolder lock(&g_type_profiler_lock); 96 InitializeTypeProfilerMemory(); 97 98 ObjectInfo obj; 99 g_type_profiler_map->FindAndRemove(address, &obj); 100 } 101 102 const std::type_info* LookupType(const void* address) { 103 SpinLockHolder lock(&g_type_profiler_lock); 104 InitializeTypeProfilerMemory(); 105 106 const ObjectInfo* found = g_type_profiler_map->Find(address); 107 if (found == NULL) 108 return NULL; 109 return found->type; 110 } 111 112 #endif // defined(TYPE_PROFILING) 113