Home | History | Annotate | Download | only in src
      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