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/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" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 TRACE_EVENT_NESTABLE_ASYNC_END1( | 87 TRACE_EVENT_NESTABLE_ASYNC_END1( |
| 88 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 88 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
| 89 TRACE_ID_MANGLE(dump_guid), "success", success); | 89 TRACE_ID_MANGLE(dump_guid), "success", success); |
| 90 | 90 |
| 91 if (!wrapped_callback.is_null()) { | 91 if (!wrapped_callback.is_null()) { |
| 92 wrapped_callback.Run(dump_guid, success); | 92 wrapped_callback.Run(dump_guid, success); |
| 93 wrapped_callback.Reset(); | 93 wrapped_callback.Reset(); |
| 94 } | 94 } |
| 95 } | 95 } |
| 96 | 96 |
| 97 // Proxy class which wraps a ConvertableToTraceFormat owned by the | |
| 98 // |session_state| into a proxy object that can be added to the trace event log. | |
| 99 // This is to solve the problem that the MemoryDumpSessionState is refcounted | |
| 100 // but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>. | |
| 101 template <typename T> | |
| 102 struct SessionStateConvertableProxy : public ConvertableToTraceFormat { | |
| 103 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const; | |
| 104 | |
| 105 SessionStateConvertableProxy( | |
| 106 scoped_refptr<MemoryDumpSessionState> session_state, | |
| 107 GetterFunctPtr getter_function) | |
| 108 : session_state(session_state), getter_function(getter_function) {} | |
| 109 | |
| 110 void AppendAsTraceFormat(std::string* out) const override { | |
| 111 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out); | |
| 112 } | |
| 113 | |
| 114 void EstimateTraceMemoryOverhead( | |
| 115 TraceEventMemoryOverhead* overhead) override { | |
| 116 return (session_state.get()->*getter_function)() | |
| 117 ->EstimateTraceMemoryOverhead(overhead); | |
| 118 } | |
| 119 | |
| 120 scoped_refptr<MemoryDumpSessionState> session_state; | |
| 121 GetterFunctPtr const getter_function; | |
| 122 }; | |
| 123 | |
| 124 } // namespace | 97 } // namespace |
| 125 | 98 |
| 126 // static | 99 // static |
| 127 const char* const MemoryDumpManager::kTraceCategory = | 100 const char* const MemoryDumpManager::kTraceCategory = |
| 128 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 101 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
| 129 | 102 |
| 130 // static | 103 // static |
| 131 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; | 104 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; |
| 132 | 105 |
| 133 // static | 106 // static |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 727 std::move(traced_value)); | 700 std::move(traced_value)); |
| 728 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | 701 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( |
| 729 TRACE_EVENT_PHASE_MEMORY_DUMP, | 702 TRACE_EVENT_PHASE_MEMORY_DUMP, |
| 730 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, | 703 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, |
| 731 trace_event_internal::kGlobalScope, dump_guid, pid, | 704 trace_event_internal::kGlobalScope, dump_guid, pid, |
| 732 kTraceEventNumArgs, kTraceEventArgNames, | 705 kTraceEventNumArgs, kTraceEventArgNames, |
| 733 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, | 706 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, |
| 734 TRACE_EVENT_FLAG_HAS_ID); | 707 TRACE_EVENT_FLAG_HAS_ID); |
| 735 } | 708 } |
| 736 | 709 |
| 710 const size_t kHeapDumpNumArgs = 1; | |
| 711 const char* kHeapDumpArgNames[] = {"data"}; | |
| 712 const unsigned char kHeapDumpArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | |
| 713 for (const auto& kv : pmd_async_state->process_dumps) { | |
| 714 ProcessId pid = kv.first; | |
| 715 ProcessMemoryDump* process_memory_dump = kv.second.get(); | |
| 716 if (pid != kNullProcessId) { | |
| 717 // We expect heap dumps only from the current process. | |
| 718 DCHECK(process_memory_dump->heap_dumps().empty()); | |
| 719 continue; | |
| 720 } | |
| 721 | |
| 722 auto heap_dump_value = MakeUnique<TracedValue>(); | |
| 723 | |
| 724 // Add version specifying format of the data below. | |
| 725 heap_dump_value->SetInteger("version", 1); | |
|
Primiano Tucci (use gerrit)
2017/02/17 17:07:05
I think that historically we avoided any sort of v
DmitrySkiba
2017/02/23 07:17:19
My position is exactly the opposite - versioning i
hjd
2017/02/23 12:33:27
I was motivated to ask Dmitry to add the version k
| |
| 726 | |
| 727 // Add "malloc", "blink_gc", etc. nodes, each containing a dump. | |
| 728 for (const auto& name_and_dump : process_memory_dump->heap_dumps()) { | |
| 729 heap_dump_value->SetValueWithCopiedName(name_and_dump.first.c_str(), | |
| 730 *name_and_dump.second); | |
| 731 } | |
| 732 | |
| 733 // Add "maps" node. | |
| 734 if (auto* session_state = pmd_async_state->session_state.get()) { | |
| 735 heap_dump_value->BeginDictionary("maps"); | |
| 736 if (auto* deduplicator = session_state->type_name_deduplicator()) { | |
| 737 heap_dump_value->BeginArray("types"); | |
| 738 deduplicator->AppendIncrementally(&*heap_dump_value); | |
| 739 heap_dump_value->EndArray(); | |
| 740 } | |
| 741 if (auto* deduplicator = session_state->stack_frame_deduplicator()) { | |
| 742 heap_dump_value->BeginArray("nodes"); | |
| 743 deduplicator->AppendIncrementally(&*heap_dump_value); | |
| 744 heap_dump_value->EndArray(); | |
| 745 } | |
| 746 heap_dump_value->EndDictionary(); | |
| 747 } | |
| 748 | |
| 749 std::unique_ptr<ConvertableToTraceFormat> values[kHeapDumpNumArgs] = { | |
| 750 std::move(heap_dump_value)}; | |
| 751 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | |
| 752 TRACE_EVENT_PHASE_SAMPLE, | |
| 753 TraceLog::GetCategoryGroupEnabled(kTraceCategory), "heap_profile", | |
|
Primiano Tucci (use gerrit)
2017/02/17 17:07:05
this is the only thing where I'm not fully sure. W
DmitrySkiba
2017/02/23 07:17:19
I think we discussed this exact concern several ti
hjd
2017/02/23 12:33:27
As I mentioned before if we eventually want to sha
| |
| 754 trace_event_internal::kGlobalScope, dump_guid, pid, kHeapDumpNumArgs, | |
| 755 kHeapDumpArgNames, kHeapDumpArgTypes, nullptr /* arg_values */, values, | |
| 756 TRACE_EVENT_FLAG_HAS_ID); | |
| 757 } | |
| 758 | |
| 737 bool tracing_still_enabled; | 759 bool tracing_still_enabled; |
| 738 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); | 760 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); |
| 739 if (!tracing_still_enabled) { | 761 if (!tracing_still_enabled) { |
| 740 pmd_async_state->dump_successful = false; | 762 pmd_async_state->dump_successful = false; |
| 741 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" | 763 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" |
| 742 << " the dump was completed"; | 764 << " the dump was completed"; |
| 743 } | 765 } |
| 744 | 766 |
| 745 if (!pmd_async_state->callback.is_null()) { | 767 if (!pmd_async_state->callback.is_null()) { |
| 746 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful); | 768 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 776 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); | 798 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); |
| 777 if (heap_profiling_enabled_) { | 799 if (heap_profiling_enabled_) { |
| 778 // If heap profiling is enabled, the stack frame deduplicator and type name | 800 // If heap profiling is enabled, the stack frame deduplicator and type name |
| 779 // deduplicator will be in use. Add a metadata events to write the frames | 801 // deduplicator will be in use. Add a metadata events to write the frames |
| 780 // and type IDs. | 802 // and type IDs. |
| 781 session_state->SetStackFrameDeduplicator( | 803 session_state->SetStackFrameDeduplicator( |
| 782 WrapUnique(new StackFrameDeduplicator)); | 804 WrapUnique(new StackFrameDeduplicator)); |
| 783 | 805 |
| 784 session_state->SetTypeNameDeduplicator( | 806 session_state->SetTypeNameDeduplicator( |
| 785 WrapUnique(new TypeNameDeduplicator)); | 807 WrapUnique(new TypeNameDeduplicator)); |
| 786 | |
| 787 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
| 788 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", | |
| 789 "stackFrames", | |
| 790 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>( | |
| 791 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)); | |
| 792 | |
| 793 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
| 794 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", | |
| 795 "typeNames", | |
| 796 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( | |
| 797 session_state, &MemoryDumpSessionState::type_name_deduplicator)); | |
| 798 } | 808 } |
| 799 | 809 |
| 800 { | 810 { |
| 801 AutoLock lock(lock_); | 811 AutoLock lock(lock_); |
| 802 | 812 |
| 803 DCHECK(delegate_); // At this point we must have a delegate. | 813 DCHECK(delegate_); // At this point we must have a delegate. |
| 804 session_state_ = session_state; | 814 session_state_ = session_state; |
| 805 | 815 |
| 806 DCHECK(!dump_thread_); | 816 DCHECK(!dump_thread_); |
| 807 dump_thread_ = std::move(dump_thread); | 817 dump_thread_ = std::move(dump_thread); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 1003 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
| 994 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 1004 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
| 995 ++periodic_dumps_count_; | 1005 ++periodic_dumps_count_; |
| 996 | 1006 |
| 997 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 1007 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
| 998 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | 1008 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
| 999 } | 1009 } |
| 1000 | 1010 |
| 1001 } // namespace trace_event | 1011 } // namespace trace_event |
| 1002 } // namespace base | 1012 } // namespace base |
| OLD | NEW |