Chromium Code Reviews| 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..adbed702679c46f44301f3a5250eec91369151aa |
| --- /dev/null |
| +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.h |
| @@ -0,0 +1,141 @@ |
| +// 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. |
| + |
| +#ifndef BASE_DEEP_HEAP_PROFILE_H_ |
| +#define BASE_DEEP_HEAP_PROFILE_H_ |
| + |
| +#include <config.h> |
| + |
| +#if defined(__linux__) |
| +#define DEEP_HEAP_PROFILE 1 |
|
Alexander Potapenko
2011/12/20 13:57:23
What does your code do if DEEP_HEAP_PROFILE is 0?
Dai Mikurube (NOT FULLTIME)
2011/12/21 09:13:49
If 0, only the constructor, the destructor and Fil
|
| +#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; |
| + |
| + DeepHeapProfile(HeapProfileTable* heap_profile, const char* prefix); |
| + ~DeepHeapProfile(); |
| + |
| + // This replaces the same function in heap-profile-table.h |
| + int FillOrderedProfile(char buf[], int size); |
| + |
| + private: |
| +#ifdef DEEP_HEAP_PROFILE |
| + struct DeepBucket { |
| + Bucket* bucket; |
| + int64 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; |
| + }; |
| + |
| + typedef AddressMap<PageState> PageStateMap; |
| + |
| + // This represents a single line of /proc/self/maps |
| + struct RegionValue { |
| + uint64 start; |
| + uint64 end; |
| + uint64 size; |
| + uint64 committed_size; |
| + uint64 recorded_size; |
| + uint64 recorded_committed_size; |
| + char permissions[5]; |
| + char filename[1000]; |
| + }; |
| + |
| + typedef AddressMap<RegionValue> RegionMap; |
| + |
| + struct RegionStats { |
| + int64 virtual_bytes; |
| + int64 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; |
| + }; |
| + |
| + DeepBucket* GetDeepBucket(Bucket* bucket); |
| + void ResetCommittedSize(Bucket** table); |
| + int FillBucketTable(Bucket** table, char buf[], int size, int bucket_length, |
| + HeapProfileTable::Stats* stats); |
| + |
| + // Functions for opening, seeking, reading /proc/pid/pagemap |
| + void OpenProcPagemap(); |
| + bool SeekProcPagemap(uint64 addr); |
| + bool ReadProcPagemap(PageState* state); |
| + uint64 GetCommittedSize(uint64 addr, uint64 size); |
| + |
| + void InitRegionStats(RegionStats* stats); |
| + void RecordRegionStats(uint64 start, uint64 end, RegionStats* stats); |
| + void GetGlobalStats(); |
| + static size_t GetRegionSize(const RegionValue& rv) { return rv.size; } |
| + |
| + // Record the committed memory size of each allocations |
| + static void RecordAlloc(const void* ptr, AllocValue* v, |
| + DeepHeapProfile* deep_profile); |
| + static void RecordMMap(const void* ptr, AllocValue* v, |
| + DeepHeapProfile* deep_profile); |
| + void RecordAllAllocs(); |
| + |
| + void WriteMapsToFile(char buf[], int size); |
| + |
| + int FillBucketForBucketFile(const DeepBucket* db, char buf[], int bufsize); |
| + void WriteBucketsTableToBucketFile(Bucket** table, RawFD bucket_fd); |
| + void WriteBucketsToBucketFile(); |
| + |
| + static int UnparseBucket(const DeepBucket& b, |
| + char* buf, int buflen, int bufsize, |
| + const char* extra, |
| + Stats* profile_stats); |
| + |
| + static int UnparseRegionStats(const RegionStats* stats, const char* name, |
| + char* buf, int buflen, int bufsize); |
| + |
| + 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 |
| + PageStateMap* page_map_; // Map for holding status of allocations in page |
| + 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 |
| +}; |
| + |
| +#endif // BASE_DEEP_HEAP_PROFILE_H_ |