Chromium Code Reviews| 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 // Define all strings once, because the deduplicator requires pointer equality, | 26 // Define all strings once, because the deduplicator requires pointer equality, |
| 26 // and string interning is unreliable. | 27 // and string interning is unreliable. |
| 27 const char kBrowserMain[] = "BrowserMain"; | 28 const char kBrowserMain[] = "BrowserMain"; |
| 28 const char kRendererMain[] = "RendererMain"; | 29 const char kRendererMain[] = "RendererMain"; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 // | 207 // |
| 207 // | | CrWidget <- BrMain | Init <- RenMain | Sum | | 208 // | | CrWidget <- BrMain | Init <- RenMain | Sum | |
| 208 // +--------+--------------------+-----------------+-------------+ | 209 // +--------+--------------------+-----------------+-------------+ |
| 209 // | | size count | size count | size count | | 210 // | | size count | size count | size count | |
| 210 // | int | 10 5 | 0 0 | 10 5 | | 211 // | int | 10 5 | 0 0 | 10 5 | |
| 211 // | bool | 18 18 | 30 30 | 48 48 | | 212 // | bool | 18 18 | 30 30 | 48 48 | |
| 212 // | string | 0 0 | 19 4 | 19 4 | | 213 // | string | 0 0 | 19 4 | 19 4 | |
| 213 // +--------+--------------------+-----------------+-------------+ | 214 // +--------+--------------------+-----------------+-------------+ |
| 214 // | Sum | 28 23 | 49 34 | 77 57 | | 215 // | Sum | 28 23 | 49 34 | 77 57 | |
| 215 | 216 |
| 216 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 217 auto session = new MemoryDumpSessionState(); |
|
Primiano Tucci (use gerrit)
2016/04/22 14:18:28
This is leaking the SessionState now, there is no
Maria
2016/04/25 18:37:23
Acknowledged.
| |
| 217 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 218 session->SetStackFrameDeduplicator(WrapUnique(new StackFrameDeduplicator)); |
| 218 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 219 session->SetTypeNameDeduplicator(WrapUnique(new TypeNameDeduplicator)); |
| 220 HeapDumpWriter writer(*session); | |
|
Primiano Tucci (use gerrit)
2016/04/22 14:18:29
anyways, following my suggestions above, since thi
Maria
2016/04/25 18:37:23
Done.
| |
| 219 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); | 221 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 220 | 222 |
| 221 // Get the indices of the backtraces and types by adding them again to the | 223 // Get the indices of the backtraces and types by adding them again to the |
| 222 // deduplicator. Because they were added before, the same number is returned. | 224 // deduplicator. Because they were added before, the same number is returned. |
| 223 StackFrame bt0[] = {kRendererMain, kInitialize}; | 225 StackFrame bt0[] = {kRendererMain, kInitialize}; |
| 224 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; | 226 StackFrame bt1[] = {kBrowserMain, kCreateWidget}; |
| 225 int bt_renderer_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 227 int bt_renderer_main = session->stack_frame_deduplicator()->Insert(bt0, bt0 + 1); |
| 226 int bt_browser_main = sf_deduplicator->Insert(bt1, bt1 + 1); | 228 int bt_browser_main = session->stack_frame_deduplicator()->Insert(bt1, bt1 + 1 ); |
| 227 int bt_renderer_main_initialize = sf_deduplicator->Insert(bt0, bt0 + 2); | 229 int bt_renderer_main_initialize = session->stack_frame_deduplicator()->Insert( bt0, bt0 + 2); |
| 228 int bt_browser_main_create_widget = sf_deduplicator->Insert(bt1, bt1 + 2); | 230 int bt_browser_main_create_widget = session->stack_frame_deduplicator()->Inser t(bt1, bt1 + 2); |
| 229 int type_id_int = tn_deduplicator->Insert(kInt); | 231 int type_id_int = session->type_name_deduplicator()->Insert(kInt); |
| 230 int type_id_bool = tn_deduplicator->Insert(kBool); | 232 int type_id_bool = session->type_name_deduplicator()->Insert(kBool); |
| 231 int type_id_string = tn_deduplicator->Insert(kString); | 233 int type_id_string = session->type_name_deduplicator()->Insert(kString); |
| 232 | 234 |
| 233 // Full heap should have size 77. | 235 // Full heap should have size 77. |
| 234 AssertSizeAndCountEq(dump, -1, -1, {77, 57}); | 236 AssertSizeAndCountEq(dump, -1, -1, {77, 57}); |
| 235 | 237 |
| 236 // 49 bytes in 34 chunks were allocated in RendererMain and children. Also | 238 // 49 bytes in 34 chunks were allocated in RendererMain and children. Also |
| 237 // check the type breakdown. | 239 // check the type breakdown. |
| 238 AssertSizeAndCountEq(dump, bt_renderer_main, -1, {49, 34}); | 240 AssertSizeAndCountEq(dump, bt_renderer_main, -1, {49, 34}); |
| 239 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_bool, {30, 30}); | 241 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_bool, {30, 30}); |
| 240 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_string, {19, 4}); | 242 AssertSizeAndCountEq(dump, bt_renderer_main, type_id_string, {19, 4}); |
| 241 | 243 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 metrics_by_context[ctx] = {512, 1}; | 277 metrics_by_context[ctx] = {512, 1}; |
| 276 | 278 |
| 277 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. | 279 // 1 MiB and 1 chunk in BrowserMain -> CreateWidget -> GetBitmap. |
| 278 ctx.backtrace.frames[2] = kGetBitmap; | 280 ctx.backtrace.frames[2] = kGetBitmap; |
| 279 metrics_by_context[ctx] = {1024 * 1024, 1}; | 281 metrics_by_context[ctx] = {1024 * 1024, 1}; |
| 280 | 282 |
| 281 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. | 283 // 0.5 KiB and 1 chunk in BrowserMain -> CreateWidget -> Initialize. |
| 282 ctx.backtrace.frames[2] = kInitialize; | 284 ctx.backtrace.frames[2] = kInitialize; |
| 283 metrics_by_context[ctx] = {512, 1}; | 285 metrics_by_context[ctx] = {512, 1}; |
| 284 | 286 |
| 285 auto sf_deduplicator = WrapUnique(new StackFrameDeduplicator); | 287 auto session = new MemoryDumpSessionState(); |
|
Primiano Tucci (use gerrit)
2016/04/22 14:18:29
ditto about leaking, and ditto about might not be
Maria
2016/04/25 18:37:23
Acknowledged.
| |
| 286 auto tn_deduplicator = WrapUnique(new TypeNameDeduplicator); | 288 session->SetStackFrameDeduplicator(WrapUnique(new StackFrameDeduplicator)); |
| 287 HeapDumpWriter writer(sf_deduplicator.get(), tn_deduplicator.get()); | 289 session->SetTypeNameDeduplicator(WrapUnique(new TypeNameDeduplicator)); |
| 290 HeapDumpWriter writer(*session); | |
| 288 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); | 291 const std::set<Entry>& dump = writer.Summarize(metrics_by_context); |
| 289 | 292 |
| 290 // Get the indices of the backtraces and types by adding them again to the | 293 // 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. | 294 // deduplicator. Because they were added before, the same number is returned. |
| 292 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; | 295 StackFrame bt0[] = {kBrowserMain, kCreateWidget, kGetBitmap}; |
| 293 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; | 296 StackFrame bt1[] = {kBrowserMain, kCreateWidget, kInitialize}; |
| 294 int bt_browser_main = sf_deduplicator->Insert(bt0, bt0 + 1); | 297 int bt_browser_main = session->stack_frame_deduplicator()->Insert(bt0, bt0 + 1 ); |
| 295 int bt_create_widget = sf_deduplicator->Insert(bt0, bt0 + 2); | 298 int bt_create_widget = session->stack_frame_deduplicator()->Insert(bt0, bt0 + 2); |
| 296 int bt_get_bitmap = sf_deduplicator->Insert(bt0, bt0 + 3); | 299 int bt_get_bitmap = session->stack_frame_deduplicator()->Insert(bt0, bt0 + 3); |
| 297 int bt_initialize = sf_deduplicator->Insert(bt1, bt1 + 3); | 300 int bt_initialize = session->stack_frame_deduplicator()->Insert(bt1, bt1 + 3); |
| 298 | 301 |
| 299 // Full heap should have size of 1 MiB + 1 KiB and 3 chunks. | 302 // Full heap should have size of 1 MiB + 1 KiB and 3 chunks. |
| 300 AssertSizeAndCountEq(dump, -1, -1 /* No type specified */, | 303 AssertSizeAndCountEq(dump, -1, -1 /* No type specified */, |
| 301 {1024 * 1024 + 512 + 512, 3}); | 304 {1024 * 1024 + 512 + 512, 3}); |
| 302 | 305 |
| 303 // |GetBitmap| allocated 1 MiB and 1 chunk. | 306 // |GetBitmap| allocated 1 MiB and 1 chunk. |
| 304 AssertSizeAndCountEq(dump, bt_get_bitmap, -1, {1024 * 1024, 1}); | 307 AssertSizeAndCountEq(dump, bt_get_bitmap, -1, {1024 * 1024, 1}); |
| 305 | 308 |
| 306 // Because |GetBitmap| was dumped, all of its parent nodes should have been | 309 // Because |GetBitmap| was dumped, all of its parent nodes should have been |
| 307 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 512 bytes in | 310 // dumped too. |CreateWidget| has 1 MiB in |GetBitmap|, 512 bytes in |
| 308 // |Initialize|, and 512 bytes of its own and each in 1 chunk. | 311 // |Initialize|, and 512 bytes of its own and each in 1 chunk. |
| 309 AssertSizeAndCountEq(dump, bt_create_widget, -1, | 312 AssertSizeAndCountEq(dump, bt_create_widget, -1, |
| 310 {1024 * 1024 + 512 + 512, 3}); | 313 {1024 * 1024 + 512 + 512, 3}); |
| 311 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); | 314 AssertSizeAndCountEq(dump, bt_browser_main, -1, {1024 * 1024 + 512 + 512, 3}); |
| 312 | 315 |
| 313 // Initialize was not significant, it should not have been dumped. | 316 // Initialize was not significant, it should not have been dumped. |
| 314 AssertNotDumped(dump, bt_initialize, -1); | 317 AssertNotDumped(dump, bt_initialize, -1); |
| 315 } | 318 } |
| 316 | 319 |
| 317 } // namespace internal | 320 } // namespace internal |
| 318 } // namespace trace_event | 321 } // namespace trace_event |
| 319 } // namespace base | 322 } // namespace base |
| OLD | NEW |