| Index: third_party/tcmalloc/chromium/src/allocated_type_map.cc
|
| diff --git a/third_party/tcmalloc/chromium/src/allocated_type_map.cc b/third_party/tcmalloc/chromium/src/allocated_type_map.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6dc53d454902b9f049d50805cf6bd101d483149c
|
| --- /dev/null
|
| +++ b/third_party/tcmalloc/chromium/src/allocated_type_map.cc
|
| @@ -0,0 +1,111 @@
|
| +// Copyright (c) 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.
|
| +
|
| +#include <config.h>
|
| +
|
| +#include <new>
|
| +#include <typeinfo>
|
| +
|
| +#include <gperftools/allocated_type_map.h>
|
| +
|
| +#include "addressmap-inl.h"
|
| +#include "tcmalloc_guard.h"
|
| +#include "base/spinlock.h"
|
| +#include "base/low_level_alloc.h"
|
| +
|
| +
|
| +//----------------------------------------------------------------------
|
| +// Locking
|
| +//----------------------------------------------------------------------
|
| +
|
| +// A pthread_mutex has way too much lock contention to be used here.
|
| +//
|
| +// I would like to use Mutex, but it can call malloc(),
|
| +// which can cause us to fall into an infinite recursion.
|
| +//
|
| +// So we use a simple spinlock.
|
| +static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
|
| +
|
| +//----------------------------------------------------------------------
|
| +// Simple allocator for allocated type map's internal memory
|
| +//----------------------------------------------------------------------
|
| +
|
| +static LowLevelAlloc::Arena* allocated_type_map_memory = NULL;
|
| +
|
| +static void* AllocatedTypeMalloc(size_t bytes) {
|
| + return LowLevelAlloc::AllocWithArena(bytes, allocated_type_map_memory);
|
| +}
|
| +static void AllocatedTypeFree(void* p) {
|
| + LowLevelAlloc::Free(p);
|
| +}
|
| +
|
| +//----------------------------------------------------------------------
|
| +// Profiling control/state data
|
| +//----------------------------------------------------------------------
|
| +
|
| +static AddressMap<const std::type_info*>* allocated_type_map = NULL;
|
| +static AddressMap<size_t>* allocated_size_map = NULL;
|
| +static AddressMap<size_t>* type_size_map = NULL;
|
| +
|
| +//----------------------------------------------------------------------
|
| +// Manage allocated type map
|
| +//----------------------------------------------------------------------
|
| +
|
| +extern "C" void InsertAllocatedType(void* address, const std::type_info& type) {
|
| + SpinLockHolder l(&heap_lock);
|
| +
|
| + if (allocated_type_map_memory == NULL) {
|
| + allocated_type_map_memory =
|
| + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
|
| + }
|
| +
|
| + if (allocated_type_map == NULL) {
|
| + allocated_type_map =
|
| + new(AllocatedTypeMalloc(sizeof(AddressMap<const std::type_info*>)))
|
| + AddressMap<const std::type_info*>(AllocatedTypeMalloc,
|
| + AllocatedTypeFree);
|
| + }
|
| +
|
| + allocated_type_map->Insert(address, &type);
|
| +}
|
| +
|
| +extern "C" void EraseAllocatedType(void* address) {
|
| + SpinLockHolder l(&heap_lock);
|
| +
|
| + if (allocated_type_map_memory == NULL) {
|
| + allocated_type_map_memory =
|
| + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
|
| + }
|
| +
|
| + if (allocated_type_map == NULL) {
|
| + allocated_type_map =
|
| + new(AllocatedTypeMalloc(sizeof(AddressMap<const std::type_info*>)))
|
| + AddressMap<const std::type_info*>(AllocatedTypeMalloc,
|
| + AllocatedTypeFree);
|
| + }
|
| +
|
| + const std::type_info* type;
|
| + allocated_type_map->FindAndRemove(address, &type);
|
| +}
|
| +
|
| +extern "C" const std::type_info* LookupAllocatedType(void* address) {
|
| + SpinLockHolder l(&heap_lock);
|
| +
|
| + if (allocated_type_map_memory == NULL) {
|
| + allocated_type_map_memory =
|
| + LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
|
| + }
|
| +
|
| + if (allocated_type_map == NULL) {
|
| + allocated_type_map =
|
| + new(AllocatedTypeMalloc(sizeof(AddressMap<const std::type_info*>)))
|
| + AddressMap<const std::type_info*>(AllocatedTypeMalloc,
|
| + AllocatedTypeFree);
|
| + }
|
| +
|
| + return *(allocated_type_map->FindMutable(address));
|
| +}
|
| +
|
| +// We want to make sure tcmalloc is up and running before starting the profiler
|
| +static const TCMallocGuard tcmalloc_initializer;
|
|
|