summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authordmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 17:20:10 +0000
committerdmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 17:20:10 +0000
commit856ff54b27138c316bd5433a20eeb527032e1608 (patch)
treecae500fb1b23bc37ac29bc31898761a368e58792 /third_party
parente6093fdce87b685f7fb9213f5a174c6c50caff76 (diff)
downloadchromium_src-856ff54b27138c316bd5433a20eeb527032e1608.zip
chromium_src-856ff54b27138c316bd5433a20eeb527032e1608.tar.gz
chromium_src-856ff54b27138c316bd5433a20eeb527032e1608.tar.bz2
Revert 127171 - Experiment for a deeper heap profile dumper to check impact for performance.
This change will be reverted soon. BUG=114301 TEST=none Review URL: https://chromiumcodereview.appspot.com/9701097 TBR=dmikurube@chromium.org Review URL: https://chromiumcodereview.appspot.com/9706107 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127194 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/tcmalloc/chromium/src/deep-heap-profile.cc600
-rw-r--r--third_party/tcmalloc/chromium/src/deep-heap-profile.h249
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profile-table.h1
-rw-r--r--third_party/tcmalloc/chromium/src/heap-profiler.cc25
4 files changed, 1 insertions, 874 deletions
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc
deleted file mode 100644
index bc18a0c..0000000
--- a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc
+++ /dev/null
@@ -1,600 +0,0 @@
-// 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.
-
-// ---
-// Author: Sainbayar Sukhbaatar
-// Dai Mikurube
-//
-
-#include "deep-heap-profile.h"
-
-#ifdef DEEP_HEAP_PROFILE
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // for getpagesize and getpid
-#endif // HAVE_UNISTD_H
-
-#include "base/cycleclock.h"
-#include "base/sysinfo.h"
-
-static const int kProfilerBufferSize = 1 << 20;
-static const int kHashTableSize = 179999; // The same as heap-profile-table.cc.
-
-static const int PAGEMAP_BYTES = 8;
-static const uint64 TOP_ADDRESS = kuint64max;
-
-// Header strings of the dumped heap profile.
-static const char kProfileHeader[] = "heap profile: ";
-static const char kProfileVersion[] = "DUMP_DEEP_3";
-static const char kGlobalStatsHeader[] = "GLOBAL_STATS:\n";
-static const char kMMapStacktraceHeader[] = "MMAP_STACKTRACES:\n";
-static const char kAllocStacktraceHeader[] = "MALLOC_STACKTRACES:\n";
-static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
-
-DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile,
- const char* prefix)
- : pagemap_fd_(-1),
- most_recent_pid_(-1),
- stats_(),
- dump_count_(0),
- filename_prefix_(NULL),
- profiler_buffer_(NULL),
- bucket_id_(0),
- heap_profile_(heap_profile) {
- deep_bucket_map_ = new(heap_profile_->alloc_(sizeof(DeepBucketMap)))
- DeepBucketMap(heap_profile_->alloc_, heap_profile_->dealloc_);
-
- // Copy filename prefix.
- const int prefix_length = strlen(prefix);
- filename_prefix_ =
- reinterpret_cast<char*>(heap_profile_->alloc_(prefix_length + 1));
- memcpy(filename_prefix_, prefix, prefix_length);
- filename_prefix_[prefix_length] = '\0';
-
- profiler_buffer_ =
- reinterpret_cast<char*>(heap_profile_->alloc_(kProfilerBufferSize));
-}
-
-DeepHeapProfile::~DeepHeapProfile() {
- heap_profile_->dealloc_(profiler_buffer_);
- heap_profile_->dealloc_(filename_prefix_);
- deep_bucket_map_->~DeepBucketMap();
- heap_profile_->dealloc_(deep_bucket_map_);
-}
-
-int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) {
-#ifndef NDEBUG
- int64 starting_cycles = CycleClock::Now();
-#endif
- ++dump_count_;
-
- // Re-open files in /proc/pid/ if the process is newly forked one.
- if (most_recent_pid_ != getpid()) {
- most_recent_pid_ = getpid();
- pagemap_fd_ = OpenProcPagemap();
-
- deep_bucket_map_->Iterate(ClearIsLogged, this);
-
- // Write maps into a .maps file with using the global buffer.
- WriteMapsToFile(filename_prefix_, kProfilerBufferSize, profiler_buffer_);
- }
-
- // Reset committed sizes of buckets.
- ResetCommittedSize(heap_profile_->alloc_table_);
- ResetCommittedSize(heap_profile_->mmap_table_);
-
- SnapshotGlobalStatsWithoutMalloc(pagemap_fd_, &stats_);
- size_t anonymous_committed = stats_.anonymous.committed_bytes();
-
- // Note: Least malloc from here. malloc here may cause a gap in the observed
- // size from actual memory allocation. The size of the gap is the size of
- // allocated memory at maximum. It doesn't cause violation.
- // TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
- // glibc's snprintf internally allocates memory by alloca normally, but it
- // allocates memory by malloc if large memory is required.
-
- // Record committed sizes.
- SnapshotAllAllocsWithoutMalloc();
-
- // Check if committed bytes changed during SnapshotAllAllocsWithoutMalloc.
- SnapshotGlobalStatsWithoutMalloc(pagemap_fd_, &stats_);
-#ifndef NDEBUG
- size_t committed_difference =
- stats_.anonymous.committed_bytes() - anonymous_committed;
- if (committed_difference != 0) {
- RAW_LOG(0, "Difference in committed size: %ld", committed_difference);
- }
-#endif
-
- // Start filling buffer with the ordered profile.
- int printed = snprintf(buffer, buffer_size,
- "%s%s\n", kProfileHeader, kProfileVersion);
- if (printed < 0 || printed >= buffer_size) {
- return 0;
- }
- int used_in_buffer = printed;
-
- // Fill buffer with the global stats.
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- kGlobalStatsHeader);
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- used_in_buffer = UnparseGlobalStats(used_in_buffer, buffer_size, buffer);
-
- // Fill buffer with the header for buckets of mmap'ed regions.
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- kMMapStacktraceHeader);
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "%10s %10s\n", "virtual", "committed");
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- // Fill buffer with stack trace buckets of mmap'ed regions.
- used_in_buffer = SnapshotBucketTableWithoutMalloc(heap_profile_->mmap_table_,
- used_in_buffer,
- buffer_size,
- buffer);
-
- // Fill buffer with the header for buckets of allocated regions.
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- kAllocStacktraceHeader);
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "%10s %10s\n", "virtual", "committed");
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- // Fill buffer with stack trace buckets of allocated regions.
- used_in_buffer = SnapshotBucketTableWithoutMalloc(heap_profile_->alloc_table_,
- used_in_buffer,
- buffer_size,
- buffer);
-
- RAW_DCHECK(used_in_buffer < buffer_size, "");
-
- // Note: Least malloc until here.
-
- // Write the bucket listing into a .bucket file.
- WriteBucketsToBucketFile();
-
-#ifndef NDEBUG
- int64 elapsed_cycles = CycleClock::Now() - starting_cycles;
- double elapsed_seconds = elapsed_cycles / CyclesPerSecond();
- RAW_LOG(0, "Time spent on DeepProfiler: %.3f sec\n", elapsed_seconds);
-#endif
-
- return used_in_buffer;
-}
-
-void DeepHeapProfile::RegionStats::Initialize() {
- virtual_bytes_ = 0;
- committed_bytes_ = 0;
-}
-
-void DeepHeapProfile::RegionStats::Record(
- int pagemap_fd, uint64 first_address, uint64 last_address) {
- virtual_bytes_ += static_cast<size_t>(last_address - first_address + 1);
- committed_bytes_ += GetCommittedSize(pagemap_fd, first_address, last_address);
-}
-
-// TODO(dmikurube): Avoid calling ClearIsLogged to rewrite buckets by add a
-// reference to a previous file in a .heap file.
-// static
-void DeepHeapProfile::ClearIsLogged(const void* pointer,
- DeepHeapProfile::DeepBucket* deep_bucket,
- DeepHeapProfile* deep_profile) {
- deep_bucket->is_logged = false;
-}
-
-// static
-int DeepHeapProfile::OpenProcPagemap() {
- char filename[100];
- snprintf(filename, sizeof(filename), "/proc/%d/pagemap", getpid());
- int pagemap_fd = open(filename, O_RDONLY);
- RAW_DCHECK(pagemap_fd != -1, "Failed to open /proc/self/pagemap");
- return pagemap_fd;
-}
-
-// static
-bool DeepHeapProfile::SeekProcPagemap(int pagemap_fd, uint64 address) {
- static int page_size = 0;
- if (!page_size) page_size = getpagesize();
- int64 index = (address / page_size) * PAGEMAP_BYTES;
- int64 offset = lseek64(pagemap_fd, index, SEEK_SET);
- RAW_DCHECK(offset == index, "");
- return offset >= 0;
-}
-
-// static
-bool DeepHeapProfile::ReadProcPagemap(int pagemap_fd, PageState* state) {
- static const uint64 U64_1 = 1;
- static const uint64 PFN_FILTER = (U64_1 << 55) - U64_1;
- static const uint64 PAGE_PRESENT = U64_1 << 63;
- static const uint64 PAGE_SWAP = U64_1 << 62;
- static const uint64 PAGE_RESERVED = U64_1 << 61;
- static const uint64 FLAG_NOPAGE = U64_1 << 20;
- static const uint64 FLAG_KSM = U64_1 << 21;
- static const uint64 FLAG_MMAP = U64_1 << 11;
-
- uint64 pagemap_value;
- int result = read(pagemap_fd, &pagemap_value, PAGEMAP_BYTES);
- if (result != PAGEMAP_BYTES) {
- return false;
- }
-
- // Check if the page is committed.
- state->is_committed = (pagemap_value & (PAGE_PRESENT | PAGE_SWAP));
-
- state->is_present = (pagemap_value & PAGE_PRESENT);
- state->is_swapped = (pagemap_value & PAGE_SWAP);
- state->is_shared = false;
-
- return true;
-}
-
-// static
-size_t DeepHeapProfile::GetCommittedSize(
- int pagemap_fd, uint64 first_address, uint64 last_address) {
- static int page_size = 0;
- if (!page_size) page_size = getpagesize();
- uint64 page_address = (first_address / page_size) * page_size;
- size_t committed_size = 0;
-
- SeekProcPagemap(pagemap_fd, first_address);
-
- // Check every page on which the allocation resides.
- while (page_address <= last_address) {
- // Read corresponding physical page.
- PageState state;
- if (ReadProcPagemap(pagemap_fd, &state) == false) {
- // We can't read the last region (e.g vsyscall).
-#ifndef NDEBUG
- RAW_LOG(0, "pagemap read failed @ %#llx %"PRId64" bytes",
- first_address, last_address - first_address + 1);
-#endif
- return 0;
- }
-
- if (state.is_committed) {
- // Calculate the size of the allocation part in this page.
- size_t bytes = page_size;
-
- // If looking at the last page in a given region.
- if (last_address <= page_address - 1 + page_size) {
- bytes = last_address - page_address + 1;
- }
-
- // If looking at the first page in a given region.
- if (page_address < first_address) {
- bytes -= first_address - page_address;
- }
-
- committed_size += bytes;
- }
- if (page_address > TOP_ADDRESS - page_size) {
- break;
- }
- page_address += page_size;
- }
-
- return committed_size;
-}
-
-// static
-void DeepHeapProfile::WriteMapsToFile(const char* filename_prefix,
- int buffer_size,
- char buffer[]) {
- char filename[100];
- snprintf(filename, sizeof(filename),
- "%s.%05d.maps", filename_prefix, getpid());
-
- RawFD maps_fd = RawOpenForWriting(filename);
- RAW_DCHECK(maps_fd != kIllegalRawFD, "");
-
- int map_length;
- bool wrote_all;
- map_length = tcmalloc::FillProcSelfMaps(buffer, buffer_size, &wrote_all);
- RAW_DCHECK(wrote_all, "");
- RAW_DCHECK(map_length <= buffer_size, "");
- RawWrite(maps_fd, buffer, map_length);
- RawClose(maps_fd);
-}
-
-// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
-// ProcMapsIterator uses snprintf internally in construction.
-// static
-void DeepHeapProfile::SnapshotGlobalStatsWithoutMalloc(int pagemap_fd,
- GlobalStats* stats) {
- ProcMapsIterator::Buffer iterator_buffer;
- ProcMapsIterator iterator(0, &iterator_buffer);
- uint64 first_address, last_address, offset;
- int64 inode;
- char* flags;
- char* filename;
-
- stats->total.Initialize();
- stats->file_mapped.Initialize();
- stats->anonymous.Initialize();
- stats->other.Initialize();
-
- while (iterator.Next(&first_address, &last_address,
- &flags, &offset, &inode, &filename)) {
- // 'last_address' should be the last inclusive address of the region.
- last_address -= 1;
- if (strcmp("[vsyscall]", filename) == 0) {
- continue; // Reading pagemap will fail in [vsyscall].
- }
-
- stats->total.Record(pagemap_fd, first_address, last_address);
-
- if (filename[0] == '/') {
- stats->file_mapped.Record(pagemap_fd, first_address, last_address);
- } else if (filename[0] == '\0' || filename[0] == '\n') {
- stats->anonymous.Record(pagemap_fd, first_address, last_address);
- } else {
- stats->other.Record(pagemap_fd, first_address, last_address);
- }
- }
-}
-
-DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket(Bucket* bucket) {
- DeepBucket* found = deep_bucket_map_->FindMutable(bucket);
- if (found != NULL)
- return found;
-
- DeepBucket created;
- created.bucket = bucket;
- created.committed_size = 0;
- created.id = (bucket_id_++);
- created.is_logged = false;
- deep_bucket_map_->Insert(bucket, created);
- return deep_bucket_map_->FindMutable(bucket);
-}
-
-void DeepHeapProfile::ResetCommittedSize(Bucket** bucket_table) {
- for (int i = 0; i < kHashTableSize; i++) {
- for (Bucket* bucket = bucket_table[i];
- bucket != NULL;
- bucket = bucket->next) {
- DeepBucket* deep_bucket = GetDeepBucket(bucket);
- deep_bucket->committed_size = 0;
- }
- }
-}
-
-// TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf.
-int DeepHeapProfile::SnapshotBucketTableWithoutMalloc(Bucket** bucket_table,
- int used_in_buffer,
- int buffer_size,
- char buffer[]) {
- for (int i = 0; i < kHashTableSize; i++) {
- for (Bucket* bucket = bucket_table[i];
- bucket != NULL;
- bucket = bucket->next) {
- if (bucket->alloc_size - bucket->free_size == 0) {
- continue; // Skip empty buckets.
- }
- const DeepBucket* deep_bucket = GetDeepBucket(bucket);
- used_in_buffer = UnparseBucket(
- *deep_bucket, "", used_in_buffer, buffer_size, buffer, NULL);
- }
- }
- return used_in_buffer;
-}
-
-void DeepHeapProfile::RecordAlloc(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile) {
- uint64 address = reinterpret_cast<uintptr_t>(pointer);
- size_t committed = GetCommittedSize(deep_profile->pagemap_fd_,
- address, address + alloc_value->bytes - 1);
-
- DeepBucket* deep_bucket = deep_profile->GetDeepBucket(alloc_value->bucket());
- deep_bucket->committed_size += committed;
- deep_profile->stats_.record_malloc.AddToVirtualBytes(alloc_value->bytes);
- deep_profile->stats_.record_malloc.AddToCommittedBytes(committed);
-}
-
-void DeepHeapProfile::RecordMMap(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile) {
- uint64 address = reinterpret_cast<uintptr_t>(pointer);
- size_t committed = GetCommittedSize(deep_profile->pagemap_fd_,
- address, address + alloc_value->bytes - 1);
-
- DeepBucket* deep_bucket = deep_profile->GetDeepBucket(alloc_value->bucket());
- deep_bucket->committed_size += committed;
- deep_profile->stats_.record_mmap.AddToVirtualBytes(alloc_value->bytes);
- deep_profile->stats_.record_mmap.AddToCommittedBytes(committed);
-}
-
-void DeepHeapProfile::SnapshotAllAllocsWithoutMalloc() {
- stats_.record_mmap.Initialize();
- stats_.record_malloc.Initialize();
-
- // malloc allocations.
- heap_profile_->alloc_address_map_->Iterate(RecordAlloc, this);
-
- // mmap allocations.
- heap_profile_->mmap_address_map_->Iterate(RecordMMap, this);
-}
-
-int DeepHeapProfile::FillBucketForBucketFile(const DeepBucket* deep_bucket,
- int buffer_size,
- char buffer[]) {
- const Bucket* bucket = deep_bucket->bucket;
- int printed = snprintf(buffer, buffer_size, "%05d", deep_bucket->id);
- if (printed < 0 || printed >= buffer_size) {
- return 0;
- }
- int used_in_buffer = printed;
-
- for (int depth = 0; depth < bucket->depth; depth++) {
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- " 0x%08" PRIxPTR,
- reinterpret_cast<uintptr_t>(bucket->stack[depth]));
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
- }
- printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "\n");
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- return used_in_buffer;
-}
-
-void DeepHeapProfile::WriteBucketsTableToBucketFile(Bucket** bucket_table,
- RawFD bucket_fd) {
- // We will use the global buffer here.
- char* buffer = profiler_buffer_;
- int buffer_size = kProfilerBufferSize;
- int used_in_buffer = 0;
-
- for (int i = 0; i < kHashTableSize; i++) {
- for (Bucket* bucket = bucket_table[i];
- bucket != NULL;
- bucket = bucket->next) {
- DeepBucket* deep_bucket = GetDeepBucket(bucket);
- if (deep_bucket->is_logged) {
- continue; // Skip the bucket if it is already logged.
- }
- if (bucket->alloc_size - bucket->free_size <= 64) {
- continue; // Skip small buckets.
- }
-
- used_in_buffer += FillBucketForBucketFile(
- deep_bucket, buffer_size - used_in_buffer, buffer + used_in_buffer);
- deep_bucket->is_logged = true;
-
- // Write to file if buffer 80% full.
- if (used_in_buffer > buffer_size * 0.8) {
- RawWrite(bucket_fd, buffer, used_in_buffer);
- used_in_buffer = 0;
- }
- }
- }
-
- RawWrite(bucket_fd, buffer, used_in_buffer);
-}
-
-void DeepHeapProfile::WriteBucketsToBucketFile() {
- char filename[100];
- snprintf(filename, sizeof(filename),
- "%s.%05d.%04d.buckets", filename_prefix_, getpid(), dump_count_);
- RawFD bucket_fd = RawOpenForWriting(filename);
- RAW_DCHECK(bucket_fd != kIllegalRawFD, "");
-
- WriteBucketsTableToBucketFile(heap_profile_->alloc_table_, bucket_fd);
- WriteBucketsTableToBucketFile(heap_profile_->mmap_table_, bucket_fd);
-
- RawClose(bucket_fd);
-}
-
-int DeepHeapProfile::UnparseBucket(const DeepBucket& deep_bucket,
- const char* extra,
- int used_in_buffer,
- int buffer_size,
- char* buffer,
- Stats* profile_stats) {
- const Bucket& bucket = *deep_bucket.bucket;
- if (profile_stats != NULL) {
- profile_stats->allocs += bucket.allocs;
- profile_stats->alloc_size += bucket.alloc_size;
- profile_stats->frees += bucket.frees;
- profile_stats->free_size += bucket.free_size;
- }
-
- int printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "%10"PRId64" %10"PRId64" %6d %6d @%s %d\n",
- bucket.alloc_size - bucket.free_size,
- deep_bucket.committed_size,
- bucket.allocs, bucket.frees, extra, deep_bucket.id);
- // If it looks like the snprintf failed, ignore the fact we printed anything.
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- return used_in_buffer;
-}
-
-int DeepHeapProfile::UnparseRegionStats(const RegionStats* stats,
- const char* name,
- int used_in_buffer,
- int buffer_size,
- char* buffer) {
- int printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "%15s %10ld %10ld\n",
- name, stats->virtual_bytes(),
- stats->committed_bytes());
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- return used_in_buffer;
-}
-
-int DeepHeapProfile::UnparseGlobalStats(int used_in_buffer,
- int buffer_size,
- char* buffer) {
- int printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer,
- "%15s %10s %10s\n", "", "virtual", "committed");
- if (printed < 0 || printed >= buffer_size - used_in_buffer) {
- return used_in_buffer;
- }
- used_in_buffer += printed;
-
- used_in_buffer = UnparseRegionStats(&(stats_.total), "total",
- used_in_buffer, buffer_size, buffer);
- used_in_buffer = UnparseRegionStats(&(stats_.file_mapped), "file mapped",
- used_in_buffer, buffer_size, buffer);
- used_in_buffer = UnparseRegionStats(&(stats_.anonymous), "anonymous",
- used_in_buffer, buffer_size, buffer);
- used_in_buffer = UnparseRegionStats(&(stats_.other), "other",
- used_in_buffer, buffer_size, buffer);
- used_in_buffer = UnparseRegionStats(&(stats_.record_mmap), "mmap",
- used_in_buffer, buffer_size, buffer);
- used_in_buffer = UnparseRegionStats(&(stats_.record_malloc), "tcmalloc",
- used_in_buffer, buffer_size, buffer);
- return used_in_buffer;
-}
-#else // DEEP_HEAP_PROFILE
-
-DeepHeapProfile::DeepHeapProfile(HeapProfileTable* heap_profile,
- const char* prefix)
- : heap_profile_(heap_profile) {
-}
-
-DeepHeapProfile::~DeepHeapProfile() {
-}
-
-int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) {
- return heap_profile_->FillOrderedProfile(buffer, buffer_size);
-}
-
-#endif // DEEP_HEAP_PROFILE
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h
deleted file mode 100644
index c3249f3..0000000
--- a/third_party/tcmalloc/chromium/src/deep-heap-profile.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// 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.
-
-// ---
-// Author: Sainbayar Sukhbaatar
-// Dai Mikurube
-//
-// This file contains a class DeepHeapProfile and its public function
-// DeepHeapProfile::FillOrderedProfile() which works as an alternative of
-// HeapProfileTable::FillOrderedProfile().
-//
-// DeepHeapProfile::FillOrderedProfile() dumps more detailed information about
-// heap usage, which includes OS-level information such as whether the memory
-// block is actually in memory, or not. DeepHeapProfile::FillOrderedProfile()
-// uses logged data in HeapProfileTable as one of its data sources.
-// DeepHeapProfile works only when its FillOrderedProfile() is called. It has
-// overhead when dumping, but no overhead when logging.
-//
-// It currently works only on Linux. It just delegates to HeapProfileTable in
-// non-Linux environments.
-
-
-#ifndef BASE_DEEP_HEAP_PROFILE_H_
-#define BASE_DEEP_HEAP_PROFILE_H_
-
-#include "config.h"
-
-#if defined(__linux__)
-#define DEEP_HEAP_PROFILE 1
-#endif
-
-#include "addressmap-inl.h"
-#include "heap-profile-table.h"
-
-class DeepHeapProfile {
- public:
- typedef HeapProfileTable::Bucket Bucket;
- typedef HeapProfileTable::AllocationMap AllocationMap;
- typedef HeapProfileTable::AllocValue AllocValue;
- typedef HeapProfileTable::Stats Stats;
-
- // Construct a DeepHeapProfile instance. It works as a wrapper of
- // HeapProfileTable.
- //
- // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads
- // data in |heap_profile| and forwards operations to |heap_profile| if
- // DeepHeapProfile is not available (non-Linux).
- // |prefix| is a prefix of dumped file names.
- DeepHeapProfile(HeapProfileTable* heap_profile, const char* prefix);
- ~DeepHeapProfile();
-
- // Fill deep profile data into |buffer| of |size|, and return the actual
- // size occupied by the dump in |buffer|. It works as an alternative
- // of HeapProfileTable::FillOrderedProfile.
- //
- // The profile buckets are dumped in the decreasing order of currently
- // allocated bytes. We do not provision for 0-terminating |buffer|.
- int FillOrderedProfile(char buffer[], int buffer_size);
-
- private:
-#ifdef DEEP_HEAP_PROFILE
- struct DeepBucket {
- Bucket* bucket;
- size_t committed_size;
- int id; // Unique ID of the bucket.
- bool is_logged; // True if the stracktrace is logged to a file.
- };
-
- typedef AddressMap<DeepBucket> DeepBucketMap;
-
- struct PageState {
- bool is_committed; // Currently, we use only this
- bool is_present;
- bool is_swapped;
- bool is_shared;
- bool is_mmap;
- };
-
- class RegionStats {
- public:
- // Initialize virtual_bytes and committed_bytes.
- void Initialize();
-
- // Update the RegionStats to include the tallies of virtual_bytes and
- // committed_bytes in the region from |first_adress| to |last_address|
- // inclusive.
- void Record(int pagemap_fd, uint64 first_address, uint64 last_address);
-
- size_t virtual_bytes() const { return virtual_bytes_; }
- size_t committed_bytes() const { return committed_bytes_; }
- void set_virtual_bytes(size_t virtual_bytes) {
- virtual_bytes_ = virtual_bytes;
- }
- void set_committed_bytes(size_t committed_bytes) {
- committed_bytes_ = committed_bytes;
- }
- void AddToVirtualBytes(size_t additional_virtual_bytes) {
- virtual_bytes_ += additional_virtual_bytes;
- }
- void AddToCommittedBytes(size_t additional_committed_bytes) {
- committed_bytes_ += additional_committed_bytes;
- }
-
- private:
- size_t virtual_bytes_;
- size_t committed_bytes_;
- };
-
- struct GlobalStats {
- // All RegionStats members in this class contain the bytes of virtual
- // memory and committed memory.
- // TODO(dmikurube): These regions should be classified more precisely later
- // for more detailed analysis.
-
- // Total bytes of the process memory.
- RegionStats total;
-
- // Total bytes of memory which is mapped to a file.
- // Regions which contain file paths in the last column of /proc/<pid>/maps.
- RegionStats file_mapped;
-
- // Total bytes of memory which is mapped anonymously.
- // Regions which contain nothing in the last column of /proc/<pid>/maps.
- RegionStats anonymous;
-
- // Total bytes of memory which is labeled, but not mapped to any file.
- // Regions which contain non-path strings in the last column of
- // /proc/<pid>/maps.
- RegionStats other;
-
- // Total bytes of mmap'ed regions.
- RegionStats record_mmap;
-
- // Total bytes of malloc'ed regions.
- RegionStats record_malloc;
- };
-
- // Clear the is_logged flag in a DeepBucket object as a callback function
- // for DeepBucketMap::Iterate().
- static void ClearIsLogged(const void* pointer,
- DeepBucket* db,
- DeepHeapProfile* deep_profile);
-
- // Open /proc/pid/pagemap and return its file descriptor.
- // File descriptors need to be refreshed after each fork.
- static int OpenProcPagemap();
-
- // Seek to the offset of the open pagemap file pagemap_fd.
- // It returns true if succeeded. Otherwise, it returns false.
- static bool SeekProcPagemap(int pagemap_fd, uint64 address);
-
- // Read a pagemap state from the current pagemap_fd offset.
- // It returns true if succeeded. Otherwise, it returns false.
- static bool ReadProcPagemap(int pagemap_fd, PageState* state);
-
- // Returns the number of resident (including swapped) bytes of the memory
- // region starting at |first_address| and ending at |last_address| inclusive.
- static size_t GetCommittedSize(int pagemap_fd,
- uint64 first_address,
- uint64 last_address);
-
- // Write re-formatted /proc/self/maps into a file which has |filename_prefix|
- // with using |buffer| of size |buffer_size|.
- static void WriteMapsToFile(const char* filename_prefix,
- int buffer_size,
- char buffer[]);
-
- // Compute the global statistics from /proc/self/maps and |pagemap_fd|, and
- // store the statistics in |stats|.
- static void SnapshotGlobalStatsWithoutMalloc(int pagemap_fd,
- GlobalStats* stats);
-
- // Get the DeepBucket object corresponding to the given |bucket|.
- // DeepBucket is an extension to Bucket which is declared above.
- DeepBucket* GetDeepBucket(Bucket* bucket);
-
- // Reset committed_size member variables in DeepBucket objects to 0.
- void ResetCommittedSize(Bucket** bucket_table);
-
- // Fill bucket data in |bucket_table| into buffer |buffer| of size
- // |buffer_size|, and return the size occupied by the bucket data in
- // |buffer|. |bucket_length| is the offset for |buffer| to start filling.
- int SnapshotBucketTableWithoutMalloc(Bucket** bucket_table,
- int used_in_buffer,
- int buffer_size,
- char buffer[]);
-
- // Record both virtual and committed byte counts of malloc and mmap regions
- // as callback functions for AllocationMap::Iterate().
- static void RecordAlloc(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile);
- static void RecordMMap(const void* pointer,
- AllocValue* alloc_value,
- DeepHeapProfile* deep_profile);
- void SnapshotAllAllocsWithoutMalloc();
-
- // Fill a bucket (a bucket id and its corresponding calling stack) into
- // |buffer| of size |buffer_size|.
- int FillBucketForBucketFile(const DeepBucket* deep_bucket,
- int buffer_size,
- char buffer[]);
-
- // Write a |bucket_table| into a file of |bucket_fd|.
- void WriteBucketsTableToBucketFile(Bucket** bucket_table, RawFD bucket_fd);
-
- // Write both malloc and mmap bucket tables into a "bucket file".
- void WriteBucketsToBucketFile();
-
- // Fill a |deep_bucket| and its corresponding bucket into |buffer| from the
- // offset |used_in_buffer|. Add the sizes to |profile_stats| if it's not
- // NULL.
- static int UnparseBucket(const DeepBucket& deep_bucket,
- const char* extra,
- int used_in_buffer,
- int buffer_size,
- char* buffer,
- Stats* profile_stats);
-
- // Fill statistics of a region into |buffer|.
- static int UnparseRegionStats(const RegionStats* stats,
- const char* name,
- int used_in_buffer,
- int buffer_size,
- char* buffer);
-
- // Fill global statistics into |buffer|.
- int UnparseGlobalStats(int used_in_buffer, int buffer_size, char* buffer);
-
- int pagemap_fd_; // File descriptor of /proc/self/pagemap.
-
- // Process ID of the last dump. This could change by fork.
- pid_t most_recent_pid_;
- GlobalStats stats_; // Stats about total memory.
- int dump_count_; // The number of dumps.
- char* filename_prefix_; // Output file prefix.
- char* profiler_buffer_; // Buffer we use many times.
-
- int bucket_id_;
- DeepBucketMap* deep_bucket_map_;
-#endif // DEEP_HEAP_PROFILE
-
- HeapProfileTable* heap_profile_;
-
- DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile);
-};
-
-#endif // BASE_DEEP_HEAP_PROFILE_H_
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.h b/third_party/tcmalloc/chromium/src/heap-profile-table.h
index 447943d..abd3184 100644
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.h
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.h
@@ -198,7 +198,6 @@ class HeapProfileTable {
void ClearMMapData();
private:
- friend class DeepHeapProfile;
// data types ----------------------------
diff --git a/third_party/tcmalloc/chromium/src/heap-profiler.cc b/third_party/tcmalloc/chromium/src/heap-profiler.cc
index 85d1aad..166afde 100644
--- a/third_party/tcmalloc/chromium/src/heap-profiler.cc
+++ b/third_party/tcmalloc/chromium/src/heap-profiler.cc
@@ -68,7 +68,6 @@
#include "base/spinlock.h"
#include "base/low_level_alloc.h"
#include "base/sysinfo.h" // for GetUniquePathFromEnv()
-#include "deep-heap-profile.h"
#include "heap-profile-table.h"
#include "memory_region_map.h"
@@ -122,9 +121,6 @@ DEFINE_bool(only_mmap_profile,
EnvToBool("HEAP_PROFILE_ONLY_MMAP", false),
"If heap-profiling is on, only profile mmap, mremap, and sbrk; "
"do not profile malloc/new/etc");
-DEFINE_bool(deep_heap_profile,
- EnvToBool("DEEP_HEAP_PROFILE", false),
- "If heap-profiling is on, profile deeper (only on Linux)");
//----------------------------------------------------------------------
@@ -183,7 +179,6 @@ static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
static int64 last_dump_time = 0; // The time of the last dump
static HeapProfileTable* heap_profile = NULL; // the heap profile table
-static DeepHeapProfile* deep_profile = NULL; // deep memory profiler
//----------------------------------------------------------------------
// Profile generation
@@ -202,11 +197,7 @@ static char* DoGetHeapProfileLocked(char* buf, int buflen) {
if (FLAGS_mmap_profile) {
heap_profile->RefreshMMapData();
}
- if (deep_profile) {
- bytes_written = deep_profile->FillOrderedProfile(buf, buflen - 1);
- } else {
- bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
- }
+ bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
if (FLAGS_mmap_profile) {
heap_profile->ClearMMapData();
}
@@ -475,13 +466,6 @@ extern "C" void HeapProfilerStart(const char* prefix) {
high_water_mark = 0;
last_dump_time = 0;
- if (FLAGS_deep_heap_profile) {
- // Initialize deep memory profiler
- RAW_VLOG(0, "[%d] Starting a deep memory profiler", getpid());
- deep_profile = new(ProfilerMalloc(sizeof(DeepHeapProfile)))
- DeepHeapProfile(heap_profile, prefix);
- }
-
// We do not reset dump_count so if the user does a sequence of
// HeapProfilerStart/HeapProfileStop, we will get a continuous
// sequence of profiles.
@@ -523,13 +507,6 @@ extern "C" void HeapProfilerStop() {
RAW_CHECK(MallocHook::RemoveMunmapHook(&MunmapHook), "");
}
- if (deep_profile) {
- // free deep memory profiler
- deep_profile->~DeepHeapProfile();
- ProfilerFree(deep_profile);
- deep_profile = NULL;
- }
-
// free profile
heap_profile->~HeapProfileTable();
ProfilerFree(heap_profile);