| Index: third_party/tcmalloc/chromium/src/heap-profiler.cc
 | 
| diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc
 | 
| index 85d1aadf7148b80f2a8b8d3c0096cf697dd5f81e..73f31f743f6146a6108b75c2ef0b2f8a821e4e4e 100644
 | 
| --- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
 | 
| +++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc
 | 
| @@ -143,7 +143,7 @@ static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
 | 
|  // Simple allocator for heap profiler's internal memory
 | 
|  //----------------------------------------------------------------------
 | 
|  
 | 
| -static LowLevelAlloc::Arena *heap_profiler_memory;
 | 
| +static LowLevelAlloc::Arena* heap_profiler_memory;
 | 
|  
 | 
|  static void* ProfilerMalloc(size_t bytes) {
 | 
|    return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory);
 | 
| @@ -152,6 +152,36 @@ static void ProfilerFree(void* p) {
 | 
|    LowLevelAlloc::Free(p);
 | 
|  }
 | 
|  
 | 
| +//----------------------------------------------------------------------
 | 
| +// Another allocator for heap profiler's internal mmap address map
 | 
| +//
 | 
| +// Large amount of memory is consumed if we use an arena 'heap_profiler_memory'
 | 
| +// for the internal mmap address map.  It looks like memory fragmentation
 | 
| +// because of repeated allocation/deallocation in the arena.
 | 
| +//
 | 
| +// 'mmap_heap_profiler_memory' is a dedicated arena for the mmap address map.
 | 
| +// This arena is reserved for every construction of the mmap address map, and
 | 
| +// disposed after every use.
 | 
| +//----------------------------------------------------------------------
 | 
| +
 | 
| +static LowLevelAlloc::Arena* mmap_heap_profiler_memory = NULL;
 | 
| +
 | 
| +static void* MMapProfilerMalloc(size_t bytes) {
 | 
| +  return LowLevelAlloc::AllocWithArena(bytes, mmap_heap_profiler_memory);
 | 
| +}
 | 
| +static void MMapProfilerFree(void* p) {
 | 
| +  LowLevelAlloc::Free(p);
 | 
| +}
 | 
| +
 | 
| +// This function should be called from a locked scope.
 | 
| +// It returns false if failed in deleting the arena.
 | 
| +static bool DeleteMMapProfilerArenaIfExistsLocked() {
 | 
| +  if (mmap_heap_profiler_memory == NULL) return true;
 | 
| +  if (!LowLevelAlloc::DeleteArena(mmap_heap_profiler_memory)) return false;
 | 
| +  mmap_heap_profiler_memory = NULL;
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
|  // We use buffers of this size in DoGetHeapProfile.
 | 
|  // The size is 1 << 20 in the original google-perftools.  Changed it to
 | 
|  // 5 << 20 since a larger buffer is requried for deeper profiling in Chromium.
 | 
| @@ -200,7 +230,12 @@ static char* DoGetHeapProfileLocked(char* buf, int buflen) {
 | 
|    int bytes_written = 0;
 | 
|    if (is_on) {
 | 
|      if (FLAGS_mmap_profile) {
 | 
| -      heap_profile->RefreshMMapData();
 | 
| +      if (!DeleteMMapProfilerArenaIfExistsLocked()) {
 | 
| +        RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
 | 
| +      }
 | 
| +      mmap_heap_profiler_memory =
 | 
| +          LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());
 | 
| +      heap_profile->RefreshMMapData(MMapProfilerMalloc, MMapProfilerFree);
 | 
|      }
 | 
|      if (deep_profile) {
 | 
|        bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
 | 
| @@ -209,6 +244,9 @@ static char* DoGetHeapProfileLocked(char* buf, int buflen) {
 | 
|      }
 | 
|      if (FLAGS_mmap_profile) {
 | 
|        heap_profile->ClearMMapData();
 | 
| +      if (!DeleteMMapProfilerArenaIfExistsLocked()) {
 | 
| +        RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
 | 
| +      }
 | 
|      }
 | 
|    }
 | 
|    buf[bytes_written] = '\0';
 | 
| @@ -532,6 +570,9 @@ extern "C" void HeapProfilerStop() {
 | 
|  
 | 
|    // free profile
 | 
|    heap_profile->~HeapProfileTable();
 | 
| +  if (!DeleteMMapProfilerArenaIfExistsLocked()) {
 | 
| +    RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
 | 
| +  }
 | 
|    ProfilerFree(heap_profile);
 | 
|    heap_profile = NULL;
 | 
|  
 | 
| @@ -553,7 +594,7 @@ extern "C" void HeapProfilerStop() {
 | 
|    is_on = false;
 | 
|  }
 | 
|  
 | 
| -extern "C" void HeapProfilerDump(const char *reason) {
 | 
| +extern "C" void HeapProfilerDump(const char* reason) {
 | 
|    SpinLockHolder l(&heap_lock);
 | 
|    if (is_on && !dumping) {
 | 
|      DumpProfileLocked(reason);
 | 
| 
 |