| 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/memory_dump_session_state.h" |
| 19 #include "base/trace_event/trace_event_argument.h" | 20 #include "base/trace_event/trace_event_argument.h" |
| 20 #include "base/values.h" | 21 #include "base/values.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 using base::trace_event::StackFrame; | 26 using base::trace_event::StackFrame; |
| 26 | 27 |
| 27 // Define all strings once, because the deduplicator requires pointer equality, | 28 // Define all strings once, because the deduplicator requires pointer equality, |
| 28 // and string interning is unreliable. | 29 // and string interning is unreliable. |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 // | 211 // |
| 211 // | | CrWidget <- BrMain | Init <- RenMain | Sum | | 212 // | | CrWidget <- BrMain | Init <- RenMain | Sum | |
| 212 // +--------+--------------------+-----------------+-------------+ | 213 // +--------+--------------------+-----------------+-------------+ |
| 213 // | | size count | size count | size count | | 214 // | | size count | size count | size count | |
| 214 // | int | 10 5 | 0 0 | 10 5 | | 215 // | int | 10 5 | 0 0 | 10 5 | |
| 215 // | bool | 18 18 | 30 30 | 48 48 | | 216 // | bool | 18 18 | 30 30 | 48 48 | |
| 216 // | string | 0 0 | 19 4 | 19 4 | | 217 // | string | 0 0 | 19 4 | 19 4 | |
| 217 // +--------+--------------------+-----------------+-------------+ | 218 // +--------+--------------------+-----------------+-------------+ |
| 218 // | Sum | 28 23 | 49 34 | 77 57 | | 219 // | Sum | 28 23 | 49 34 | 77 57 | |
| 219 | 220 |
| 220 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 221 auto stack_frame_deduplicator = WrapUnique(new StackFrameDeduplicator); |
| 221 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 222 auto type_name_deduplicator = WrapUnique(new TypeNameDeduplicator); |
| 222 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 223 HeapDumpWriter writer(stack_frame_deduplicator.get(), |
| 224 type_name_deduplicator.get(), |
| 225 10u); |
| 223 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); | 226 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 224 | 227 |
| 225 // Get the indices of the backtraces and types by adding them again to the | 228 // Get the indices of the backtraces and types by adding them again to the |
| 226 // deduplicator. Because they were added before, the same number is returned. | 229 // deduplicator. Because they were added before, the same number is returned. |
| 227 StackFrame bt0[] = {kRendererMain, kInitialize}; | 230 StackFrame bt0[] = {kRendererMain, kInitialize}; |
| 228 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; | 231 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; |
| 229 int bt_renderer_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 232 int bt_renderer_main = stack_frame_deduplicator->Insert(bt0, bt0 + 1); |
| 230 int bt_browser_main = sf_deduplicator->Insert(bt1, bt1 + 1); | 233 int bt_browser_main = stack_frame_deduplicator->Insert(bt1, bt1 + 1); |
| 231 int bt_renderer_main_initialize = sf_deduplicator->Insert(bt0, bt0 + 2); | 234 int bt_renderer_main_initialize = |
| 232 int bt_browser_main_create_widget = sf_deduplicator->Insert(bt1, bt1 + 2); | 235 stack_frame_deduplicator->Insert(bt0, bt0 + 2); |
| 233 int type_id_int = tn_deduplicator->Insert(kInt); | 236 int bt_browser_main_create_widget = |
| 234 int type_id_bool = tn_deduplicator->Insert(kBool); | 237 stack_frame_deduplicator->Insert(bt1, bt1 + 2); |
| 235 int type_id_string = tn_deduplicator->Insert(kString); | 238 int type_id_int = type_name_deduplicator->Insert(kInt); |
| 239 int type_id_bool = type_name_deduplicator->Insert(kBool); |
| 240 int type_id_string = type_name_deduplicator->Insert(kString); |
| 236 | 241 |
| 237 // Full heap should have size 77. | 242 // Full heap should have size 77. |
| 238 AssertSizeAndCountEq(dump, -1, -1, {77, 57}); | 243 AssertSizeAndCountEq(dump, -1, -1, {77, 57}); |
| 239 | 244 |
| 240 // 49 bytes in 34 chunks were allocated in RendererMain and children. Also | 245 // 49 bytes in 34 chunks were allocated in RendererMain and children. Also |
| 241 // check the type breakdown. | 246 // check the type breakdown. |
| 242 AssertSizeAndCountEq(dump, bt_renderer_main, -1, {49, 34}); | 247 AssertSizeAndCountEq(dump, bt_renderer_main, -1, {49, 34}); |
| 243 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_bool, {30, 30}); | 248 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_bool, {30, 30}); |
| 244 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_string, {19, 4}); | 249 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_string, {19, 4}); |
| 245 | 250 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 ctx.backtrace.frame_count = 2; | 282 ctx.backtrace.frame_count = 2; |
| 278 | 283 |
| 279 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget itself. | 284 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget itself. |
| 280 metrics_by_context[ctx] = {512, 1}; | 285 metrics_by_context[ctx] = {512, 1}; |
| 281 | 286 |
| 282 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. | 287 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. |
| 283 ctx.backtrace.frames[2] = kGetBitmap; | 288 ctx.backtrace.frames[2] = kGetBitmap; |
| 284 ctx.backtrace.frame_count = 3; | 289 ctx.backtrace.frame_count = 3; |
| 285 metrics_by_context[ctx] = {1024 * 1024, 1}; | 290 metrics_by_context[ctx] = {1024 * 1024, 1}; |
| 286 | 291 |
| 287 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. | 292 // 400B and 1 chunk in BrowserMain -> CreateWidget -> Initialize. |
| 288 ctx.backtrace.frames[2] = kInitialize; | 293 ctx.backtrace.frames[2] = kInitialize; |
| 289 ctx.backtrace.frame_count = 3; | 294 ctx.backtrace.frame_count = 3; |
| 290 metrics_by_context[ctx] = {512, 1}; | 295 metrics_by_context[ctx] = {400, 1}; |
| 291 | 296 |
| 292 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 297 auto stack_frame_deduplicator = WrapUnique(new StackFrameDeduplicator); |
| 293 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 298 auto type_name_deduplicator = WrapUnique(new TypeNameDeduplicator); |
| 294 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 299 HeapDumpWriter writer(stack_frame_deduplicator.get(), |
| 300 type_name_deduplicator.get(), |
| 301 512u); |
| 295 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); | 302 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 296 | 303 |
| 297 // Get the indices of the backtraces and types by adding them again to the | 304 // Get the indices of the backtraces and types by adding them again to the |
| 298 // deduplicator. Because they were added before, the same number is returned. | 305 // deduplicator. Because they were added before, the same number is returned. |
| 299 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; | 306 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; |
| 300 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; | 307 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; |
| 301 int bt_browser_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 308 int bt_browser_main = stack_frame_deduplicator->Insert(bt0, bt0 + 1); |
| 302 int bt_create_widget = sf_deduplicator->Insert(bt0, bt0 + 2); | 309 int bt_create_widget = stack_frame_deduplicator->Insert(bt0, bt0 + 2); |
| 303 int bt_get_bitmap = sf_deduplicator->Insert(bt0, bt0 + 3); | 310 int bt_get_bitmap = stack_frame_deduplicator->Insert(bt0, bt0 + 3); |
| 304 int bt_initialize = sf_deduplicator->Insert(bt1, bt1 + 3); | 311 int bt_initialize = stack_frame_deduplicator->Insert(bt1, bt1 + 3); |
| 305 | 312 |
| 306 // Full heap should have size of 1 MiB + 1 KiB and 3 chunks. | 313 // Full heap should have size of 1 MiB + .9 KiB and 3 chunks. |
| 307 AssertSizeAndCountEq(dump, -1, -1 /* No type specified */, | 314 AssertSizeAndCountEq(dump, -1, -1 /* No type specified */, |
| 308 {1024 * 1024 + 512 + 512, 3}); | 315 {1024 * 1024 + 512 + 400, 3}); |
| 309 | 316 |
| 310 // |GetBitmap| allocated 1 MiB and 1 chunk. | 317 // |GetBitmap| allocated 1 MiB and 1 chunk. |
| 311 AssertSizeAndCountEq(dump, bt_get_bitmap, -1, {1024 * 1024, 1}); | 318 AssertSizeAndCountEq(dump, bt_get_bitmap, -1, {1024 * 1024, 1}); |
| 312 | 319 |
| 313 // Because |GetBitmap| was dumped, all of its parent nodes should have been | 320 // Because |GetBitmap| was dumped, all of its parent nodes should have been |
| 314 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 512 bytes in | 321 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 400 bytes in |
| 315 // |Initialize|, and 512 bytes of its own and each in 1 chunk. | 322 // |Initialize|, and 512 bytes of its own and each in 1 chunk. |
| 316 AssertSizeAndCountEq(dump, bt_create_widget, -1, | 323 AssertSizeAndCountEq(dump, bt_create_widget, -1, |
| 317 {1024 * 1024 + 512 + 512, 3}); | 324 {1024 * 1024 + 400 + 512, 3}); |
| 318 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); | 325 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 400 + 512, 3}); |
| 319 | 326 |
| 320 // Initialize was not significant, it should not have been dumped. | 327 // Initialize was not significant, it should not have been dumped. |
| 321 AssertNotDumped(dump, bt_initialize, -1); | 328 AssertNotDumped(dump, bt_initialize, -1); |
| 322 } | 329 } |
| 323 | 330 |
| 324 } // namespace internal | 331 } // namespace internal |
| 325 } // namespace trace_event | 332 } // namespace trace_event |
| 326 } // namespace base | 333 } // namespace base |
| OLD | NEW |