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

Side by Side Diff: base/trace_event/heap_profiler_stack_frame_deduplicator_unittest.cc

Issue 2977783002: [tracing] Optimize StackFrameDeduplicator. (Closed)
Patch Set: Don't use ASSERT_EQ on deque iterators (see goo.gl/9gkBf7) Created 3 years, 5 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" 5 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 StackFrame null_bt[] = {kNull}; 99 StackFrame null_bt[] = {kNull};
100 100
101 // Empty backtraces (begin == end) are mapped to an implicitly added 101 // Empty backtraces (begin == end) are mapped to an implicitly added
102 // node #0. However, backtrace with a single null frame is not empty, 102 // node #0. However, backtrace with a single null frame is not empty,
103 // and should be mapped to some other id. 103 // and should be mapped to some other id.
104 104
105 StringDeduplicator string_dedup; 105 StringDeduplicator string_dedup;
106 StackFrameDeduplicator dedup(&string_dedup); 106 StackFrameDeduplicator dedup(&string_dedup);
107 107
108 // Node #0 is added implicitly and corresponds to an empty backtrace. 108 // Node #0 is added implicitly and corresponds to an empty backtrace.
109 ASSERT_EQ(dedup.begin() + 1, dedup.end()); 109 ASSERT_TRUE(dedup.begin() + 1 == dedup.end());
110 ASSERT_EQ(0, dedup.Insert(std::begin(null_bt), std::begin(null_bt))); 110 ASSERT_EQ(0, dedup.Insert(std::begin(null_bt), std::begin(null_bt)));
111 111
112 // Placeholder entry for ID 0 is a frame with NULL name and no parent. 112 // Placeholder entry for ID 0 is a frame with NULL name and no parent.
113 // However inserting such a frame should yield a different ID. 113 // However inserting such a frame should yield a different ID.
114 ExpectIncrementalEntries(&dedup, &string_dedup, {{0, kNull}}); 114 ExpectIncrementalEntries(&dedup, &string_dedup, {{0, kNull}});
115 ASSERT_EQ(1, dedup.Insert(std::begin(null_bt), std::end(null_bt))); 115 ASSERT_EQ(1, dedup.Insert(std::begin(null_bt), std::end(null_bt)));
116 } 116 }
117 117
118 TEST(StackFrameDeduplicatorTest, SingleBacktrace) { 118 TEST(StackFrameDeduplicatorTest, SingleBacktrace) {
119 StackFrame bt[] = {kBrowserMain, kCreateWidget, kMalloc}; 119 StackFrame bt[] = {kBrowserMain, kCreateWidget, kMalloc};
(...skipping 11 matching lines...) Expand all
131 auto iter = dedup.begin() + 1; // skip implicit node #0 131 auto iter = dedup.begin() + 1; // skip implicit node #0
132 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); 132 ASSERT_EQ(kBrowserMain, (iter + 0)->frame);
133 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index); 133 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index);
134 134
135 ASSERT_EQ(kCreateWidget, (iter + 1)->frame); 135 ASSERT_EQ(kCreateWidget, (iter + 1)->frame);
136 ASSERT_EQ(1, (iter + 1)->parent_frame_index); 136 ASSERT_EQ(1, (iter + 1)->parent_frame_index);
137 137
138 ASSERT_EQ(kMalloc, (iter + 2)->frame); 138 ASSERT_EQ(kMalloc, (iter + 2)->frame);
139 ASSERT_EQ(2, (iter + 2)->parent_frame_index); 139 ASSERT_EQ(2, (iter + 2)->parent_frame_index);
140 140
141 ASSERT_EQ(iter + 3, dedup.end()); 141 ASSERT_TRUE(iter + 3 == dedup.end());
142 } 142 }
143 143
144 TEST(StackFrameDeduplicatorTest, SingleBacktraceWithNull) { 144 TEST(StackFrameDeduplicatorTest, SingleBacktraceWithNull) {
145 StackFrame null_frame = StackFrame::FromTraceEventName(nullptr); 145 StackFrame null_frame = StackFrame::FromTraceEventName(nullptr);
146 StackFrame bt[] = {kBrowserMain, null_frame, kMalloc}; 146 StackFrame bt[] = {kBrowserMain, null_frame, kMalloc};
147 147
148 // Deduplicator doesn't care about what's inside StackFrames, 148 // Deduplicator doesn't care about what's inside StackFrames,
149 // and handles nullptr StackFrame values as any other. 149 // and handles nullptr StackFrame values as any other.
150 // 150 //
151 // So the call tree should look like this (index in brackets). 151 // So the call tree should look like this (index in brackets).
152 // 152 //
153 // BrowserMain [1] 153 // BrowserMain [1]
154 // (null) [2] 154 // (null) [2]
155 // malloc [3] 155 // malloc [3]
156 156
157 StringDeduplicator string_dedup; 157 StringDeduplicator string_dedup;
158 StackFrameDeduplicator dedup(&string_dedup); 158 StackFrameDeduplicator dedup(&string_dedup);
159 ASSERT_EQ(3, dedup.Insert(std::begin(bt), std::end(bt))); 159 ASSERT_EQ(3, dedup.Insert(std::begin(bt), std::end(bt)));
160 160
161 auto iter = dedup.begin() + 1; // skip implicit node #0 161 auto iter = dedup.begin() + 1; // skip implicit node #0
162 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); 162 ASSERT_EQ(kBrowserMain, (iter + 0)->frame);
163 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index); 163 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index);
164 164
165 ASSERT_EQ(null_frame, (iter + 1)->frame); 165 ASSERT_EQ(null_frame, (iter + 1)->frame);
166 ASSERT_EQ(1, (iter + 1)->parent_frame_index); 166 ASSERT_EQ(1, (iter + 1)->parent_frame_index);
167 167
168 ASSERT_EQ(kMalloc, (iter + 2)->frame); 168 ASSERT_EQ(kMalloc, (iter + 2)->frame);
169 ASSERT_EQ(2, (iter + 2)->parent_frame_index); 169 ASSERT_EQ(2, (iter + 2)->parent_frame_index);
170 170
171 ASSERT_EQ(iter + 3, dedup.end()); 171 ASSERT_TRUE(iter + 3 == dedup.end());
172 } 172 }
173 173
174 // Test that there can be different call trees (there can be multiple bottom 174 // Test that there can be different call trees (there can be multiple bottom
175 // frames). Also verify that frames with the same name but a different caller 175 // frames). Also verify that frames with the same name but a different caller
176 // are represented as distinct nodes. 176 // are represented as distinct nodes.
177 TEST(StackFrameDeduplicatorTest, MultipleRoots) { 177 TEST(StackFrameDeduplicatorTest, MultipleRoots) {
178 StackFrame bt0[] = {kBrowserMain, kCreateWidget}; 178 StackFrame bt0[] = {kBrowserMain, kCreateWidget};
179 StackFrame bt1[] = {kRendererMain, kCreateWidget}; 179 StackFrame bt1[] = {kRendererMain, kCreateWidget};
180 180
181 // The call tree should look like this (index in brackets). 181 // The call tree should look like this (index in brackets).
(...skipping 17 matching lines...) Expand all
199 199
200 ASSERT_EQ(kCreateWidget, (iter + 1)->frame); 200 ASSERT_EQ(kCreateWidget, (iter + 1)->frame);
201 ASSERT_EQ(1, (iter + 1)->parent_frame_index); 201 ASSERT_EQ(1, (iter + 1)->parent_frame_index);
202 202
203 ASSERT_EQ(kRendererMain, (iter + 2)->frame); 203 ASSERT_EQ(kRendererMain, (iter + 2)->frame);
204 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 2)->parent_frame_index); 204 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 2)->parent_frame_index);
205 205
206 ASSERT_EQ(kCreateWidget, (iter + 3)->frame); 206 ASSERT_EQ(kCreateWidget, (iter + 3)->frame);
207 ASSERT_EQ(3, (iter + 3)->parent_frame_index); 207 ASSERT_EQ(3, (iter + 3)->parent_frame_index);
208 208
209 ASSERT_EQ(iter + 4, dedup.end()); 209 ASSERT_TRUE(iter + 4 == dedup.end());
210 } 210 }
211 211
212 TEST(StackFrameDeduplicatorTest, Deduplication) { 212 TEST(StackFrameDeduplicatorTest, Deduplication) {
213 StackFrame bt0[] = {kBrowserMain, kCreateWidget}; 213 StackFrame bt0[] = {kBrowserMain, kCreateWidget};
214 StackFrame bt1[] = {kBrowserMain, kInitialize}; 214 StackFrame bt1[] = {kBrowserMain, kInitialize};
215 215
216 // The call tree should look like this (index in brackets). 216 // The call tree should look like this (index in brackets).
217 // 217 //
218 // BrowserMain [1] 218 // BrowserMain [1]
219 // CreateWidget [2] 219 // CreateWidget [2]
220 // Initialize [3] 220 // Initialize [3]
221 // 221 //
222 // Note that BrowserMain will be re-used. 222 // Note that BrowserMain will be re-used.
223 223
224 StringDeduplicator string_dedup; 224 StringDeduplicator string_dedup;
225 StackFrameDeduplicator dedup(&string_dedup); 225 StackFrameDeduplicator dedup(&string_dedup);
226 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0))); 226 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0)));
227 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1))); 227 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1)));
228 228
229 auto iter = dedup.begin() + 1; // skip implicit node #0 229 auto iter = dedup.begin() + 1; // skip implicit node #0
230 ASSERT_EQ(kBrowserMain, (iter + 0)->frame); 230 ASSERT_EQ(kBrowserMain, (iter + 0)->frame);
231 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index); 231 ASSERT_EQ(kInvalidStackFrameIndex, (iter + 0)->parent_frame_index);
232 232
233 ASSERT_EQ(kCreateWidget, (iter + 1)->frame); 233 ASSERT_EQ(kCreateWidget, (iter + 1)->frame);
234 ASSERT_EQ(1, (iter + 1)->parent_frame_index); 234 ASSERT_EQ(1, (iter + 1)->parent_frame_index);
235 235
236 ASSERT_EQ(kInitialize, (iter + 2)->frame); 236 ASSERT_EQ(kInitialize, (iter + 2)->frame);
237 ASSERT_EQ(1, (iter + 2)->parent_frame_index); 237 ASSERT_EQ(1, (iter + 2)->parent_frame_index);
238 238
239 ASSERT_EQ(iter + 3, dedup.end()); 239 ASSERT_TRUE(iter + 3 == dedup.end());
240 240
241 // Inserting the same backtrace again should return the index of the existing 241 // Inserting the same backtrace again should return the index of the existing
242 // node. 242 // node.
243 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0))); 243 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0)));
244 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1))); 244 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1)));
245 ASSERT_EQ(4 /* 1 implicit + 3 added */, dedup.end() - dedup.begin()); 245 ASSERT_EQ(4 /* 1 implicit + 3 added */, dedup.end() - dedup.begin());
246 } 246 }
247 247
248 TEST(StackFrameDeduplicatorTest, SerializeIncrementally) { 248 TEST(StackFrameDeduplicatorTest, SerializeIncrementally) {
249 StringDeduplicator string_dedup; 249 StringDeduplicator string_dedup;
250 StackFrameDeduplicator dedup(&string_dedup); 250 StackFrameDeduplicator dedup(&string_dedup);
251 251
252 StackFrame bt0[] = {kBrowserMain, kCreateWidget}; 252 StackFrame bt0[] = {kBrowserMain, kCreateWidget};
253 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0))); 253 ASSERT_EQ(2, dedup.Insert(std::begin(bt0), std::end(bt0)));
254 254
255 ExpectIncrementalEntries( 255 ExpectIncrementalEntries(
256 &dedup, &string_dedup, 256 &dedup, &string_dedup,
257 {{0, kNull}, {1, kBrowserMain}, {2, kCreateWidget, 1}}); 257 {{0, kNull}, {1, kBrowserMain}, {2, kCreateWidget, 1}});
258 258
259 StackFrame bt1[] = {kBrowserMain, kInitialize}; 259 StackFrame bt1[] = {kBrowserMain, kInitialize};
260 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1))); 260 ASSERT_EQ(3, dedup.Insert(std::begin(bt1), std::end(bt1)));
261 261
262 ExpectIncrementalEntries(&dedup, &string_dedup, {{3, kInitialize, 1}}); 262 ExpectIncrementalEntries(&dedup, &string_dedup, {{3, kInitialize, 1}});
263 263
264 ExpectIncrementalEntries(&dedup, &string_dedup, {}); 264 ExpectIncrementalEntries(&dedup, &string_dedup, {});
265 } 265 }
266 266
267 } // namespace trace_event 267 } // namespace trace_event
268 } // namespace base 268 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/heap_profiler_stack_frame_deduplicator.cc ('k') | base/trace_event/memory_usage_estimator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698