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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 ASSERT_TRUE(json_entry->GetString("size", &size)); | 166 ASSERT_TRUE(json_entry->GetString("size", &size)); |
165 ASSERT_EQ(large_value_str, size); | 167 ASSERT_EQ(large_value_str, size); |
166 } | 168 } |
167 | 169 |
168 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { | 170 TEST(HeapDumpWriterTest, BacktraceTypeNameTable) { |
169 hash_map<AllocationContext, size_t> bytes_by_context; | 171 hash_map<AllocationContext, size_t> bytes_by_context; |
170 | 172 |
171 AllocationContext ctx = AllocationContext::Empty(); | 173 AllocationContext ctx = AllocationContext::Empty(); |
172 ctx.backtrace.frames[0] = kBrowserMain; | 174 ctx.backtrace.frames[0] = kBrowserMain; |
173 ctx.backtrace.frames[1] = kCreateWidget; | 175 ctx.backtrace.frames[1] = kCreateWidget; |
| 176 ctx.backtrace.frame_count = 2; |
174 ctx.type_name = kInt; | 177 ctx.type_name = kInt; |
175 | 178 |
176 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. | 179 // 10 bytes with context { type: int, bt: [BrowserMain, CreateWidget] }. |
177 bytes_by_context[ctx] = 10; | 180 bytes_by_context[ctx] = 10; |
178 | 181 |
179 ctx.type_name = kBool; | 182 ctx.type_name = kBool; |
180 | 183 |
181 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. | 184 // 18 bytes with context { type: bool, bt: [BrowserMain, CreateWidget] }. |
182 bytes_by_context[ctx] = 18; | 185 bytes_by_context[ctx] = 18; |
183 | 186 |
184 ctx.backtrace.frames[0] = kRendererMain; | 187 ctx.backtrace.frames[0] = kRendererMain; |
185 ctx.backtrace.frames[1] = kInitialize; | 188 ctx.backtrace.frames[1] = kInitialize; |
| 189 ctx.backtrace.frame_count = 2; |
186 | 190 |
187 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. | 191 // 30 bytes with context { type: bool, bt: [RendererMain, Initialize] }. |
188 bytes_by_context[ctx] = 30; | 192 bytes_by_context[ctx] = 30; |
189 | 193 |
190 ctx.type_name = kString; | 194 ctx.type_name = kString; |
191 | 195 |
192 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. | 196 // 19 bytes with context { type: string, bt: [RendererMain, Initialize] }. |
193 bytes_by_context[ctx] = 19; | 197 bytes_by_context[ctx] = 19; |
194 | 198 |
195 // At this point the heap looks like this: | 199 // At this point the heap looks like this: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 AssertSizeEq(dump, -1, type_id_bool, 48); | 252 AssertSizeEq(dump, -1, type_id_bool, 48); |
249 AssertSizeEq(dump, -1, type_id_string, 19); | 253 AssertSizeEq(dump, -1, type_id_string, 19); |
250 } | 254 } |
251 | 255 |
252 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { | 256 TEST(HeapDumpWriterTest, InsignificantValuesNotDumped) { |
253 hash_map<AllocationContext, size_t> bytes_by_context; | 257 hash_map<AllocationContext, size_t> bytes_by_context; |
254 | 258 |
255 AllocationContext ctx = AllocationContext::Empty(); | 259 AllocationContext ctx = AllocationContext::Empty(); |
256 ctx.backtrace.frames[0] = kBrowserMain; | 260 ctx.backtrace.frames[0] = kBrowserMain; |
257 ctx.backtrace.frames[1] = kCreateWidget; | 261 ctx.backtrace.frames[1] = kCreateWidget; |
| 262 ctx.backtrace.frame_count = 2; |
258 | 263 |
259 // 0.5a KiB in BrowserMain -> CreateWidget itself. | 264 // 0.5a KiB in BrowserMain -> CreateWidget itself. |
260 bytes_by_context[ctx] = 512; | 265 bytes_by_context[ctx] = 512; |
261 | 266 |
262 // 1 MiB in BrowserMain -> CreateWidget -> GetBitmap. | 267 // 1 MiB in BrowserMain -> CreateWidget -> GetBitmap. |
263 ctx.backtrace.frames[2] = kGetBitmap; | 268 ctx.backtrace.frames[2] = kGetBitmap; |
| 269 ctx.backtrace.frame_count = 3; |
264 bytes_by_context[ctx] = 1024 * 1024; | 270 bytes_by_context[ctx] = 1024 * 1024; |
265 | 271 |
266 // 0.5 KiB in BrowserMain -> CreateWidget -> Initialize. | 272 // 0.5 KiB in BrowserMain -> CreateWidget -> Initialize. |
267 ctx.backtrace.frames[2] = kInitialize; | 273 ctx.backtrace.frames[2] = kInitialize; |
| 274 ctx.backtrace.frame_count = 3; |
268 bytes_by_context[ctx] = 512; | 275 bytes_by_context[ctx] = 512; |
269 | 276 |
270 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 277 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); |
271 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 278 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); |
272 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 279 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); |
273 const std::set<Entry>& dump = writer.Summarize(bytes_by_context); | 280 const std::set<Entry>& dump = writer.Summarize(bytes_by_context); |
274 | 281 |
275 // Get the indices of the backtraces and types by adding them again to the | 282 // Get the indices of the backtraces and types by adding them again to the |
276 // deduplicator. Because they were added before, the same number is returned. | 283 // deduplicator. Because they were added before, the same number is returned. |
277 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; | 284 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; |
(...skipping 15 matching lines...) Expand all Loading... |
293 AssertSizeEq(dump, bt_create_widget, -1, 1024 * 1024 + 512 + 512); | 300 AssertSizeEq(dump, bt_create_widget, -1, 1024 * 1024 + 512 + 512); |
294 AssertSizeEq(dump, bt_browser_main, -1, 1024 * 1024 + 512 + 512); | 301 AssertSizeEq(dump, bt_browser_main, -1, 1024 * 1024 + 512 + 512); |
295 | 302 |
296 // Initialize was not significant, it should not have been dumped. | 303 // Initialize was not significant, it should not have been dumped. |
297 AssertNotDumped(dump, bt_initialize, -1); | 304 AssertNotDumped(dump, bt_initialize, -1); |
298 } | 305 } |
299 | 306 |
300 } // namespace internal | 307 } // namespace internal |
301 } // namespace trace_event | 308 } // namespace trace_event |
302 } // namespace base | 309 } // namespace base |
OLD | NEW |