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/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/allocator/features.h" | 10 #include "base/allocator/features.h" |
11 #include "base/atomic_sequence_num.h" | 11 #include "base/atomic_sequence_num.h" |
12 #include "base/base_switches.h" | 12 #include "base/base_switches.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
15 #include "base/debug/alias.h" | 15 #include "base/debug/alias.h" |
16 #include "base/debug/debugging_flags.h" | 16 #include "base/debug/debugging_flags.h" |
17 #include "base/debug/stack_trace.h" | 17 #include "base/debug/stack_trace.h" |
18 #include "base/debug/thread_heap_usage_tracker.h" | 18 #include "base/debug/thread_heap_usage_tracker.h" |
19 #include "base/memory/ptr_util.h" | 19 #include "base/memory/ptr_util.h" |
20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
21 #include "base/threading/thread_task_runner_handle.h" | 21 #include "base/threading/thread_task_runner_handle.h" |
22 #include "base/trace_event/heap_profiler.h" | 22 #include "base/trace_event/heap_profiler.h" |
23 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 23 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
24 #include "base/trace_event/heap_profiler_event_filter.h" | 24 #include "base/trace_event/heap_profiler_event_filter.h" |
25 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" | 25 #include "base/trace_event/heap_profiler_event_writer.h" |
26 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" | |
27 #include "base/trace_event/malloc_dump_provider.h" | 26 #include "base/trace_event/malloc_dump_provider.h" |
28 #include "base/trace_event/memory_dump_provider.h" | 27 #include "base/trace_event/memory_dump_provider.h" |
29 #include "base/trace_event/memory_dump_scheduler.h" | 28 #include "base/trace_event/memory_dump_scheduler.h" |
30 #include "base/trace_event/memory_dump_session_state.h" | 29 #include "base/trace_event/memory_dump_session_state.h" |
31 #include "base/trace_event/memory_infra_background_whitelist.h" | 30 #include "base/trace_event/memory_infra_background_whitelist.h" |
32 #include "base/trace_event/process_memory_dump.h" | 31 #include "base/trace_event/process_memory_dump.h" |
33 #include "base/trace_event/trace_event.h" | 32 #include "base/trace_event/trace_event.h" |
34 #include "base/trace_event/trace_event_argument.h" | 33 #include "base/trace_event/trace_event_argument.h" |
35 #include "build/build_config.h" | 34 #include "build/build_config.h" |
36 | 35 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 TRACE_EVENT_NESTABLE_ASYNC_END1( | 82 TRACE_EVENT_NESTABLE_ASYNC_END1( |
84 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 83 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
85 TRACE_ID_MANGLE(dump_guid), "success", success); | 84 TRACE_ID_MANGLE(dump_guid), "success", success); |
86 | 85 |
87 if (!wrapped_callback.is_null()) { | 86 if (!wrapped_callback.is_null()) { |
88 wrapped_callback.Run(dump_guid, success); | 87 wrapped_callback.Run(dump_guid, success); |
89 wrapped_callback.Reset(); | 88 wrapped_callback.Reset(); |
90 } | 89 } |
91 } | 90 } |
92 | 91 |
93 // Proxy class which wraps a ConvertableToTraceFormat owned by the | |
94 // |session_state| into a proxy object that can be added to the trace event log. | |
95 // This is to solve the problem that the MemoryDumpSessionState is refcounted | |
96 // but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>. | |
97 template <typename T> | |
98 struct SessionStateConvertableProxy : public ConvertableToTraceFormat { | |
99 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const; | |
100 | |
101 SessionStateConvertableProxy( | |
102 scoped_refptr<MemoryDumpSessionState> session_state, | |
103 GetterFunctPtr getter_function) | |
104 : session_state(session_state), getter_function(getter_function) {} | |
105 | |
106 void AppendAsTraceFormat(std::string* out) const override { | |
107 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out); | |
108 } | |
109 | |
110 void EstimateTraceMemoryOverhead( | |
111 TraceEventMemoryOverhead* overhead) override { | |
112 return (session_state.get()->*getter_function)() | |
113 ->EstimateTraceMemoryOverhead(overhead); | |
114 } | |
115 | |
116 scoped_refptr<MemoryDumpSessionState> session_state; | |
117 GetterFunctPtr const getter_function; | |
118 }; | |
119 | |
120 } // namespace | 92 } // namespace |
121 | 93 |
122 // static | 94 // static |
123 const char* const MemoryDumpManager::kTraceCategory = | 95 const char* const MemoryDumpManager::kTraceCategory = |
124 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 96 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
125 | 97 |
126 // static | 98 // static |
127 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; | 99 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; |
128 | 100 |
129 // static | 101 // static |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 const TraceConfig& trace_config = | 772 const TraceConfig& trace_config = |
801 TraceLog::GetInstance()->GetCurrentTraceConfig(); | 773 TraceLog::GetInstance()->GetCurrentTraceConfig(); |
802 const TraceConfig::MemoryDumpConfig& memory_dump_config = | 774 const TraceConfig::MemoryDumpConfig& memory_dump_config = |
803 trace_config.memory_dump_config(); | 775 trace_config.memory_dump_config(); |
804 scoped_refptr<MemoryDumpSessionState> session_state = | 776 scoped_refptr<MemoryDumpSessionState> session_state = |
805 new MemoryDumpSessionState; | 777 new MemoryDumpSessionState; |
806 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes); | 778 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes); |
807 session_state->set_heap_profiler_breakdown_threshold_bytes( | 779 session_state->set_heap_profiler_breakdown_threshold_bytes( |
808 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes); | 780 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes); |
809 if (heap_profiling_enabled_) { | 781 if (heap_profiling_enabled_) { |
810 // If heap profiling is enabled, the stack frame deduplicator and type name | 782 // TODO(dskiba): support continuous mode (crbug.com/701052) |
811 // deduplicator will be in use. Add a metadata events to write the frames | 783 LOG_IF(ERROR, trace_config.GetTraceRecordMode() != RECORD_CONTINUOUSLY) |
812 // and type IDs. | 784 << "Heap profile format is incremental and doesn't yet support " |
813 session_state->SetStackFrameDeduplicator( | 785 << "continuous mode."; |
814 WrapUnique(new StackFrameDeduplicator)); | 786 session_state->CreateDeduplicators(); |
815 | |
816 session_state->SetTypeNameDeduplicator( | |
817 WrapUnique(new TypeNameDeduplicator)); | |
818 | |
819 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
820 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", | |
821 "stackFrames", | |
822 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>( | |
823 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)); | |
824 | |
825 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
826 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", | |
827 "typeNames", | |
828 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( | |
829 session_state, &MemoryDumpSessionState::type_name_deduplicator)); | |
830 } | 787 } |
831 | 788 |
832 std::unique_ptr<MemoryDumpScheduler> dump_scheduler( | 789 std::unique_ptr<MemoryDumpScheduler> dump_scheduler( |
833 new MemoryDumpScheduler(this, dump_thread->task_runner())); | 790 new MemoryDumpScheduler(this, dump_thread->task_runner())); |
834 DCHECK_LE(memory_dump_config.triggers.size(), 3u); | 791 DCHECK_LE(memory_dump_config.triggers.size(), 3u); |
835 for (const auto& trigger : memory_dump_config.triggers) { | 792 for (const auto& trigger : memory_dump_config.triggers) { |
836 if (!session_state->IsDumpModeAllowed(trigger.level_of_detail)) { | 793 if (!session_state->IsDumpModeAllowed(trigger.level_of_detail)) { |
837 NOTREACHED(); | 794 NOTREACHED(); |
838 continue; | 795 continue; |
839 } | 796 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 if (iter == process_dumps.end()) { | 925 if (iter == process_dumps.end()) { |
969 std::unique_ptr<ProcessMemoryDump> new_pmd( | 926 std::unique_ptr<ProcessMemoryDump> new_pmd( |
970 new ProcessMemoryDump(session_state, dump_args)); | 927 new ProcessMemoryDump(session_state, dump_args)); |
971 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 928 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
972 } | 929 } |
973 return iter->second.get(); | 930 return iter->second.get(); |
974 } | 931 } |
975 | 932 |
976 } // namespace trace_event | 933 } // namespace trace_event |
977 } // namespace base | 934 } // namespace base |
OLD | NEW |