OLD | NEW |
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_heap_dump_writer.h" | 5 #include "base/trace_event/heap_profiler_heap_dump_writer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <set> | 10 #include <set> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/trace_event/heap_profiler_allocation_context.h" | 16 #include "base/trace_event/heap_profiler_allocation_context.h" |
17 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" | 17 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" |
18 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" | 18 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" |
19 #include "base/trace_event/trace_event_argument.h" | 19 #include "base/trace_event/trace_event_argument.h" |
20 #include "base/values.h" | 20 #include "base/values.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
| 25 using base::trace_event::StackFrame; |
| 26 |
25 // Define all strings once, because the deduplicator requires pointer equality, | 27 // Define all strings once, because the deduplicator requires pointer equality, |
26 // and string interning is unreliable. | 28 // and string interning is unreliable. |
27 const char kBrowserMain[] = "BrowserMain"; | 29 StackFrame kBrowserMain = StackFrame::FromTraceEventName("BrowserMain"); |
28 const char kRendererMain[] = "RendererMain"; | 30 StackFrame kRendererMain = StackFrame::FromTraceEventName("RendererMain"); |
29 const char kCreateWidget[] = "CreateWidget"; | 31 StackFrame kCreateWidget = StackFrame::FromTraceEventName("CreateWidget"); |
30 const char kInitialize[] = "Initialize"; | 32 StackFrame kInitialize = StackFrame::FromTraceEventName("Initialize"); |
31 const char kGetBitmap[] = "GetBitmap"; | 33 StackFrame kGetBitmap = StackFrame::FromTraceEventName("GetBitmap"); |
32 | 34 |
33 const char kInt[] = "int"; | 35 const char kInt[] = "int"; |
34 const char kBool[] = "bool"; | 36 const char kBool[] = "bool"; |
35 const char kString[] = "string"; | 37 const char kString[] = "string"; |
36 | 38 |
37 } // namespace | 39 } // namespace |
38 | 40 |
39 namespace base { | 41 namespace base { |
40 namespace trace_event { | 42 namespace trace_event { |
41 namespace internal { | 43 namespace internal { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 ASSERT_TRUE(json_entry->GetString("count", &count)); | 176 ASSERT_TRUE(json_entry->GetString("count", &count)); |
175 ASSERT_EQ(large_value_str, count); | 177 ASSERT_EQ(large_value_str, count); |
176 } | 178 } |
177 | 179 |
178 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { | 180 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { |
179 hash_map<AllocationContext, AllocationMetrics> metrics_by_context; | 181 hash_map<AllocationContext, AllocationMetrics> metrics_by_context; |
180 | 182 |
181 AllocationContext ctx = AllocationContext::Empty(); | 183 AllocationContext ctx = AllocationContext::Empty(); |
182 ctx.backtrace.frames[0] = kBrowserMain; | 184 ctx.backtrace.frames[0] = kBrowserMain; |
183 ctx.backtrace.frames[1] = kCreateWidget; | 185 ctx.backtrace.frames[1] = kCreateWidget; |
| 186 ctx.backtrace.frame_count = 2; |
184 ctx.type_name = kInt; | 187 ctx.type_name = kInt; |
185 | 188 |
186 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. | 189 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. |
187 metrics_by_context[ctx] = {10, 5}; | 190 metrics_by_context[ctx] = {10, 5}; |
188 | 191 |
189 ctx.type_name = kBool; | 192 ctx.type_name = kBool; |
190 | 193 |
191 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. | 194 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. |
192 metrics_by_context[ctx] = {18, 18}; | 195 metrics_by_context[ctx] = {18, 18}; |
193 | 196 |
194 ctx.backtrace.frames[0] = kRendererMain; | 197 ctx.backtrace.frames[0] = kRendererMain; |
195 ctx.backtrace.frames[1] = kInitialize; | 198 ctx.backtrace.frames[1] = kInitialize; |
| 199 ctx.backtrace.frame_count = 2; |
196 | 200 |
197 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. | 201 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. |
198 metrics_by_context[ctx] = {30, 30}; | 202 metrics_by_context[ctx] = {30, 30}; |
199 | 203 |
200 ctx.type_name = kString; | 204 ctx.type_name = kString; |
201 | 205 |
202 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. | 206 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. |
203 metrics_by_context[ctx] = {19, 4}; | 207 metrics_by_context[ctx] = {19, 4}; |
204 | 208 |
205 // At this point the heap looks like this: | 209 // At this point the heap looks like this: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 AssertSizeAndCountEq(dump, -1, type_id_bool, {48, 48}); | 267 AssertSizeAndCountEq(dump, -1, type_id_bool, {48, 48}); |
264 AssertSizeAndCountEq(dump, -1, type_id_string, {19, 4}); | 268 AssertSizeAndCountEq(dump, -1, type_id_string, {19, 4}); |
265 } | 269 } |
266 | 270 |
267 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { | 271 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { |
268 hash_map<AllocationContext, AllocationMetrics> metrics_by_context; | 272 hash_map<AllocationContext, AllocationMetrics> metrics_by_context; |
269 | 273 |
270 AllocationContext ctx = AllocationContext::Empty(); | 274 AllocationContext ctx = AllocationContext::Empty(); |
271 ctx.backtrace.frames[0] = kBrowserMain; | 275 ctx.backtrace.frames[0] = kBrowserMain; |
272 ctx.backtrace.frames[1] = kCreateWidget; | 276 ctx.backtrace.frames[1] = kCreateWidget; |
| 277 ctx.backtrace.frame_count = 2; |
273 | 278 |
274 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget itself. | 279 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget itself. |
275 metrics_by_context[ctx] = {512, 1}; | 280 metrics_by_context[ctx] = {512, 1}; |
276 | 281 |
277 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. | 282 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. |
278 ctx.backtrace.frames[2] = kGetBitmap; | 283 ctx.backtrace.frames[2] = kGetBitmap; |
| 284 ctx.backtrace.frame_count = 3; |
279 metrics_by_context[ctx] = {1024 * 1024, 1}; | 285 metrics_by_context[ctx] = {1024 * 1024, 1}; |
280 | 286 |
281 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. | 287 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. |
282 ctx.backtrace.frames[2] = kInitialize; | 288 ctx.backtrace.frames[2] = kInitialize; |
| 289 ctx.backtrace.frame_count = 3; |
283 metrics_by_context[ctx] = {512, 1}; | 290 metrics_by_context[ctx] = {512, 1}; |
284 | 291 |
285 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 292 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); |
286 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 293 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); |
287 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 294 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); |
288 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); | 295 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
289 | 296 |
290 // Get the indices of the backtraces and types by adding them again to the | 297 // Get the indices of the backtraces and types by adding them again to the |
291 // deduplicator. Because they were added before, the same number is returned. | 298 // deduplicator. Because they were added before, the same number is returned. |
292 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; | 299 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; |
(...skipping 17 matching lines...) Expand all Loading... |
310 {1024 * 1024 + 512 + 512, 3}); | 317 {1024 * 1024 + 512 + 512, 3}); |
311 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); | 318 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); |
312 | 319 |
313 // Initialize was not significant, it should not have been dumped. | 320 // Initialize was not significant, it should not have been dumped. |
314 AssertNotDumped(dump, bt_initialize, -1); | 321 AssertNotDumped(dump, bt_initialize, -1); |
315 } | 322 } |
316 | 323 |
317 } // namespace internal | 324 } // namespace internal |
318 } // namespace trace_event | 325 } // namespace trace_event |
319 } // namespace base | 326 } // namespace base |
OLD | NEW |