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 21namespace { 22 23const TCMallocGuard tcmalloc_initializer; 24 25//---------------------------------------------------------------------- 26// A struct to store size and type_info of an object 27//---------------------------------------------------------------------- 28 29struct 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 45SpinLock g_type_profiler_lock(SpinLock::LINKER_INITIALIZED); 46 47//---------------------------------------------------------------------- 48// Simple allocator for type_info map's internal memory 49//---------------------------------------------------------------------- 50 51LowLevelAlloc::Arena* g_type_profiler_map_memory = NULL; 52 53void* TypeProfilerMalloc(size_t bytes) { 54 return LowLevelAlloc::AllocWithArena(bytes, g_type_profiler_map_memory); 55} 56 57void TypeProfilerFree(void* p) { 58 LowLevelAlloc::Free(p); 59} 60 61//---------------------------------------------------------------------- 62// Profiling control/state data 63//---------------------------------------------------------------------- 64 65AddressMap<ObjectInfo>* g_type_profiler_map = NULL; 66 67//---------------------------------------------------------------------- 68// Manage type_info map 69//---------------------------------------------------------------------- 70 71void 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 87void 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 94void 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 102const 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