Index: third_party/tcmalloc/chromium/src/heap-profile-table.cc |
diff --git a/third_party/tcmalloc/chromium/src/heap-profile-table.cc b/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
index 6d75c4a49a861320dd2eb500e9a23058ef54fd07..d0edc2a3bb56e82cbbe2b339c47b03587ee30919 100644 |
--- a/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
+++ b/third_party/tcmalloc/chromium/src/heap-profile-table.cc |
@@ -67,6 +67,10 @@ |
#include "base/logging.h" // for the RawFD I/O commands |
#include "base/sysinfo.h" |
+#ifdef DEEP_PROFILER_ON |
+#include "deep-memory-profiler.h" |
+#endif |
+ |
using std::sort; |
using std::equal; |
using std::copy; |
@@ -129,6 +133,11 @@ HeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc) |
// Make allocation map |
allocation_ = |
new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_); |
+ |
+ allocation_mmap_ = |
+ new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_); |
+ mmap_record_ = false; |
+ |
// init the rest: |
memset(&total_, 0, sizeof(total_)); |
num_buckets_ = 0; |
@@ -139,6 +148,11 @@ HeapProfileTable::~HeapProfileTable() { |
allocation_->~AllocationMap(); |
dealloc_(allocation_); |
allocation_ = NULL; |
+ |
+ allocation_mmap_->~AllocationMap(); |
+ dealloc_(allocation_mmap_); |
+ allocation_mmap_ = NULL; |
+ |
// free hash table |
for (int b = 0; b < kHashTableSize; b++) { |
for (Bucket* x = table_[b]; x != 0; /**/) { |
@@ -184,6 +198,10 @@ HeapProfileTable::Bucket* HeapProfileTable::GetBucket(int depth, |
b->depth = depth; |
b->stack = kcopy; |
b->next = table_[buck]; |
+#ifdef DEEP_PROFILER_ON |
+ b->id = num_buckets_; |
+ b->is_logged = false; |
+#endif |
table_[buck] = b; |
num_buckets_++; |
return b; |
@@ -209,12 +227,22 @@ void HeapProfileTable::RecordAllocWithStack( |
AllocValue v; |
v.set_bucket(b); // also did set_live(false); set_ignore(false) |
v.bytes = bytes; |
- allocation_->Insert(ptr, v); |
+ |
+ if(mmap_record_) |
+ allocation_mmap_->Insert(ptr, v); |
+ else |
+ allocation_->Insert(ptr, v); |
} |
void HeapProfileTable::RecordFree(const void* ptr) { |
AllocValue v; |
- if (allocation_->FindAndRemove(ptr, &v)) { |
+ AllocationMap* a; |
+ if(mmap_record_) |
+ a = allocation_mmap_; |
+ else |
+ a = allocation_; |
+ |
+ if(a->FindAndRemove(ptr, &v)){ |
Bucket* b = v.bucket(); |
b->frees++; |
b->free_size += v.bytes; |
@@ -278,7 +306,7 @@ int HeapProfileTable::UnparseBucket(const Bucket& b, |
profile_stats->free_size += b.free_size; |
} |
int printed = |
- snprintf(buf + buflen, bufsize - buflen, "%6d: %8"PRId64" [%6d: %8"PRId64"] @%s", |
+ snprintf(buf + buflen, bufsize - buflen, "%6d: %8"PRId64" [%6d: %8"PRId64"] @%s", |
b.allocs - b.frees, |
b.alloc_size - b.free_size, |
b.allocs, |
@@ -300,9 +328,12 @@ int HeapProfileTable::UnparseBucket(const Bucket& b, |
} |
HeapProfileTable::Bucket** |
-HeapProfileTable::MakeSortedBucketList() const { |
+HeapProfileTable::MakeBucketList() const { |
+ // We allocate memory for (num_buckets_ + 1) buckets |
+ // because this allocations itself could create a new bucket. |
+ // There is no harm even if it doesn't create a new bucket. |
Bucket** list = |
- reinterpret_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_)); |
+ reinterpret_cast<Bucket**>(alloc_(sizeof(Bucket) * (num_buckets_ + 1))); |
int n = 0; |
for (int b = 0; b < kHashTableSize; b++) { |
@@ -312,6 +343,12 @@ HeapProfileTable::MakeSortedBucketList() const { |
} |
RAW_DCHECK(n == num_buckets_, ""); |
+ return list; |
+} |
+ |
+HeapProfileTable::Bucket** |
+HeapProfileTable::MakeSortedBucketList() const { |
+ Bucket** list = MakeBucketList(); |
sort(list, list + num_buckets_, ByAllocatedSpace); |
return list; |
@@ -431,7 +468,14 @@ bool HeapProfileTable::WriteProfile(const char* file_name, |
void HeapProfileTable::CleanupOldProfiles(const char* prefix) { |
if (!FLAGS_cleanup_old_heap_profiles) |
return; |
+#ifndef DEEP_PROFILER_ON |
string pattern = string(prefix) + ".*" + kFileExt; |
+#else |
+ char buf[1000]; |
+ snprintf(buf, 1000,"%s.%05d.", prefix, getpid()); |
+ string pattern = string(buf) + ".*" + kFileExt; |
+#endif |
+ |
#if defined(HAVE_GLOB_H) |
glob_t g; |
const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g); |