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

Side by Side Diff: components/metrics/leak_detector/call_stack_table.cc

Issue 986503002: components/metrics: Add runtime memory leak detector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: LeakDetectorImpl stores addrs as uintptr_t; Implement move semantics for RankedList Created 5 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/leak_detector/call_stack_table.h"
6
7 #include <utility>
8
9 #include "base/hash.h"
10
11 namespace leak_detector {
12
13 namespace {
14
15 using ValueType = LeakDetectorValueType;
16
17 // Get the top |kRankedListSize| entries.
18 const int kRankedListSize = 16;
19
20 // Initial number of hash table buckets.
21 const int kInitialHashTableSize = 1999;
22
23 } // namespace
24
25 size_t CallStack::ComputeHash::operator() (const CallStack* call_stack) const {
26 return base::Hash(reinterpret_cast<const char*>(call_stack->stack),
27 sizeof(*(call_stack->stack)) * call_stack->depth);
28 }
29
30 CallStackTable::CallStackTable(int call_stack_suspicion_threshold)
31 : num_allocs_(0),
32 num_frees_(0),
33 entry_map_(kInitialHashTableSize),
34 leak_analyzer_(kRankedListSize, call_stack_suspicion_threshold) {
35 }
36
37 CallStackTable::~CallStackTable() {}
38
39 void CallStackTable::Add(const CallStack* call_stack) {
40 auto iter = entry_map_.find(call_stack);
41 Entry* entry = nullptr;
42 if (iter == entry_map_.end()) {
43 entry = &entry_map_[call_stack];
44 } else {
45 entry = &iter->second;
46 }
47
48 ++entry->net_num_allocs;
49 ++num_allocs_;
50 }
51
52 void CallStackTable::Remove(const CallStack* call_stack) {
53 auto iter = entry_map_.find(call_stack);
54 if (iter == entry_map_.end())
55 return;
56 Entry* entry = &iter->second;
57 --entry->net_num_allocs;
58 ++num_frees_;
59
60 // Delete zero-alloc entries to free up space.
61 if (entry->net_num_allocs == 0)
62 entry_map_.erase(iter);
63 }
64
65 size_t CallStackTable::Dump(const size_t buffer_size, char* buffer) const {
66 size_t size_left = buffer_size;
67
68 if (entry_map_.empty())
69 return size_left;
70
71 int attempted_size =
72 snprintf(buffer, size_left,
73 "Total number of allocations: %u\n"
74 "Total number of frees: %u\n"
75 "Net number of allocations: %u\n"
76 "Total number of distinct stack traces: %zu\n",
77 num_allocs_, num_frees_, num_allocs_ - num_frees_,
78 entry_map_.size());
79 size_left -= attempted_size;
80 buffer += attempted_size;
81
82 if (size_left > 1) {
83 int attempted_size = leak_analyzer_.Dump(size_left, buffer);
84 size_left -= attempted_size;
85 buffer += attempted_size;
86 }
87
88 return buffer_size - size_left;
89 }
90
91 void CallStackTable::TestForLeaks() {
92 // Add all entries to the ranked list.
93 RankedList ranked_list(kRankedListSize);
94
95 for (const auto& entry_pair : entry_map_) {
96 const Entry& entry = entry_pair.second;
97 if (entry.net_num_allocs > 0) {
98 LeakDetectorValueType call_stack_value(entry_pair.first);
99 ranked_list.Add(call_stack_value, entry.net_num_allocs);
100 }
101 }
102 leak_analyzer_.AddSample(std::move(ranked_list));
103 }
104
105 } // namespace leak_detector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698