Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Unified Diff: third_party/tcmalloc/chromium/src/deep-heap-profile.h

Issue 8632007: A deeper heap profile dumper in third_party/tcmalloc/chromium. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixed the snprintf issues. Created 8 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/tcmalloc/chromium/src/deep-heap-profile.h
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h
new file mode 100644
index 0000000000000000000000000000000000000000..bdd3a13f1b3bae09b905d37ba0ed5818c7f6dade
--- /dev/null
+++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.h
@@ -0,0 +1,190 @@
+// Copyright (c) 2011 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 'buf' of size 'size', and return the
+ // actual size occupied by the dump in 'buf'. 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 'buf'.
+ int FillOrderedProfile(char buf[], int 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;
+ };
+
+ struct RegionStats {
+ size_t virtual_bytes;
+ size_t committed_bytes;
+ };
+
+ struct GlobalStats {
+ RegionStats total;
+ RegionStats file_mapped;
+ RegionStats anonymous;
+ RegionStats other;
+ RegionStats record_mmap;
+ RegionStats record_tcmalloc;
+ };
+
+ struct BufferArgs {
+ char* buf;
+ int size;
+ int len;
+ };
+
+ // 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** table);
+
+ // Fill bucket data in 'table' into buffer 'buf' of size 'size', and return
+ // the size occupied by the bucket data in 'buf'. 'bucket_length' is the
+ // offset for 'buf' to start filling. Statistics in 'stats' is updated if
+ // it's not NULL.
+ int FillBucketTable(Bucket** table, char buf[], int size, int bucket_length,
+ HeapProfileTable::Stats* stats);
+
+ // Open /proc/pid/pagemap and store its file descriptor in pagemap_fd_.
+ void OpenProcPagemap();
+
+ // Seek the offset of the open pagemap file pagemap_fd_.
+ bool SeekProcPagemap(uint64 addr);
+
+ // Read a pagemap state from the current pagemap_fd_ offset.
+ bool ReadProcPagemap(PageState* state);
+
+ // Get a committed (resident + swapped) size in the memory region
+ // from 'addr' to 'addr + size'.
+ size_t GetCommittedSize(uint64 addr, size_t size);
+
+ // Initialize 'virtual_bytes' and 'committed_bytes' in RegionStats.
+ void InitRegionStats(RegionStats* stats);
+
+ // Add the virtual size (end - start) and the committed size in the region
+ // to 'stats'.
+ void RecordRegionStats(uint64 start, uint64 end, RegionStats* stats);
+
+ // Compute the global statistics from /proc/self/maps and pagemap, and
+ // store them in stats_.
+ void GetGlobalStats();
+
+ // Record the committed memory size of each allocation and mmap.
+ static void RecordAlloc(const void* ptr, AllocValue* v,
+ DeepHeapProfile* deep_profile);
+ static void RecordMMap(const void* ptr, AllocValue* v,
+ DeepHeapProfile* deep_profile);
+ void RecordAllAllocs();
+
+ // Fill re-formatted /proc/self/maps into 'buf' of size 'size'.
+ void WriteMapsToFile(char buf[], int size);
+
+ // Fill a bucket (a bucket id and its corresponding calling stack) into 'buf'
+ // of size 'bufsize'.
+ int FillBucketForBucketFile(const DeepBucket* db, char buf[], int bufsize);
+
+ // Write a bucket table 'table' into a file of 'bucket_fd'.
+ void WriteBucketsTableToBucketFile(Bucket** table, RawFD bucket_fd);
+
+ // Write both malloc and mmap bucket tables into "a bucket file".
+ void WriteBucketsToBucketFile();
+
+ // Fill a (deep) bucket into 'buf' from the offset 'buflen'. Add the sizes
+ // to 'profile_stats' if it's not NULL.
+ static int UnparseBucket(const DeepBucket& b,
+ char* buf, int buflen, int bufsize,
+ const char* extra,
+ Stats* profile_stats);
+
+ // Fill statistics of a region into 'buf'.
+ static int UnparseRegionStats(const RegionStats* stats, const char* name,
+ char* buf, int buflen, int bufsize);
+
+ // Fill global statistics into 'buf'.
+ int UnparseGlobalStats(char* buf, int buflen, int bufsize);
+
+#endif // DEEP_HEAP_PROFILE
+ HeapProfileTable* heap_profile_;
+#ifdef DEEP_HEAP_PROFILE
+
+ int pagemap_fd_; // File descriptor of /proc/self/pagemap.
+ pid_t most_recent_pid_; // Process ID of the last dump. This could change.
+ 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
+
+ DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile);
+};
+
+#endif // BASE_DEEP_HEAP_PROFILE_H_

Powered by Google App Engine
This is Rietveld 408576698